diff options
Diffstat (limited to 'src/mesa/drivers/dri')
311 files changed, 15268 insertions, 5435 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 0e01d74265..3649c29666 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -454,6 +454,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; + pdp->validBuffers = GL_FALSE; if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, renderType == GLX_PIXMAP_BIT)) { diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 35d8b8ff93..95df702f1a 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -376,6 +376,8 @@ struct __DRIdrawableRec { * GLX_MESA_swap_control. */ unsigned int swap_interval; + + GLboolean validBuffers; }; /** diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index 447f3d15b9..c152226902 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -400,7 +400,7 @@ # define READ_RGBA( rgba, _x, _y ) \ do { \ GLuint p = GET_VALUE(_x, _y); \ - *((uint32_t *) rgba) = (t << 8) | 0xff; \ + *((uint32_t *) rgba) = (p << 8) | 0xff; \ } while (0) # else # define READ_RGBA( rgba, _x, _y ) \ diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index b272eb74ea..81d026a697 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -34,7 +34,6 @@ #include "main/mtypes.h" #include "main/cpuinfo.h" #include "main/extensions.h" -#include "glapi/dispatch.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/fb/Makefile b/src/mesa/drivers/dri/fb/Makefile index cf9b3a8556..848e2041e2 100644 --- a/src/mesa/drivers/dri/fb/Makefile +++ b/src/mesa/drivers/dri/fb/Makefile @@ -5,9 +5,6 @@ include $(TOP)/configs/current LIBNAME = fb_dri.so -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif DRIVER_SOURCES = \ fb_dri.c \ diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c deleted file mode 100644 index 02e44bb8ee..0000000000 --- a/src/mesa/drivers/dri/fb/fb_egl.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Test egl driver for fb_dri.so - */ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <linux/fb.h> - -#include "utils.h" -#include "buffers.h" -#include "main/extensions.h" -#include "main/framebuffer.h" -#include "main/renderbuffer.h" -#include "vbo/vbo.h" -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" -#include "tnl/tcontext.h" -#include "tnl/t_pipeline.h" -#include "drivers/common/driverfuncs.h" -#include "drirenderbuffer.h" - -#include "eglconfig.h" -#include "eglmain/context.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" - -extern void -fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis); - -/** - * fb driver-specific driver class derived from _EGLDriver - */ -typedef struct fb_driver -{ - _EGLDriver Base; /* base class/object */ - GLuint fbStuff; -} fbDriver; - -/** - * fb display-specific driver class derived from _EGLDisplay - */ -typedef struct fb_display -{ - _EGLDisplay Base; /* base class/object */ - void *pFB; -} fbDisplay; - -/** - * fb driver-specific screen class derived from _EGLScreen - */ -typedef struct fb_screen -{ - _EGLScreen Base; - char fb[NAME_MAX]; -} fbScreen; - - -/** - * fb driver-specific surface class derived from _EGLSurface - */ -typedef struct fb_surface -{ - _EGLSurface Base; /* base class/object */ - struct gl_framebuffer *mesa_framebuffer; -} fbSurface; - - -/** - * fb driver-specific context class derived from _EGLContext - */ -typedef struct fb_context -{ - _EGLContext Base; /* base class/object */ - GLcontext *glCtx; - struct { - __DRIcontext *context; - __DRIscreen *screen; - __DRIdrawable *drawable; /* drawable bound to this ctx */ - } dri; -} fbContext, *fbContextPtr; - -#define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx)) - - -static EGLBoolean -fbFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) { - _EGLConfig *configs; - _EGLConfig *c; - unsigned int i, num_configs; - unsigned int depth_buffer_factor; - unsigned int back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy - * enough to add support. Basically, if a context is created with an - * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping - * will never be used. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ - }; - - uint8_t depth_bits_array[2]; - uint8_t stencil_bits_array[2]; - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; - back_buffer_factor = (have_back_buffer) ? 2 : 1; - - num_configs = depth_buffer_factor * back_buffer_factor * 2; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } else { - fb_format = GL_RGBA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = calloc(sizeof(*configs), num_configs); - c = configs; - if (!_eglFillInConfigs(c, fb_format, fb_type, - depth_bits_array, stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return EGL_FALSE; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (i = 0, c = configs; i < num_configs; i++, c++) { - int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); - if ((stencil != 0) && (stencil != stencil_bits)) { - SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); - } - } - - for (i = 0, c = configs; i < num_configs; i++, c++) - _eglAddConfig(disp, c); - - free(configs); - - return EGL_TRUE; -} - -static EGLBoolean -fbSetupFramebuffer(fbDisplay *disp, char *fbdev) -{ - int fd; - char dev[20]; - struct fb_var_screeninfo varInfo; - struct fb_fix_screeninfo fixedInfo; - - snprintf(dev, sizeof(dev), "/dev/%s", fbdev); - - /* open the framebuffer device */ - fd = open(dev, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Error opening %s: %s\n", fbdev, strerror(errno)); - return EGL_FALSE; - } - - /* get the original variable screen info */ - if (ioctl(fd, FBIOGET_VSCREENINFO, &varInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", - strerror(errno)); - return EGL_FALSE; - } - - /* Turn off hw accels (otherwise mmap of mmio region will be - * refused) - */ - if (varInfo.accel_flags) { - varInfo.accel_flags = 0; - if (ioctl(fd, FBIOPUT_VSCREENINFO, &varInfo)) { - fprintf(stderr, "error: ioctl(FBIOPUT_VSCREENINFO) failed: %s\n", - strerror(errno)); - return EGL_FALSE; - } - } - - /* Get the fixed screen info */ - if (ioctl(fd, FBIOGET_FSCREENINFO, &fixedInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", - strerror(errno)); - return EGL_FALSE; - } - - if (fixedInfo.visual == FB_VISUAL_DIRECTCOLOR) { - struct fb_cmap cmap; - unsigned short red[256], green[256], blue[256]; - int rcols = 1 << varInfo.red.length; - int gcols = 1 << varInfo.green.length; - int bcols = 1 << varInfo.blue.length; - int i; - - cmap.start = 0; - cmap.len = gcols; - cmap.red = red; - cmap.green = green; - cmap.blue = blue; - cmap.transp = NULL; - - for (i = 0; i < rcols ; i++) - red[i] = (65536/(rcols-1)) * i; - - for (i = 0; i < gcols ; i++) - green[i] = (65536/(gcols-1)) * i; - - for (i = 0; i < bcols ; i++) - blue[i] = (65536/(bcols-1)) * i; - - if (ioctl(fd, FBIOPUTCMAP, (void *) &cmap) < 0) { - fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i); - exit(1); - } - } - - /* mmap the framebuffer into our address space */ - if (!disp->pFB) - disp->pFB = (caddr_t)mmap(0, /* start */ - fixedInfo.smem_len, /* bytes */ - PROT_READ | PROT_WRITE, /* prot */ - MAP_SHARED, /* flags */ - fd, /* fd */ - 0); /* offset */ - if (disp->pFB == (caddr_t)-1) { - fprintf(stderr, "error: unable to mmap framebuffer: %s\n", - strerror(errno)); - return EGL_FALSE; - } - - return EGL_TRUE; -} - -const char *sysfs = "/sys/class/graphics"; - -static EGLBoolean -fbInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - fbDisplay *display; - fbScreen *s; - _EGLScreen *scrn; - char c; - unsigned int x, y, r; - DIR *dir; - FILE *file; - struct dirent *dirent; - char path[NAME_MAX]; - - /* Switch display structure to one with our private fields */ - display = calloc(1, sizeof(*display)); - display->Base = *disp; - _eglHashInsert(_eglGlobal.Displays, disp->Handle, display); - free(disp); - - *major = 1; - *minor = 0; - - dir = opendir(sysfs); - if (!dir) { - printf("EGL - %s framebuffer device not found.", sysfs); - return EGL_FALSE; - } - - while ((dirent = readdir(dir))) { /* assignment! */ - - if (dirent->d_name[0] != 'f') - continue; - if (dirent->d_name[1] != 'b') - continue; - - if (fbSetupFramebuffer(display, dirent->d_name) == EGL_FALSE) - continue; - - /* Create a screen */ - s = (fbScreen *) calloc(1, sizeof(fbScreen)); - if (!s) - return EGL_FALSE; - - strncpy(s->fb, dirent->d_name, NAME_MAX); - scrn = &s->Base; - _eglInitScreen(scrn); - _eglAddScreen(&display->Base, scrn); - - snprintf(path, sizeof(path), "%s/%s/modes", sysfs, s->fb); - file = fopen(path, "r"); - while (fgets(path, sizeof(path), file)) { - sscanf(path, "%c:%ux%u-%u", &c, &x, &y, &r); - _eglAddMode(scrn, x, y, r * 1000, path); - } - fclose(file); - - fbFillInConfigs(&display->Base, 32, 24, 8, 1); - - } - closedir(dir); - - drv->Initialized = EGL_TRUE; - return EGL_TRUE; -} - - -static fbDisplay * -Lookup_fbDisplay(EGLDisplay dpy) -{ - _EGLDisplay *d = _eglLookupDisplay(dpy); - return (fbDisplay *) d; -} - - -static fbScreen * -Lookup_fbScreen(EGLDisplay dpy, EGLScreenMESA screen) -{ - _EGLScreen *s = _eglLookupScreen(dpy, screen); - return (fbScreen *) s; -} - - -static fbContext * -Lookup_fbContext(EGLContext ctx) -{ - _EGLContext *c = _eglLookupContext(ctx); - return (fbContext *) c; -} - - -static fbSurface * -Lookup_fbSurface(EGLSurface surf) -{ - _EGLSurface *s = _eglLookupSurface(surf); - return (fbSurface *) s; -} - - -static EGLBoolean -fbTerminate(_EGLDriver *drv, EGLDisplay dpy) -{ - fbDisplay *display = Lookup_fbDisplay(dpy); - _eglCleanupDisplay(&display->Base); - free(display); - free(drv); - return EGL_TRUE; -} - - -static const GLubyte * -get_string(GLcontext *ctx, GLenum pname) -{ - (void) ctx; - switch (pname) { - case GL_RENDERER: - return (const GLubyte *) "Mesa dumb framebuffer"; - default: - return NULL; - } -} - - -static void -update_state( GLcontext *ctx, GLuint new_state ) -{ - /* not much to do here - pass it on */ - _swrast_InvalidateState( ctx, new_state ); - _swsetup_InvalidateState( ctx, new_state ); - _vbo_InvalidateState( ctx, new_state ); - _tnl_InvalidateState( ctx, new_state ); -} - - -/** - * Called by ctx->Driver.GetBufferSize from in core Mesa to query the - * current framebuffer size. - */ -static void -get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) -{ - *width = buffer->Width; - *height = buffer->Height; -} - - -static void -updateFramebufferSize(GLcontext *ctx) -{ - fbContextPtr fbmesa = FB_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->WinSysDrawBuffer; - if (fbmesa->dri.drawable->w != fb->Width || - fbmesa->dri.drawable->h != fb->Height) { - driUpdateFramebufferSize(ctx, fbmesa->dri.drawable); - } -} - -static void -viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - /* XXX this should be called after we acquire the DRI lock, not here */ - updateFramebufferSize(ctx); -} - - -static void -init_core_functions( struct dd_function_table *functions ) -{ - functions->GetString = get_string; - functions->UpdateState = update_state; - functions->GetBufferSize = get_buffer_size; - functions->Viewport = viewport; - - functions->Clear = _swrast_Clear; /* could accelerate with blits */ -} - - -static EGLContext -fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) -{ - GLcontext *ctx; - _EGLConfig *conf; - fbContext *c; - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct dd_function_table functions; - GLvisual vis; - int i; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - c = (fbContext *) calloc(1, sizeof(fbContext)); - if (!c) - return EGL_NO_CONTEXT; - - _eglInitContext(&c->Base); - c->Base.Display = disp; - c->Base.Config = conf; - c->Base.DrawSurface = EGL_NO_SURFACE; - c->Base.ReadSurface = EGL_NO_SURFACE; - - /* link to display */ - _eglLinkContext(&c->Base, disp); - assert(c->Base.Handle); - - /* Init default driver functions then plug in our FBdev-specific functions - */ - _mesa_init_driver_functions(&functions); - init_core_functions(&functions); - - _eglConfigToContextModesRec(conf, &vis); - - ctx = c->glCtx = _mesa_create_context(&vis, NULL, &functions, (void *)c); - if (!c->glCtx) { - _mesa_free(c); - return GL_FALSE; - } - - /* Create module contexts */ - _swrast_CreateContext( ctx ); - _vbo_CreateContext( ctx ); - _tnl_CreateContext( ctx ); - _swsetup_CreateContext( ctx ); - _swsetup_Wakeup( ctx ); - - - /* use default TCL pipeline */ - { - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->Driver.RunPipeline = _tnl_run_pipeline; - } - - _mesa_enable_sw_extensions(ctx); - - return c->Base.Handle; -} - - -static EGLSurface -fbCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) -{ - int i; - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface"); - return EGL_NO_SURFACE; - } - } - printf("eglCreateWindowSurface()\n"); - /* XXX unfinished */ - - return EGL_NO_SURFACE; -} - - -static EGLSurface -fbCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) -{ - _EGLConfig *conf; - EGLint i; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - } - - if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) { - _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - - printf("eglCreatePixmapSurface()\n"); - return EGL_NO_SURFACE; -} - - -static EGLSurface -fbCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) -{ - fbSurface *surf; - - surf = (fbSurface *) calloc(1, sizeof(fbSurface)); - if (!surf) { - return EGL_NO_SURFACE; - } - - if (_eglInitPbufferSurface(&surf->Base, drv, dpy, config, attrib_list) == EGL_NO_SURFACE) { - free(surf); - return EGL_NO_SURFACE; - } - - /* create software-based pbuffer */ - { - GLcontext *ctx = NULL; /* this _should_ be OK */ - GLvisual vis; - _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); - assert(conf); /* bad config should be caught earlier */ - _eglConfigToContextModesRec(conf, &vis); - - surf->mesa_framebuffer = _mesa_create_framebuffer(&vis); - _mesa_add_soft_renderbuffers(surf->mesa_framebuffer, - GL_TRUE, /* color bufs */ - vis.haveDepthBuffer, - vis.haveStencilBuffer, - vis.haveAccumBuffer, - GL_FALSE, /* alpha */ - GL_FALSE /* aux */ ); - - /* set pbuffer/framebuffer size */ - _mesa_resize_framebuffer(ctx, surf->mesa_framebuffer, - surf->Base.Width, surf->Base.Height); - } - - return surf->Base.Handle; -} - - -static EGLBoolean -fbDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) -{ - fbSurface *fs = Lookup_fbSurface(surface); - _eglUnlinkSurface(&fs->Base); - if (!_eglIsSurfaceBound(&fs->Base)) - free(fs); - return EGL_TRUE; -} - - -static EGLBoolean -fbDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) -{ - fbContext *fc = Lookup_fbContext(context); - _eglUnlinkContext(&fc->Base); - if (!_eglIsContextBound(&fc->Base)) - free(fc); - return EGL_TRUE; -} - - -static EGLBoolean -fbMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) -{ - fbSurface *readSurf = Lookup_fbSurface(read); - fbSurface *drawSurf = Lookup_fbSurface(draw); - fbContext *ctx = Lookup_fbContext(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - _mesa_make_current( ctx->glCtx, - drawSurf->mesa_framebuffer, - readSurf->mesa_framebuffer); - } else - _mesa_make_current( NULL, NULL, NULL ); - - return EGL_TRUE; -} - - -/** - * Create a drawing surface which can be directly displayed on a screen. - */ -static EGLSurface -fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, - const EGLint *attrib_list) -{ - _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg); - fbDisplay *display = Lookup_fbDisplay(dpy); - fbSurface *surface; - EGLSurface surf; - GLvisual vis; - GLcontext *ctx = NULL; /* this should be OK */ - int origin, bytesPerPixel; - int width, height, stride; - - surface = (fbSurface *) malloc(sizeof(*surface)); - if (!surface) { - return EGL_NO_SURFACE; - } - - /* init base class, error check, etc. */ - surf = _eglInitScreenSurface(&surface->Base, drv, dpy, cfg, attrib_list); - if (surf == EGL_NO_SURFACE) { - free(surface); - return EGL_NO_SURFACE; - } - - /* convert EGLConfig to GLvisual */ - _eglConfigToContextModesRec(config, &vis); - - /* create Mesa framebuffer */ - surface->mesa_framebuffer = _mesa_create_framebuffer(&vis); - if (!surface->mesa_framebuffer) { - free(surface); - _eglUnlinkSurface(&surface->Base); - return EGL_NO_SURFACE; - } - - width = surface->Base.Width; - height = surface->Base.Height; - bytesPerPixel = vis.rgbBits / 8; - stride = width * bytesPerPixel; - origin = 0; - - /* front color renderbuffer */ - { - driRenderbuffer *drb = driNewRenderbuffer(MESA_FORMAT_ARGB8888, display->pFB, - bytesPerPixel, - origin, stride, NULL); - fbSetSpanFunctions(drb, &vis); - _mesa_add_renderbuffer(surface->mesa_framebuffer, - BUFFER_FRONT_LEFT, &drb->Base); - } - - /* back color renderbuffer */ - if (vis.doubleBufferMode) { - GLubyte *backBuf = _mesa_malloc(stride * height); - driRenderbuffer *drb = driNewRenderbuffer(MESA_FORMAT_ARGB8888, backBuf, - bytesPerPixel, - origin, stride, NULL); - fbSetSpanFunctions(drb, &vis); - _mesa_add_renderbuffer(surface->mesa_framebuffer, - BUFFER_BACK_LEFT, &drb->Base); - } - - /* other renderbuffers- software based */ - _mesa_add_soft_renderbuffers(surface->mesa_framebuffer, - GL_FALSE, /* color */ - vis.haveDepthBuffer, - vis.haveStencilBuffer, - vis.haveAccumBuffer, - GL_FALSE, /* alpha */ - GL_FALSE /* aux */); - - _mesa_resize_framebuffer(ctx, surface->mesa_framebuffer, width, height); - - return surf; -} - - -/** - * Show the given surface on the named screen. - * If surface is EGL_NO_SURFACE, disable the screen's output. - */ -static EGLBoolean -fbShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - fbDisplay *display = Lookup_fbDisplay(dpy); - fbScreen *scrn = Lookup_fbScreen(dpy, screen); - fbSurface *surf = Lookup_fbSurface(surface); - FILE *file; - char buffer[NAME_MAX]; - _EGLMode *mode = _eglLookupMode(dpy, m); - int bits; - - if (!_eglShowSurfaceMESA(drv, dpy, screen, surface, m)) - return EGL_FALSE; - - snprintf(buffer, sizeof(buffer), "%s/%s/blank", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) { -err: - printf("chown all fb sysfs attrib to allow write - %s\n", buffer); - return EGL_FALSE; - } - snprintf(buffer, sizeof(buffer), "%d", (m == EGL_NO_MODE_MESA ? VESA_POWERDOWN : VESA_VSYNC_SUSPEND)); - fputs(buffer, file); - fclose(file); - - if (m == EGL_NO_MODE_MESA) - return EGL_TRUE; - - snprintf(buffer, sizeof(buffer), "%s/%s/mode", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) - goto err; - fputs(mode->Name, file); - fclose(file); - - snprintf(buffer, sizeof(buffer), "%s/%s/bits_per_pixel", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) - goto err; - bits = GET_CONFIG_ATTRIB(surf->Base.Config, EGL_BUFFER_SIZE); - snprintf(buffer, sizeof(buffer), "%d", bits); - fputs(buffer, file); - fclose(file); - - fbSetupFramebuffer(display, scrn->fb); - - snprintf(buffer, sizeof(buffer), "%s/%s/blank", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) - goto err; - - snprintf(buffer, sizeof(buffer), "%d", VESA_NO_BLANKING); - fputs(buffer, file); - fclose(file); - - return EGL_TRUE; -} - - -/* If the backbuffer is on a videocard, this is extraordinarily slow! - */ -static EGLBoolean -fbSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) -{ - fbContext *context = (fbContext *)_eglGetCurrentContext(); - fbSurface *fs = Lookup_fbSurface(draw); - struct gl_renderbuffer * front_renderbuffer = fs->mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - void *frontBuffer = front_renderbuffer->Data; - int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch; - void *backBuffer = fs->mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data; - - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; - - if (context) { - GLcontext *ctx = context->glCtx; - - if (ctx->Visual.doubleBufferMode) { - int i; - int offset = 0; - char *tmp = _mesa_malloc(currentPitch); - - _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - - ASSERT(frontBuffer); - ASSERT(backBuffer); - - for (i = 0; i < fs->Base.Height; i++) { - _mesa_memcpy(tmp, (char *) backBuffer + offset, - currentPitch); - _mesa_memcpy((char *) frontBuffer + offset, tmp, - currentPitch); - offset += currentPitch; - } - - _mesa_free(tmp); - } - } - else { - /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n"); - return EGL_FALSE; - } - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new fbDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy) -{ - fbDriver *fb; - - fb = (fbDriver *) calloc(1, sizeof(fbDriver)); - if (!fb) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(&fb->Base); - - /* then plug in our fb-specific functions */ - fb->Base.Initialize = fbInitialize; - fb->Base.Terminate = fbTerminate; - fb->Base.CreateContext = fbCreateContext; - fb->Base.MakeCurrent = fbMakeCurrent; - fb->Base.CreateWindowSurface = fbCreateWindowSurface; - fb->Base.CreatePixmapSurface = fbCreatePixmapSurface; - fb->Base.CreatePbufferSurface = fbCreatePbufferSurface; - fb->Base.DestroySurface = fbDestroySurface; - fb->Base.DestroyContext = fbDestroyContext; - fb->Base.CreateScreenSurfaceMESA = fbCreateScreenSurfaceMESA; - fb->Base.ShowSurfaceMESA = fbShowSurfaceMESA; - fb->Base.SwapBuffers = fbSwapBuffers; - - /* enable supported extensions */ - fb->Base.MESA_screen_surface = EGL_TRUE; - fb->Base.MESA_copy_context = EGL_TRUE; - - return &fb->Base; -} diff --git a/src/mesa/drivers/dri/ffb/ffb_bitmap.c b/src/mesa/drivers/dri/ffb/ffb_bitmap.c index 611afddfaf..b71a552c9d 100644 --- a/src/mesa/drivers/dri/ffb/ffb_bitmap.c +++ b/src/mesa/drivers/dri/ffb/ffb_bitmap.c @@ -30,7 +30,6 @@ #include "ffb_lock.h" #include "ffb_bitmap.h" #include "swrast/swrast.h" -#include "main/image.h" #include "main/macros.h" /* Compute ceiling of integer quotient of A divided by B: */ diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.c b/src/mesa/drivers/dri/ffb/ffb_clear.c index dfe60f36f2..aa3fa0a86c 100644 --- a/src/mesa/drivers/dri/ffb/ffb_clear.c +++ b/src/mesa/drivers/dri/ffb/ffb_clear.c @@ -26,15 +26,12 @@ */ #include "main/mtypes.h" -#include "main/extensions.h" #include "main/mm.h" #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" #include "ffb_vb.h" -#include "ffb_tris.h" #include "ffb_clear.h" #include "ffb_lock.h" diff --git a/src/mesa/drivers/dri/ffb/ffb_dd.c b/src/mesa/drivers/dri/ffb/ffb_dd.c index cf83b91f0d..91b6d3153a 100644 --- a/src/mesa/drivers/dri/ffb/ffb_dd.c +++ b/src/mesa/drivers/dri/ffb/ffb_dd.c @@ -27,13 +27,9 @@ #include "main/mtypes.h" #include "main/mm.h" -#include "main/extensions.h" #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" -#include "ffb_vb.h" -#include "ffb_tris.h" #include "ffb_clear.h" #include "ffb_lock.h" diff --git a/src/mesa/drivers/dri/ffb/ffb_depth.c b/src/mesa/drivers/dri/ffb/ffb_depth.c index 5d509ff696..d19385b776 100644 --- a/src/mesa/drivers/dri/ffb/ffb_depth.c +++ b/src/mesa/drivers/dri/ffb/ffb_depth.c @@ -26,7 +26,6 @@ */ #include "main/mtypes.h" -#include "swrast/swrast.h" #include "ffb_dd.h" #include "ffb_span.h" #include "ffb_context.h" diff --git a/src/mesa/drivers/dri/ffb/ffb_lines.c b/src/mesa/drivers/dri/ffb/ffb_lines.c index 19dff50935..6dca4edd29 100644 --- a/src/mesa/drivers/dri/ffb/ffb_lines.c +++ b/src/mesa/drivers/dri/ffb/ffb_lines.c @@ -27,15 +27,11 @@ #include "main/mtypes.h" #include "main/mm.h" -#include "main/extensions.h" #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" #include "ffb_vb.h" #include "ffb_lines.h" -#include "ffb_tris.h" -#include "ffb_lock.h" #undef FFB_LINE_TRACE diff --git a/src/mesa/drivers/dri/ffb/ffb_points.c b/src/mesa/drivers/dri/ffb/ffb_points.c index 9c37a47aeb..5bf4f8f070 100644 --- a/src/mesa/drivers/dri/ffb/ffb_points.c +++ b/src/mesa/drivers/dri/ffb/ffb_points.c @@ -30,8 +30,6 @@ #include "ffb_context.h" #include "ffb_vb.h" #include "ffb_points.h" -#include "ffb_tris.h" -#include "ffb_lock.h" #undef FFB_POINT_TRACE diff --git a/src/mesa/drivers/dri/ffb/ffb_span.c b/src/mesa/drivers/dri/ffb/ffb_span.c index 8ec33a11bc..61901cccad 100644 --- a/src/mesa/drivers/dri/ffb/ffb_span.c +++ b/src/mesa/drivers/dri/ffb/ffb_span.c @@ -31,8 +31,6 @@ #include "ffb_context.h" #include "ffb_lock.h" -#include "swrast/swrast.h" - #define DBG 0 #define HW_LOCK() \ diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c index 6f8a46d1fc..c09d2fef83 100644 --- a/src/mesa/drivers/dri/ffb/ffb_state.c +++ b/src/mesa/drivers/dri/ffb/ffb_state.c @@ -27,8 +27,6 @@ #include "main/mtypes.h" #include "main/colormac.h" -#include "main/mm.h" -#include "main/extensions.h" #include "main/enums.h" #include "vbo/vbo.h" @@ -39,12 +37,9 @@ #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" -#include "ffb_vb.h" #include "ffb_tris.h" #include "ffb_state.h" -#include "ffb_lock.h" #undef STATE_TRACE diff --git a/src/mesa/drivers/dri/ffb/ffb_stencil.c b/src/mesa/drivers/dri/ffb/ffb_stencil.c index ce8ef43c91..10cdfbc616 100644 --- a/src/mesa/drivers/dri/ffb/ffb_stencil.c +++ b/src/mesa/drivers/dri/ffb/ffb_stencil.c @@ -32,8 +32,6 @@ #include "ffb_stencil.h" #include "ffb_lock.h" -#include "swrast/swrast.h" - #undef STENCIL_TRACE static void FFBWriteStencilSpan( GLcontext *ctx, diff --git a/src/mesa/drivers/dri/ffb/ffb_vb.c b/src/mesa/drivers/dri/ffb/ffb_vb.c index f9c6fd1f31..ca8ffb2721 100644 --- a/src/mesa/drivers/dri/ffb/ffb_vb.c +++ b/src/mesa/drivers/dri/ffb/ffb_vb.c @@ -30,8 +30,6 @@ #include "ffb_vb.h" #include "main/imports.h" #include "tnl/t_context.h" -#include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #undef VB_DEBUG diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 88285f454e..6a84651479 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -28,7 +28,6 @@ #include "ffb_xmesa.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/matrix.h" #include "main/renderbuffer.h" #include "main/simple_list.h" #include "main/imports.h" @@ -52,7 +51,6 @@ #include "ffb_lines.h" #include "ffb_points.h" #include "ffb_state.h" -#include "ffb_tex.h" #include "ffb_lock.h" #include "ffb_vtxfmt.h" #include "ffb_bitmap.h" diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c index bd9cfe5c0f..34e34606b4 100644 --- a/src/mesa/drivers/dri/i810/i810context.c +++ b/src/mesa/drivers/dri/i810/i810context.c @@ -34,10 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "main/context.h" -#include "main/matrix.h" #include "main/simple_list.h" -#include "main/extensions.h" -#include "main/framebuffer.h" #include "main/imports.h" #include "main/points.h" diff --git a/src/mesa/drivers/dri/i810/i810render.c b/src/mesa/drivers/dri/i810/i810render.c index 1d98e00688..b543d4f012 100644 --- a/src/mesa/drivers/dri/i810/i810render.c +++ b/src/mesa/drivers/dri/i810/i810render.c @@ -44,7 +44,6 @@ #include "i810context.h" #include "i810tris.h" -#include "i810state.h" #include "i810vb.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index 2a30782afd..476c801358 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -36,8 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/fbobject.h" -#include "main/matrix.h" #include "main/renderbuffer.h" #include "main/simple_list.h" #include "utils.h" @@ -48,8 +46,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i810state.h" #include "i810tex.h" #include "i810span.h" -#include "i810tris.h" -#include "i810ioctl.h" #include "GL/internal/dri_interface.h" diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 642245c61c..0c68e120b0 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -20,8 +20,6 @@ #include "i810context.h" #include "i810state.h" #include "i810tex.h" -#include "i810vb.h" -#include "i810tris.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810tex.c b/src/mesa/drivers/dri/i810/i810tex.c index e764644a6c..2ccb9562e9 100644 --- a/src/mesa/drivers/dri/i810/i810tex.c +++ b/src/mesa/drivers/dri/i810/i810tex.c @@ -33,7 +33,6 @@ #include "main/colormac.h" #include "main/texobj.h" #include "main/mm.h" -#include "swrast/swrast.h" #include "texmem.h" @@ -42,7 +41,6 @@ #include "i810context.h" #include "i810tex.h" -#include "i810state.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810texmem.c b/src/mesa/drivers/dri/i810/i810texmem.c index d93afbf9ef..bb426a4112 100644 --- a/src/mesa/drivers/dri/i810/i810texmem.c +++ b/src/mesa/drivers/dri/i810/i810texmem.c @@ -35,7 +35,6 @@ #include "i810_dri.h" #include "i810context.h" #include "i810tex.h" -#include "i810state.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810vb.c b/src/mesa/drivers/dri/i810/i810vb.c index 30890dc9b7..09a772258c 100644 --- a/src/mesa/drivers/dri/i810/i810vb.c +++ b/src/mesa/drivers/dri/i810/i810vb.c @@ -38,7 +38,6 @@ #include "i810context.h" #include "i810vb.h" #include "i810ioctl.h" -#include "i810tris.h" #include "i810state.h" diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index cf32476f40..dc15ae425c 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -8,7 +8,6 @@ MINIGLX_SOURCES = server/intel_dri.c DRIVER_SOURCES = \ i830_context.c \ - i830_metaops.c \ i830_state.c \ i830_texblend.c \ i830_texstate.c \ @@ -40,7 +39,6 @@ DRIVER_SOURCES = \ i915_debug.c \ i915_debug_fp.c \ i915_fragprog.c \ - i915_metaops.c \ i915_program.c \ i915_state.c \ i915_vtbl.c \ diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 4cb6305988..ebe8b15ca7 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -28,14 +28,11 @@ #include "i830_context.h" #include "main/imports.h" #include "texmem.h" -#include "intel_tex.h" #include "tnl/tnl.h" #include "tnl/t_vertex.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "utils.h" #include "intel_span.h" -#include "intel_pixel.h" #include "intel_tris.h" /*************************************** @@ -108,7 +105,6 @@ i830CreateContext(const __GLcontextModes * mesaVis, intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; i830InitState(i830); - i830InitMetaFuncs(i830); _tnl_allow_vertex_fog(ctx, 1); _tnl_allow_pixel_fog(ctx, 0); diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h index 592ae53976..b755d48678 100644 --- a/src/mesa/drivers/dri/i915/i830_context.h +++ b/src/mesa/drivers/dri/i915/i830_context.h @@ -144,7 +144,7 @@ struct i830_context GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; DECLARE_RENDERINPUTS(last_index_bitset); - struct i830_hw_state meta, initial, state, *current; + struct i830_hw_state state; }; @@ -206,10 +206,6 @@ extern void i830EmitState(struct i830_context *i830); extern void i830InitState(struct i830_context *i830); extern void i830_update_provoking_vertex(GLcontext *ctx); -/* i830_metaops.c - */ -extern void i830InitMetaFuncs(struct i830_context *i830); - /*====================================================================== * Inline conversion functions. These are better-typed than the * macros used previously: diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c deleted file mode 100644 index 2cce661c86..0000000000 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ /dev/null @@ -1,456 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/enums.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_regions.h" - -#include "i830_context.h" -#include "i830_reg.h" - -/* A large amount of state doesn't need to be uploaded. - */ -#define ACTIVE (I830_UPLOAD_INVARIENT | \ - I830_UPLOAD_CTX | \ - I830_UPLOAD_BUFFERS | \ - I830_UPLOAD_STIPPLE | \ - I830_UPLOAD_TEXBLEND(0) | \ - I830_UPLOAD_TEX(0)) - - -#define SET_STATE( i830, STATE ) \ -do { \ - i830->current->emitted &= ~ACTIVE; \ - i830->current = &i830->STATE; \ - i830->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -set_no_stencil_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -static void -set_no_depth_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Set depth unit to replace. - */ -static void -set_depth_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; - i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC - (COMPAREFUNC_ALWAYS)); - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -set_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK((s_mask & - 0xff))); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE((s_clear & 0xff)) | - STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); - - - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -set_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | - (1 << WRITEMASK_GREEN_SHIFT) | - (1 << WRITEMASK_BLUE_SHIFT) | - (1 << WRITEMASK_ALPHA_SHIFT)); - - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; - - if (state) { - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= - (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); - } - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Installs a one-stage passthrough texture blend pipeline. Is there - * more that can be done to turn off texturing? - */ -static void -set_no_texture(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_NONE, GL_NONE, - {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, - {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, - 0, 0, 0, 0 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); -} - -/* Set up a single element blend stage for 'replace' texturing with no - * funny ops. - */ -static void -set_texture_blend_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_REPLACE, GL_REPLACE, - {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, - GL_TEXTURE,}, - {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, - GL_SRC_ALPHA}, - 0, 0, 1, 1 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); - -/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ -/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ -} - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -set_tex_rect_source(struct intel_context *intel, - dri_bo *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLuint *setup = i830->meta.Tex[0]; - GLint numLevels = 1; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - i830->meta.tex_buffer[0] = buffer; - i830->meta.tex_offset[0] = offset; - - setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << 0) | 4); - setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | - ((pitch - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - setup[I830_TEXREG_TM0S2] = - (((((pitch * cpp) / 4) - - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); - - setup[I830_TEXREG_TM0S3] = - ((((numLevels - - 1) * - 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << - TM0S3_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << - TM0S3_MAG_FILTER_SHIFT)); - - setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); - - setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_IN_TEXELUNITS | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - i830->meta.emitted &= ~I830_UPLOAD_TEX(0); - return GL_TRUE; -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | - VFT0_TEX_COUNT(1) | - VFT0_DIFFUSE | VFT0_XYZ); - i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | - VFT1_TEX0_FMT(TEXCOORDFMT_2D) | - VFT1_TEX1_FMT(TEXCOORDFMT_2D) | - VFT1_TEX2_FMT(TEXCOORDFMT_2D) | - VFT1_TEX3_FMT(TEXCOORDFMT_2D)); - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; - i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; - i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; - i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; - i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; - i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; - i830->meta.Ctx[I830_CTXREG_STENCILTST] = - i830->state.Ctx[I830_CTXREG_STENCILTST]; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] = - i830->state.Ctx[I830_CTXREG_ENABLES_1]; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] = - i830->state.Ctx[I830_CTXREG_ENABLES_2]; - i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; - i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = - i830->state.Ctx[I830_CTXREG_FOGCOLOR]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; - i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; - i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; - - - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - i830->meta.emitted &= ~I830_UPLOAD_CTX; - - - i830->meta.Buffer[I830_DESTREG_SENABLE] = - i830->state.Buffer[I830_DESTREG_SENABLE]; - i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; - i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; - i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; -} - - - -/* Select between front and back draw buffers. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830_state_draw_region(intel, &i830->meta, color_region, depth_region); -} - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); - - i830->meta.active = ACTIVE; - i830->meta.emitted = 0; - - SET_STATE(i830, meta); - set_vertex_format(intel); - set_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - intel_region_release(&i830->meta.draw_region); - intel_region_release(&i830->meta.depth_region); -/* intel_region_release(intel, &i830->meta.tex_region[0]); */ - SET_STATE(i830, state); -} - - - -void -i830InitMetaFuncs(struct i830_context *i830) -{ - i830->intel.vtbl.install_meta_state = install_meta_state; - i830->intel.vtbl.leave_meta_state = leave_meta_state; - i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; - i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; - i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; - i830->intel.vtbl.meta_depth_replace = set_depth_replace; - i830->intel.vtbl.meta_color_mask = set_color_mask; - i830->intel.vtbl.meta_no_texture = set_no_texture; - i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; - i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; - i830->intel.vtbl.meta_draw_region = meta_draw_region; - i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index acda7e70de..3b9b3ae329 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -1127,9 +1127,6 @@ i830InitState(struct i830_context *i830) _mesa_init_driver_state(ctx); - memcpy(&i830->initial, &i830->state, sizeof(i830->state)); - - i830->current = &i830->state; i830->state.emitted = 0; i830->state.active = (I830_UPLOAD_INVARIENT | I830_UPLOAD_RASTER_RULES | diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 4471ca2bbb..a8df77c600 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -25,8 +25,6 @@ * **************************************************************************/ -#include "glapi/glapi.h" - #include "i830_context.h" #include "i830_reg.h" #include "intel_batchbuffer.h" @@ -237,8 +235,8 @@ static GLboolean i830_check_vertex_size(struct intel_context *intel, GLuint expected) { struct i830_context *i830 = i830_context(&intel->ctx); - int vft0 = i830->current->Ctx[I830_CTXREG_VF]; - int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; + int vft0 = i830->state.Ctx[I830_CTXREG_VF]; + int vft1 = i830->state.Ctx[I830_CTXREG_VF2]; int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; int i, sz = 0; @@ -414,7 +412,7 @@ static void i830_emit_state(struct intel_context *intel) { struct i830_context *i830 = i830_context(&intel->ctx); - struct i830_hw_state *state = i830->current; + struct i830_hw_state *state = &i830->state; int i, count; GLuint dirty; dri_bo *aper_array[3 + I830_TEX_UNITS]; @@ -543,10 +541,6 @@ i830_emit_state(struct intel_context *intel) I915_GEM_DOMAIN_SAMPLER, 0, state->tex_offset[i]); } - else if (state == &i830->meta) { - assert(i == 0); - OUT_BATCH(0); - } else { OUT_BATCH(state->tex_offset[i]); } @@ -581,10 +575,6 @@ i830_destroy_context(struct intel_context *intel) intel_region_release(&i830->state.draw_region); intel_region_release(&i830->state.depth_region); - intel_region_release(&i830->meta.draw_region); - intel_region_release(&i830->meta.depth_region); - intel_region_release(&i830->initial.draw_region); - intel_region_release(&i830->initial.depth_region); for (i = 0; i < I830_TEX_UNITS; i++) { if (i830->state.tex_buffer[i] != NULL) { @@ -596,24 +586,22 @@ i830_destroy_context(struct intel_context *intel) _tnl_free_vertices(&intel->ctx); } - -void -i830_state_draw_region(struct intel_context *intel, - struct i830_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) +static void +i830_set_draw_region(struct intel_context *intel, + struct intel_region *color_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct i830_context *i830 = i830_context(&intel->ctx); GLcontext *ctx = &intel->ctx; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); GLuint value; + struct i830_hw_state *state = &i830->state; - ASSERT(state == &i830->state || state == &i830->meta); - - if (state->draw_region != color_region) { + if (state->draw_region != color_regions[0]) { intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); + intel_region_reference(&state->draw_region, color_regions[0]); } if (state->depth_region != depth_region) { intel_region_release(&state->depth_region); @@ -624,7 +612,7 @@ i830_state_draw_region(struct intel_context *intel, * Set stride/cpp values */ i915_set_buf_info_for_region(&state->Buffer[I830_DESTREG_CBUFADDR0], - color_region, BUF_3D_ID_COLOR_BACK); + color_regions[0], BUF_3D_ID_COLOR_BACK); i915_set_buf_info_for_region(&state->Buffer[I830_DESTREG_DBUFADDR0], depth_region, BUF_3D_ID_DEPTH); @@ -674,19 +662,6 @@ i830_state_draw_region(struct intel_context *intel, state->Buffer[I830_DESTREG_DRAWRECT5] = 0; I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - - -} - - -static void -i830_set_draw_region(struct intel_context *intel, - struct intel_region *color_regions[], - struct intel_region *depth_region, - GLuint num_regions) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region); } /* This isn't really handled at the moment. @@ -702,8 +677,7 @@ static void i830_assert_not_dirty( struct intel_context *intel ) { struct i830_context *i830 = i830_context(&intel->ctx); - struct i830_hw_state *state = i830->current; - assert(!get_dirty(state)); + assert(!get_dirty(&i830->state)); } static void diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 7c7711da09..ed9a44ff24 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -28,7 +28,6 @@ #include "i915_context.h" #include "main/imports.h" #include "main/macros.h" -#include "intel_tex.h" #include "intel_tris.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -38,15 +37,11 @@ #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "utils.h" #include "i915_reg.h" #include "i915_program.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" #include "intel_tris.h" #include "intel_span.h" -#include "intel_pixel.h" /*************************************** * Mesa's Driver Functions @@ -116,7 +111,6 @@ i915CreateContext(const __GLcontextModes * mesaVis, _mesa_printf("\ntexmem-0-3 branch\n\n"); i915InitVtbl(i915); - i915InitMetaFuncs(i915); i915InitDriverFunctions(&functions); diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index f55b551139..60b357ec28 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -259,7 +259,7 @@ struct i915_context struct i915_fragment_program *current_program; - struct i915_hw_state meta, initial, state, *current; + struct i915_hw_state state; }; @@ -346,12 +346,6 @@ extern void i915UpdateTextureState(struct intel_context *intel); extern void i915InitTextureFuncs(struct dd_function_table *functions); /*====================================================================== - * i915_metaops.c - */ -void i915InitMetaFuncs(struct i915_context *i915); - - -/*====================================================================== * i915_fragprog.c */ extern void i915ValidateFragmentProgram(struct i915_context *i915); diff --git a/src/mesa/drivers/dri/i915/i915_debug_fp.c b/src/mesa/drivers/dri/i915/i915_debug_fp.c index 84347a01ef..bf500e54fa 100644 --- a/src/mesa/drivers/dri/i915/i915_debug_fp.c +++ b/src/mesa/drivers/dri/i915/i915_debug_fp.c @@ -30,9 +30,6 @@ #include "i915_reg.h" #include "i915_debug.h" #include "main/imports.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_print.h" #define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index a273bd28ea..15e3b87097 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -1205,7 +1205,7 @@ i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) return GL_TRUE; } -static void +static GLboolean i915ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { @@ -1223,7 +1223,10 @@ i915ProgramStringNotify(GLcontext * ctx, } } - _tnl_program_string(ctx, target, prog); + (void) _tnl_program_string(ctx, target, prog); + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } void diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c deleted file mode 100644 index 90a78c6082..0000000000 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ /dev/null @@ -1,507 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/enums.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_regions.h" - -#include "i915_context.h" -#include "i915_reg.h" - -/* We touch almost everything: - */ -#define ACTIVE (I915_UPLOAD_INVARIENT | \ - I915_UPLOAD_CTX | \ - I915_UPLOAD_BUFFERS | \ - I915_UPLOAD_STIPPLE | \ - I915_UPLOAD_PROGRAM | \ - I915_UPLOAD_FOG | \ - I915_UPLOAD_TEX(0)) - -#define SET_STATE( i915, STATE ) \ -do { \ - i915->current->emitted &= ~ACTIVE; \ - i915->current = &i915->STATE; \ - i915->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -meta_no_stencil_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_no_depth_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_depth_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->meta.Ctx[I915_CTXREG_LIS6] |= - COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -meta_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint op = STENCILOP_REPLACE; - GLuint func = COMPAREFUNC_ALWAYS; - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(s_mask)); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); - - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | - (func << S5_STENCIL_TEST_FUNC_SHIFT)); - - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -static void -meta_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - const GLuint mask = (S5_WRITEDISABLE_RED | - S5_WRITEDISABLE_GREEN | - S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); - - /* Copy colormask state from "regular" hw context. - */ - if (state) { - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; - i915->meta.Ctx[I915_CTXREG_LIS5] |= - (i915->state.Ctx[I915_CTXREG_LIS5] & mask); - } - else - i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); - - i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; - i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; - i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; - i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; - i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; - - i915->meta.Buffer[I915_DESTREG_SENABLE] = - i915->state.Buffer[I915_DESTREG_SENABLE]; - i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; - i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; - - i915->meta.emitted &= ~I915_UPLOAD_FOG; - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - - -#define REG( type, nr ) (((type)<<5)|(nr)) - -#define REG_R(x) REG(REG_TYPE_R, x) -#define REG_T(x) REG(REG_TYPE_T, x) -#define REG_CONST(x) REG(REG_TYPE_CONST, x) -#define REG_S(x) REG(REG_TYPE_S, x) -#define REG_OC REG(REG_TYPE_OC, 0) -#define REG_OD REG(REG_TYPE_OD, 0) -#define REG_U(x) REG(REG_TYPE_U, x) - -#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) -#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) -#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) -#define REG_T_TEX(x) REG(REG_TYPE_T, x) - - -#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) -#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) -#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) -#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) -#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) -#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) -#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) - -#define T0_SAMPLER( unit ) ((unit)<<T0_SAMPLER_NR_SHIFT) - -#define T1_ADDRESS_REG( type, nr ) (((type)<<T1_ADDRESS_REG_TYPE_SHIFT)| \ - ((nr)<<T1_ADDRESS_REG_NR_SHIFT)) - - -#define A1_SRC0_XYZW ((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \ - (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \ - (SRC_W << A1_SRC0_CHANNEL_W_SHIFT)) - -#define A1_SRC1_XY ((SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | \ - (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT)) - -#define A2_SRC1_ZW ((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC1_CHANNEL_W_SHIFT)) - -#define A2_SRC2_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ - (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) - - - - - -static void -meta_no_texture(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare incoming diffuse color: - */ - (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = mov(t_diffuse) - */ - (A0_MOV | - A0_DEST_REG(REG_OC) | - A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), - (A1_SRC0_XYZW), - 0, - }; - - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - -static void -meta_texture_blend_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare the sampler: - */ - (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), - D1_MBZ, - D2_MBZ, - - /* Declare the interpolated texture coordinate: - */ - (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = texld(sample0, texcoord0) - */ - (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), - T1_ADDRESS_REG(REG_TYPE_T, 0), - T2_MBZ - }; - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - - - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -meta_tex_rect_source(struct intel_context *intel, - dri_bo *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint unit = 0; - GLint numLevels = 1; - GLuint *state = i915->meta.Tex[0]; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - - if ((pitch * cpp) & 3) { - _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); - return GL_FALSE; - } - -/* intel_region_release(&i915->meta.tex_region[0]); */ -/* intel_region_reference(&i915->meta.tex_region[0], region); */ - i915->meta.tex_buffer[0] = buffer; - i915->meta.tex_offset[0] = offset; - - state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | - ((pitch - 1) << MS3_WIDTH_SHIFT) | - textureFormat | MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); - - state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | - (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); - - state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); - - state[I915_TEXREG_SS4] = 0; - - i915->meta.emitted &= ~I915_UPLOAD_TEX(0); - return GL_TRUE; -} - - -/** - * Set the color and depth drawing region for meta ops. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->meta, color_region, depth_region); -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - i915->meta.Ctx[I915_CTXREG_LIS2] = - (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | - S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); - - i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; - - i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); - i915->meta.active = ACTIVE; - i915->meta.emitted = 0; - - SET_STATE(i915, meta); - set_vertex_format(intel); - meta_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - intel_region_release(&i915->meta.draw_region); - intel_region_release(&i915->meta.depth_region); -/* intel_region_release(&i915->meta.tex_region[0]); */ - SET_STATE(i915, state); -} - - - -void -i915InitMetaFuncs(struct i915_context *i915) -{ - i915->intel.vtbl.install_meta_state = install_meta_state; - i915->intel.vtbl.leave_meta_state = leave_meta_state; - i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; - i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; - i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; - i915->intel.vtbl.meta_depth_replace = meta_depth_replace; - i915->intel.vtbl.meta_color_mask = meta_color_mask; - i915->intel.vtbl.meta_no_texture = meta_no_texture; - i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; - i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; - i915->intel.vtbl.meta_draw_region = meta_draw_region; - i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 9d7a9e1dfe..7275617a6f 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -1157,7 +1157,4 @@ i915InitState(struct i915_context *i915) i915_init_packets(i915); _mesa_init_driver_state(ctx); - - memcpy(&i915->initial, &i915->state, sizeof(i915->state)); - i915->current = &i915->state; } diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 266e6848c3..392126b7dc 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -37,17 +37,13 @@ #include "tnl/t_vertex.h" #include "intel_batchbuffer.h" -#include "intel_tex.h" #include "intel_regions.h" #include "intel_tris.h" #include "intel_fbo.h" -#include "intel_chipset.h" #include "i915_reg.h" #include "i915_context.h" -#include "glapi/glapi.h" - static void i915_render_prevalidate(struct intel_context *intel) { @@ -100,8 +96,8 @@ static GLboolean i915_check_vertex_size(struct intel_context *intel, GLuint expected) { struct i915_context *i915 = i915_context(&intel->ctx); - int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; - int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; + int lis2 = i915->state.Ctx[I915_CTXREG_LIS2]; + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4]; int i, sz = 0; switch (lis4 & S4_VFMT_XYZW_MASK) { @@ -287,7 +283,7 @@ static void i915_emit_state(struct intel_context *intel) { struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; + struct i915_hw_state *state = &i915->state; int i, count, aper_count; GLuint dirty; dri_bo *aper_array[3 + I915_TEX_UNITS]; @@ -443,10 +439,6 @@ i915_emit_state(struct intel_context *intel) I915_GEM_DOMAIN_SAMPLER, 0, state->tex_offset[i]); } - else if (state == &i915->meta) { - assert(i == 0); - OUT_BATCH(0); - } else { OUT_BATCH(state->tex_offset[i]); } @@ -500,10 +492,6 @@ i915_destroy_context(struct intel_context *intel) intel_region_release(&i915->state.draw_region); intel_region_release(&i915->state.depth_region); - intel_region_release(&i915->meta.draw_region); - intel_region_release(&i915->meta.depth_region); - intel_region_release(&i915->initial.draw_region); - intel_region_release(&i915->initial.depth_region); for (i = 0; i < I915_TEX_UNITS; i++) { if (i915->state.tex_buffer[i] != NULL) { @@ -533,29 +521,22 @@ i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region, } } -/** - * Set the drawing regions for the color and depth/stencil buffers. - * This involves setting the pitch, cpp and buffer ID/location. - * Also set pixel format for color and Z rendering - * Used for setting both regular and meta state. - */ -void -i915_state_draw_region(struct intel_context *intel, - struct i915_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) +static void +i915_set_draw_region(struct intel_context *intel, + struct intel_region *color_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct i915_context *i915 = i915_context(&intel->ctx); GLcontext *ctx = &intel->ctx; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); GLuint value; + struct i915_hw_state *state = &i915->state; - ASSERT(state == &i915->state || state == &i915->meta); - - if (state->draw_region != color_region) { + if (state->draw_region != color_regions[0]) { intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); + intel_region_reference(&state->draw_region, color_regions[0]); } if (state->depth_region != depth_region) { intel_region_release(&state->depth_region); @@ -566,7 +547,7 @@ i915_state_draw_region(struct intel_context *intel, * Set stride/cpp values */ i915_set_buf_info_for_region(&state->Buffer[I915_DESTREG_CBUFADDR0], - color_region, BUF_3D_ID_COLOR_BACK); + color_regions[0], BUF_3D_ID_COLOR_BACK); i915_set_buf_info_for_region(&state->Buffer[I915_DESTREG_DBUFADDR0], depth_region, BUF_3D_ID_DEPTH); @@ -627,17 +608,6 @@ i915_state_draw_region(struct intel_context *intel, } -static void -i915_set_draw_region(struct intel_context *intel, - struct intel_region *color_regions[], - struct intel_region *depth_region, - GLuint num_regions) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->state, color_regions[0], depth_region); -} - - static void i915_new_batch(struct intel_context *intel) @@ -655,8 +625,7 @@ static void i915_assert_not_dirty( struct intel_context *intel ) { struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; - GLuint dirty = get_dirty(state); + GLuint dirty = get_dirty(&i915->state); assert(!dirty); } diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index e99baf8e0e..6d498c5654 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -52,8 +52,6 @@ #include "intel_buffers.h" #include "intel_reg.h" #include "intel_span.h" -#include "intel_tex.h" -#include "intel_chipset.h" #include "i830_context.h" #include "i830_reg.h" diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c index bac1c3a49c..fa2d394b22 100644 --- a/src/mesa/drivers/dri/i965/brw_cc.c +++ b/src/mesa/drivers/dri/i965/brw_cc.c @@ -34,9 +34,7 @@ #include "brw_state.h" #include "brw_defines.h" #include "brw_util.h" -#include "intel_fbo.h" #include "main/macros.h" -#include "main/enums.h" static void prepare_cc_vp( struct brw_context *brw ) { @@ -295,8 +293,7 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT, key, sizeof(*key), &brw->cc.vp_bo, 1, - &cc, sizeof(cc), - NULL, NULL); + &cc, sizeof(cc)); /* Emit CC viewport relocation */ dri_bo_emit_reloc(bo, diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index af1d975de9..d3275c7a89 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -130,13 +130,14 @@ static void compile_clip_prog( struct brw_context *brw, /* Upload */ dri_bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_upload_cache( &brw->cache, - BRW_CLIP_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->clip.prog_data ); + brw->clip.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, + BRW_CLIP_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + sizeof(c.prog_data), + &brw->clip.prog_data); } /* Calculate interpolants for triangle and line rasterization. diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index afc0b11049..ceb62a3116 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c index 8458f61c5a..7f47634dca 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_point.c +++ b/src/mesa/drivers/dri/i965/brw_clip_point.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index c8f24a94e4..424c9a1f19 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -32,7 +32,6 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "main/macros.h" struct brw_clip_unit_key { unsigned int total_grf; @@ -143,8 +142,7 @@ clip_unit_create_from_key(struct brw_context *brw, bo = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT, key, sizeof(*key), &brw->clip.prog_bo, 1, - &clip, sizeof(clip), - NULL, NULL); + &clip, sizeof(clip)); /* Emit clip program relocation */ assert(brw->clip.prog_bo); diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index cfbb8f2686..815211acc2 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" static void release_tmps( struct brw_clip_compile *c ) diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c index ad1bfa435f..f36d22fdbf 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c +++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index 86fed59fa4..14bc889b0f 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -40,7 +40,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 7bb15956b5..65f51be341 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -33,7 +33,6 @@ #include "main/imports.h" #include "main/api_noop.h" #include "main/macros.h" -#include "main/vtxfmt.h" #include "main/simple_list.h" #include "shader/shader_api.h" @@ -41,16 +40,9 @@ #include "brw_defines.h" #include "brw_draw.h" #include "brw_state.h" -#include "brw_vs.h" -#include "intel_tex.h" -#include "intel_blit.h" -#include "intel_batchbuffer.h" -#include "intel_pixel.h" #include "intel_span.h" #include "tnl/t_pipeline.h" -#include "utils.h" - /*************************************** * Mesa's Driver Functions diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 0dd3087143..21c4cd38a7 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -131,7 +131,6 @@ struct brw_context; #define BRW_NEW_WM_INPUT_DIMENSIONS 0x100 #define BRW_NEW_PSP 0x800 #define BRW_NEW_WM_SURFACES 0x1000 -#define BRW_NEW_FENCE 0x2000 #define BRW_NEW_INDICES 0x4000 #define BRW_NEW_VERTICES 0x8000 /** @@ -332,7 +331,6 @@ struct brw_cache { struct brw_cache_item **items; GLuint size, n_items; - GLuint aux_size[BRW_MAX_CACHE]; char *name[BRW_MAX_CACHE]; /* Record of the last BOs chosen for each cache_id. Used to set @@ -574,15 +572,11 @@ struct brw_context GLfloat *last_buf; GLuint last_bufsz; - /** - * Whether we should create a new bo instead of reusing the old one - * (if we just dispatch the batch pointing at the old one. - */ - GLboolean need_new_bo; } curbe; struct { struct brw_vs_prog_data *prog_data; + int8_t *constant_map; /* variable array following prog_data */ dri_bo *prog_bo; dri_bo *state_bo; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 190310afbb..6cb8edb611 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -179,6 +179,7 @@ static GLfloat fixed_plane[6][4] = { */ static void prepare_constant_buffer(struct brw_context *brw) { + struct intel_context *intel = &brw->intel; GLcontext *ctx = &brw->intel.ctx; const struct brw_vertex_program *vp = brw_vertex_program_const(brw->vertex_program); @@ -256,13 +257,24 @@ static void prepare_constant_buffer(struct brw_context *brw) */ _mesa_load_state_parameters(ctx, vp->program.Base.Parameters); - /* XXX just use a memcpy here */ - for (i = 0; i < nr; i++) { - const GLfloat *value = vp->program.Base.Parameters->ParameterValues[i]; - buf[offset + i * 4 + 0] = value[0]; - buf[offset + i * 4 + 1] = value[1]; - buf[offset + i * 4 + 2] = value[2]; - buf[offset + i * 4 + 3] = value[3]; + if (vp->use_const_buffer) { + /* Load the subset of push constants that will get used when + * we also have a pull constant buffer. + */ + for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) { + if (brw->vs.constant_map[i] != -1) { + assert(brw->vs.constant_map[i] <= nr); + memcpy(buf + offset + brw->vs.constant_map[i] * 4, + vp->program.Base.Parameters->ParameterValues[i], + 4 * sizeof(float)); + } + } + } else { + for (i = 0; i < nr; i++) { + memcpy(buf + offset + i * 4, + vp->program.Base.Parameters->ParameterValues[i], + 4 * sizeof(float)); + } } } @@ -293,9 +305,9 @@ static void prepare_constant_buffer(struct brw_context *brw) brw->curbe.last_bufsz = bufsz; if (brw->curbe.curbe_bo != NULL && - (brw->curbe.need_new_bo || - brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size)) + brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size) { + intel_bo_unmap_gtt_preferred(intel, brw->curbe.curbe_bo); dri_bo_unreference(brw->curbe.curbe_bo); brw->curbe.curbe_bo = NULL; } @@ -307,6 +319,7 @@ static void prepare_constant_buffer(struct brw_context *brw) brw->curbe.curbe_bo = dri_bo_alloc(brw->intel.bufmgr, "CURBE", 4096, 1 << 6); brw->curbe.curbe_next_offset = 0; + intel_bo_map_gtt_preferred(intel, brw->curbe.curbe_bo, GL_TRUE); } brw->curbe.curbe_offset = brw->curbe.curbe_next_offset; @@ -315,7 +328,9 @@ static void prepare_constant_buffer(struct brw_context *brw) /* Copy data to the buffer: */ - dri_bo_subdata(brw->curbe.curbe_bo, brw->curbe.curbe_offset, bufsz, buf); + memcpy(brw->curbe.curbe_bo->virtual + brw->curbe.curbe_offset, + buf, + bufsz); } brw_add_validated_bo(brw, brw->curbe.curbe_bo); diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index df281b27d5..d510d767f9 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -39,10 +39,8 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_fallback.h" #include "intel_batchbuffer.h" -#include "intel_buffer_objects.h" #define FILE_DEBUG_FLAG DEBUG_BATCH diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index c773b71507..c46b9ba89c 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -29,19 +29,15 @@ #include "main/glheader.h" #include "main/bufferobj.h" #include "main/context.h" -#include "main/state.h" -#include "main/api_validate.h" #include "main/enums.h" #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_fallback.h" #include "intel_batchbuffer.h" #include "intel_buffer_objects.h" -#include "intel_tex.h" static GLuint double_types[5] = { 0, @@ -59,6 +55,14 @@ static GLuint float_types[5] = { BRW_SURFACEFORMAT_R32G32B32A32_FLOAT }; +static GLuint half_float_types[5] = { + 0, + BRW_SURFACEFORMAT_R16_FLOAT, + BRW_SURFACEFORMAT_R16G16_FLOAT, + 0, /* can't seem to render this one */ + BRW_SURFACEFORMAT_R16G16B16A16_FLOAT +}; + static GLuint uint_types_norm[5] = { 0, BRW_SURFACEFORMAT_R32_UNORM, @@ -172,6 +176,7 @@ static GLuint get_surface_type( GLenum type, GLuint size, switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; + case GL_HALF_FLOAT: return half_float_types[size]; case GL_INT: return int_types_norm[size]; case GL_SHORT: return short_types_norm[size]; case GL_BYTE: return byte_types_norm[size]; @@ -194,6 +199,7 @@ static GLuint get_surface_type( GLenum type, GLuint size, switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; + case GL_HALF_FLOAT: return half_float_types[size]; case GL_INT: return int_types_scale[size]; case GL_SHORT: return short_types_scale[size]; case GL_BYTE: return byte_types_scale[size]; @@ -211,6 +217,7 @@ static GLuint get_size( GLenum type ) switch (type) { case GL_DOUBLE: return sizeof(GLdouble); case GL_FLOAT: return sizeof(GLfloat); + case GL_HALF_FLOAT: return sizeof(GLhalfARB); case GL_INT: return sizeof(GLint); case GL_SHORT: return sizeof(GLshort); case GL_BYTE: return sizeof(GLbyte); diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index fe5c1ae279..ba401c215c 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -36,13 +36,9 @@ #include "swrast/swrast.h" #include "tnl/tnl.h" #include "brw_context.h" -#include "brw_fallback.h" -#include "intel_chipset.h" #include "intel_fbo.h" #include "intel_regions.h" -#include "glapi/glapi.h" - #define FILE_DEBUG_FLAG DEBUG_FALLBACKS static GLboolean do_check_fallback(struct brw_context *brw) diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 1bc3eccf49..7261b316c1 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -125,12 +125,13 @@ static void compile_gs_prog( struct brw_context *brw, /* Upload */ dri_bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_upload_cache( &brw->cache, BRW_GS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->gs.prog_data ); + brw->gs.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_GS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + sizeof(c.prog_data), + &brw->gs.prog_data); } static const GLenum gs_prim[GL_POLYGON+1] = { diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index a81b972ef4..dd7b057d62 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -40,7 +40,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_gs.h" static void brw_gs_alloc_regs( struct brw_gs_compile *c, diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c index 1af5790a67..d8ad5cecf3 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_state.c @@ -34,7 +34,6 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "main/macros.h" struct brw_gs_unit_key { unsigned int total_grf; @@ -108,8 +107,7 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) bo = brw_upload_cache(&brw->cache, BRW_GS_UNIT, key, sizeof(*key), &brw->gs.prog_bo, 1, - &gs, sizeof(gs), - NULL, NULL); + &gs, sizeof(gs)); if (key->prog_active) { /* Emit GS program relocation */ diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 7b70f787b7..f708ee0063 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -327,7 +327,7 @@ const struct brw_tracked_state brw_polygon_stipple = { static void upload_polygon_stipple_offset(struct brw_context *brw) { - __DRIdrawable *dPriv = brw->intel.driDrawable; + GLcontext *ctx = &brw->intel.ctx; struct brw_polygon_stipple_offset bpso; memset(&bpso, 0, sizeof(bpso)); @@ -343,8 +343,8 @@ static void upload_polygon_stipple_offset(struct brw_context *brw) * worry about. */ if (brw->intel.ctx.DrawBuffer->Name == 0) { - bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31; - bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31; + bpso.bits0.x_offset = 0; + bpso.bits0.y_offset = (32 - (ctx->DrawBuffer->Height & 31)) & 31; } else { bpso.bits0.y_offset = 0; diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index bac69187c1..c78f7b38ae 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -37,7 +37,6 @@ #include "tnl/tnl.h" #include "brw_context.h" -#include "brw_util.h" #include "brw_wm.h" static void brwBindProgram( GLcontext *ctx, @@ -112,9 +111,10 @@ static GLboolean brwIsProgramNative( GLcontext *ctx, return GL_TRUE; } -static void brwProgramStringNotify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) + +static GLboolean brwProgramStringNotify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); @@ -151,6 +151,9 @@ static void brwProgramStringNotify( GLcontext *ctx, */ _tnl_program_string(ctx, target, prog); } + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } void brwInitFragProgFuncs( struct dd_function_table *functions ) diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index 968890f7fb..8e6839b812 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -117,12 +117,13 @@ static void compile_sf_prog( struct brw_context *brw, /* Upload */ dri_bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_upload_cache( &brw->cache, BRW_SF_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->sf.prog_data ); + brw->sf.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_SF_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + sizeof(c.prog_data), + &brw->sf.prog_data); } /* Calculate interpolants for triangle and line rasterization. diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 09223b7cfb..847c886279 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -35,7 +35,6 @@ #include "brw_state.h" #include "brw_defines.h" #include "main/macros.h" -#include "intel_fbo.h" static void upload_sf_vp(struct brw_context *brw) { @@ -70,9 +69,9 @@ static void upload_sf_vp(struct brw_context *brw) * for DrawBuffer->_[XY]{min,max} */ - /* The scissor only needs to handle the intersection of drawable and - * scissor rect. Clipping to the boundaries of static shared buffers - * for front/back/depth is covered by looping over cliprects in brw_draw.c. + /* The scissor only needs to handle the intersection of drawable + * and scissor rect, since there are no longer cliprects for shared + * buffers with DRI2. * * Note that the hardware's coordinates are inclusive, while Mesa's min is * inclusive but max is exclusive. @@ -309,8 +308,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, bo = brw_upload_cache(&brw->cache, BRW_SF_UNIT, key, sizeof(*key), reloc_bufs, 2, - &sf, sizeof(sf), - NULL, NULL); + &sf, sizeof(sf)); /* STATE_PREFETCH command description describes this state as being * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain. diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 9c9d145c4b..536fe8b249 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -124,16 +124,26 @@ dri_bo *brw_cache_data(struct brw_cache *cache, dri_bo **reloc_bufs, GLuint nr_reloc_bufs); -dri_bo *brw_upload_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_sz, - dri_bo **reloc_bufs, - GLuint nr_reloc_bufs, - const void *data, - GLuint data_sz, - const void *aux, - void *aux_return ); +drm_intel_bo *brw_upload_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_sz); + +drm_intel_bo *brw_upload_cache_with_auxdata(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_sz, + const void *aux, + GLuint aux_sz, + void *aux_return); dri_bo *brw_search_cache( struct brw_cache *cache, enum brw_cache_id cache_id, diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index e4c9ba7d87..5fc47b0420 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -71,25 +71,23 @@ static GLuint -hash_key(const void *key, GLuint key_size, - dri_bo **reloc_bufs, GLuint nr_reloc_bufs) +hash_key(struct brw_cache_item *item) { - GLuint *ikey = (GLuint *)key; - GLuint hash = 0, i; + GLuint *ikey = (GLuint *)item->key; + GLuint hash = item->cache_id, i; - assert(key_size % 4 == 0); + assert(item->key_size % 4 == 0); /* I'm sure this can be improved on: */ - for (i = 0; i < key_size/4; i++) { + for (i = 0; i < item->key_size/4; i++) { hash ^= ikey[i]; hash = (hash << 5) | (hash >> 27); } /* Include the BO pointers as key data as well */ - ikey = (GLuint *)reloc_bufs; - key_size = nr_reloc_bufs * sizeof(dri_bo *); - for (i = 0; i < key_size/4; i++) { + ikey = (GLuint *)item->reloc_bufs; + for (i = 0; i < item->nr_reloc_bufs * sizeof(drm_intel_bo *) / 4; i++) { hash ^= ikey[i]; hash = (hash << 5) | (hash >> 27); } @@ -114,11 +112,22 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, cache->brw->state.dirty.cache |= 1 << cache_id; } +static int +brw_cache_item_equals(const struct brw_cache_item *a, + const struct brw_cache_item *b) +{ + return a->cache_id == b->cache_id && + a->hash == b->hash && + a->key_size == b->key_size && + (memcmp(a->key, b->key, a->key_size) == 0) && + a->nr_reloc_bufs == b->nr_reloc_bufs && + (memcmp(a->reloc_bufs, b->reloc_bufs, + a->nr_reloc_bufs * sizeof(dri_bo *)) == 0); +} static struct brw_cache_item * -search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, - GLuint hash, const void *key, GLuint key_size, - dri_bo **reloc_bufs, GLuint nr_reloc_bufs) +search_cache(struct brw_cache *cache, GLuint hash, + struct brw_cache_item *lookup) { struct brw_cache_item *c; @@ -133,13 +142,7 @@ search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, #endif for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->cache_id == cache_id && - c->hash == hash && - c->key_size == key_size && - memcmp(c->key, key, key_size) == 0 && - c->nr_reloc_bufs == nr_reloc_bufs && - memcmp(c->reloc_bufs, reloc_bufs, - nr_reloc_bufs * sizeof(dri_bo *)) == 0) + if (brw_cache_item_equals(lookup, c)) return c; } @@ -182,10 +185,18 @@ brw_search_cache(struct brw_cache *cache, void *aux_return) { struct brw_cache_item *item; - GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); + struct brw_cache_item lookup; + GLuint hash; - item = search_cache(cache, cache_id, hash, key, key_size, - reloc_bufs, nr_reloc_bufs); + lookup.cache_id = cache_id; + lookup.key = key; + lookup.key_size = key_size; + lookup.reloc_bufs = reloc_bufs; + lookup.nr_reloc_bufs = nr_reloc_bufs; + hash = hash_key(&lookup); + lookup.hash = hash; + + item = search_cache(cache, hash, &lookup); if (item == NULL) return NULL; @@ -200,26 +211,34 @@ brw_search_cache(struct brw_cache *cache, } -dri_bo * -brw_upload_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_size, - dri_bo **reloc_bufs, - GLuint nr_reloc_bufs, - const void *data, - GLuint data_size, - const void *aux, - void *aux_return ) +drm_intel_bo * +brw_upload_cache_with_auxdata(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_size, + const void *aux, + GLuint aux_size, + void *aux_return) { struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item); - GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); + GLuint hash; GLuint relocs_size = nr_reloc_bufs * sizeof(dri_bo *); - GLuint aux_size = cache->aux_size[cache_id]; void *tmp; dri_bo *bo; int i; + item->cache_id = cache_id; + item->key = key; + item->key_size = key_size; + item->reloc_bufs = reloc_bufs; + item->nr_reloc_bufs = nr_reloc_bufs; + hash = hash_key(item); + item->hash = hash; + /* Create the buffer object to contain the data */ bo = dri_bo_alloc(cache->brw->intel.bufmgr, cache->name[cache_id], data_size, 1 << 6); @@ -229,19 +248,15 @@ brw_upload_cache( struct brw_cache *cache, tmp = _mesa_malloc(key_size + aux_size + relocs_size); memcpy(tmp, key, key_size); - memcpy(tmp + key_size, aux, cache->aux_size[cache_id]); + memcpy(tmp + key_size, aux, aux_size); memcpy(tmp + key_size + aux_size, reloc_bufs, relocs_size); for (i = 0; i < nr_reloc_bufs; i++) { if (reloc_bufs[i] != NULL) dri_bo_reference(reloc_bufs[i]); } - item->cache_id = cache_id; item->key = tmp; - item->hash = hash; - item->key_size = key_size; item->reloc_bufs = tmp + key_size + aux_size; - item->nr_reloc_bufs = nr_reloc_bufs; item->bo = bo; dri_bo_reference(bo); @@ -255,7 +270,6 @@ brw_upload_cache( struct brw_cache *cache, cache->n_items++; if (aux_return) { - assert(cache->aux_size[cache_id]); *(void **)aux_return = (void *)((char *)item->key + item->key_size); } @@ -272,6 +286,23 @@ brw_upload_cache( struct brw_cache *cache, return bo; } +drm_intel_bo * +brw_upload_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_size) +{ + return brw_upload_cache_with_auxdata(cache, cache_id, + key, key_size, + reloc_bufs, nr_reloc_bufs, + data, data_size, + NULL, 0, + NULL); +} /** * Wrapper around brw_cache_data_sz using the cache_id's canonical key size. @@ -292,11 +323,18 @@ brw_cache_data(struct brw_cache *cache, GLuint nr_reloc_bufs) { dri_bo *bo; - struct brw_cache_item *item; - GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs); - - item = search_cache(cache, cache_id, hash, data, data_size, - reloc_bufs, nr_reloc_bufs); + struct brw_cache_item *item, lookup; + GLuint hash; + + lookup.cache_id = cache_id; + lookup.key = data; + lookup.key_size = data_size; + lookup.reloc_bufs = reloc_bufs; + lookup.nr_reloc_bufs = nr_reloc_bufs; + hash = hash_key(&lookup); + lookup.hash = hash; + + item = search_cache(cache, hash, &lookup); if (item) { update_cache_last(cache, cache_id, item->bo); dri_bo_reference(item->bo); @@ -306,8 +344,7 @@ brw_cache_data(struct brw_cache *cache, bo = brw_upload_cache(cache, cache_id, data, data_size, reloc_bufs, nr_reloc_bufs, - data, data_size, - NULL, NULL); + data, data_size); return bo; } @@ -321,11 +358,9 @@ enum pool_type { static void brw_init_cache_id(struct brw_cache *cache, const char *name, - enum brw_cache_id id, - GLuint aux_size) + enum brw_cache_id id) { cache->name[id] = strdup(name); - cache->aux_size[id] = aux_size; } @@ -341,80 +376,28 @@ brw_init_non_surface_cache(struct brw_context *brw) cache->items = (struct brw_cache_item **) _mesa_calloc(cache->size * sizeof(struct brw_cache_item)); - brw_init_cache_id(cache, - "CC_VP", - BRW_CC_VP, - 0); - - brw_init_cache_id(cache, - "CC_UNIT", - BRW_CC_UNIT, - 0); - - brw_init_cache_id(cache, - "WM_PROG", - BRW_WM_PROG, - sizeof(struct brw_wm_prog_data)); - - brw_init_cache_id(cache, - "SAMPLER_DEFAULT_COLOR", - BRW_SAMPLER_DEFAULT_COLOR, - 0); - - brw_init_cache_id(cache, - "SAMPLER", - BRW_SAMPLER, - 0); - - brw_init_cache_id(cache, - "WM_UNIT", - BRW_WM_UNIT, - 0); - - brw_init_cache_id(cache, - "SF_PROG", - BRW_SF_PROG, - sizeof(struct brw_sf_prog_data)); - - brw_init_cache_id(cache, - "SF_VP", - BRW_SF_VP, - 0); - - brw_init_cache_id(cache, - "SF_UNIT", - BRW_SF_UNIT, - 0); - - brw_init_cache_id(cache, - "VS_UNIT", - BRW_VS_UNIT, - 0); - - brw_init_cache_id(cache, - "VS_PROG", - BRW_VS_PROG, - sizeof(struct brw_vs_prog_data)); - - brw_init_cache_id(cache, - "CLIP_UNIT", - BRW_CLIP_UNIT, - 0); - - brw_init_cache_id(cache, - "CLIP_PROG", - BRW_CLIP_PROG, - sizeof(struct brw_clip_prog_data)); - - brw_init_cache_id(cache, - "GS_UNIT", - BRW_GS_UNIT, - 0); - - brw_init_cache_id(cache, - "GS_PROG", - BRW_GS_PROG, - sizeof(struct brw_gs_prog_data)); + brw_init_cache_id(cache, "CC_VP", BRW_CC_VP); + brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT); + brw_init_cache_id(cache, "WM_PROG", BRW_WM_PROG); + brw_init_cache_id(cache, "SAMPLER_DEFAULT_COLOR", BRW_SAMPLER_DEFAULT_COLOR); + brw_init_cache_id(cache, "SAMPLER", BRW_SAMPLER); + brw_init_cache_id(cache, "WM_UNIT", BRW_WM_UNIT); + brw_init_cache_id(cache, "SF_PROG", BRW_SF_PROG); + brw_init_cache_id(cache, "SF_VP", BRW_SF_VP); + + brw_init_cache_id(cache, "SF_UNIT", BRW_SF_UNIT); + + brw_init_cache_id(cache, "VS_UNIT", BRW_VS_UNIT); + + brw_init_cache_id(cache, "VS_PROG", BRW_VS_PROG); + + brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT); + + brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG); + + brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT); + + brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG); } @@ -430,15 +413,8 @@ brw_init_surface_cache(struct brw_context *brw) cache->items = (struct brw_cache_item **) _mesa_calloc(cache->size * sizeof(struct brw_cache_item)); - brw_init_cache_id(cache, - "SS_SURFACE", - BRW_SS_SURFACE, - 0); - - brw_init_cache_id(cache, - "SS_SURF_BIND", - BRW_SS_SURF_BIND, - 0); + brw_init_cache_id(cache, "SS_SURFACE", BRW_SS_SURFACE); + brw_init_cache_id(cache, "SS_SURF_BIND", BRW_SS_SURF_BIND); } diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c index e94fa7d2b4..020ac523b6 100644 --- a/src/mesa/drivers/dri/i965/brw_state_dump.c +++ b/src/mesa/drivers/dri/i965/brw_state_dump.c @@ -28,7 +28,6 @@ #include "main/mtypes.h" #include "brw_context.h" -#include "brw_state.h" #include "brw_defines.h" /** diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index af8dfb4c15..0ecbef1ef9 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -36,13 +36,7 @@ #include "intel_batchbuffer.h" #include "intel_buffers.h" -/* This is used to initialize brw->state.atoms[]. We could use this - * list directly except for a single atom, brw_constant_buffer, which - * has a .dirty value which changes according to the parameters of the - * current fragment and vertex programs, and so cannot be a static - * value. - */ -const struct brw_tracked_state *atoms[] = +static const struct brw_tracked_state *atoms[] = { &brw_check_fallback, @@ -208,7 +202,6 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_CONTEXT), DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), DEFINE_BIT(BRW_NEW_PSP), - DEFINE_BIT(BRW_NEW_FENCE), DEFINE_BIT(BRW_NEW_INDICES), DEFINE_BIT(BRW_NEW_INDEX_BUFFER), DEFINE_BIT(BRW_NEW_VERTICES), diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 64a9535282..09edfd81fd 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -36,7 +36,6 @@ #include "intel_tex_layout.h" #include "intel_context.h" #include "main/macros.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_MIPTREE diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index fd055e225e..44b085e214 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -35,6 +35,7 @@ #include "brw_util.h" #include "brw_state.h" #include "shader/prog_print.h" +#include "shader/prog_parameter.h" @@ -42,9 +43,11 @@ static void do_vs_prog( struct brw_context *brw, struct brw_vertex_program *vp, struct brw_vs_prog_key *key ) { + GLcontext *ctx = &brw->intel.ctx; GLuint program_size; const GLuint *program; struct brw_vs_compile c; + int aux_size; memset(&c, 0, sizeof(c)); memcpy(&c.key, key, sizeof(*key)); @@ -73,13 +76,27 @@ static void do_vs_prog( struct brw_context *brw, */ program = brw_get_program(&c.func, &program_size); + /* We upload from &c.prog_data including the constant_map assuming + * they're packed together. It would be nice to have a + * compile-time assert macro here. + */ + assert(c.constant_map == (int8_t *)&c.prog_data + + sizeof(c.prog_data)); + assert(ctx->Const.VertexProgram.MaxNativeParameters == + ARRAY_SIZE(c.constant_map)); + + aux_size = sizeof(c.prog_data); + if (c.vp->use_const_buffer) + aux_size += c.vp->program.Base.Parameters->NumParameters; + dri_bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_upload_cache( &brw->cache, BRW_VS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->vs.prog_data ); + brw->vs.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_VS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + aux_size, + &brw->vs.prog_data); } @@ -109,6 +126,8 @@ static void brw_upload_vs_prog(struct brw_context *brw) &brw->vs.prog_data); if (brw->vs.prog_bo == NULL) do_vs_prog(brw, vp, &key); + brw->vs.constant_map = ((int8_t *)brw->vs.prog_data + + sizeof(*brw->vs.prog_data)); } diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index 4a591365c9..95e0501b1e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -51,6 +51,7 @@ struct brw_vs_compile { struct brw_compile func; struct brw_vs_prog_key key; struct brw_vs_prog_data prog_data; + int8_t constant_map[1024]; struct brw_vertex_program *vp; @@ -81,6 +82,8 @@ struct brw_vs_compile { GLint index; struct brw_reg reg; } current_const[3]; + + GLboolean needs_stack; }; void brw_vs_emit( struct brw_vs_compile *c ); diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 1b84dd505f..4f4eef85e8 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -104,9 +104,47 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) /* Vertex program parameters from curbe: */ if (c->vp->use_const_buffer) { - /* get constants from a real constant buffer */ - c->prog_data.curb_read_length = 0; - c->prog_data.nr_params = 4; /* XXX 0 causes a bug elsewhere... */ + int max_constant = BRW_MAX_GRF - 20 - c->vp->program.Base.NumTemporaries; + int constant = 0; + + /* We've got more constants than we can load with the push + * mechanism. This is often correlated with reladdr loads where + * we should probably be using a pull mechanism anyway to avoid + * excessive reading. However, the pull mechanism is slow in + * general. So, we try to allocate as many non-reladdr-loaded + * constants through the push buffer as we can before giving up. + */ + memset(c->constant_map, -1, c->vp->program.Base.Parameters->NumParameters); + for (i = 0; + i < c->vp->program.Base.NumInstructions && constant < max_constant; + i++) { + struct prog_instruction *inst = &c->vp->program.Base.Instructions[i]; + int arg; + + for (arg = 0; arg < 3 && constant < max_constant; arg++) { + if ((inst->SrcReg[arg].File != PROGRAM_STATE_VAR && + inst->SrcReg[arg].File != PROGRAM_CONSTANT && + inst->SrcReg[arg].File != PROGRAM_UNIFORM && + inst->SrcReg[arg].File != PROGRAM_ENV_PARAM && + inst->SrcReg[arg].File != PROGRAM_LOCAL_PARAM) || + inst->SrcReg[arg].RelAddr) + continue; + + if (c->constant_map[inst->SrcReg[arg].Index] == -1) { + c->constant_map[inst->SrcReg[arg].Index] = constant++; + } + } + } + + for (i = 0; i < constant; i++) { + c->regs[PROGRAM_STATE_VAR][i] = stride( brw_vec4_grf(reg+i/2, + (i%2) * 4), + 0, 4, 1); + } + reg += (constant + 1) / 2; + c->prog_data.curb_read_length = reg - 1; + /* XXX 0 causes a bug elsewhere... */ + c->prog_data.nr_params = MAX2(constant * 4, 4); } else { /* use a section of the GRF for constants */ @@ -214,8 +252,10 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) } } - c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0); - reg += 2; + if (c->needs_stack) { + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0); + reg += 2; + } /* Some opcodes need an internal temporary: */ @@ -762,15 +802,14 @@ get_constant(struct brw_vs_compile *c, { const struct prog_src_register *src = &inst->SrcReg[argIndex]; struct brw_compile *p = &c->func; - struct brw_reg const_reg; - struct brw_reg const2_reg; - const GLboolean relAddr = src->RelAddr; + struct brw_reg const_reg = c->current_const[argIndex].reg; assert(argIndex < 3); - if (c->current_const[argIndex].index != src->Index || relAddr) { + if (c->current_const[argIndex].index != src->Index) { struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0]; + /* Keep track of the last constant loaded in this slot, for reuse. */ c->current_const[argIndex].index = src->Index; #if 0 @@ -779,48 +818,74 @@ get_constant(struct brw_vs_compile *c, #endif /* need to fetch the constant now */ brw_dp_READ_4_vs(p, - c->current_const[argIndex].reg,/* writeback dest */ + const_reg, /* writeback dest */ 0, /* oword */ - relAddr, /* relative indexing? */ + 0, /* relative indexing? */ addrReg, /* address register */ 16 * src->Index, /* byte offset */ SURF_INDEX_VERT_CONST_BUFFER /* binding table index */ ); - - if (relAddr) { - /* second read */ - const2_reg = get_tmp(c); - - /* use upper half of address reg for second read */ - addrReg = stride(addrReg, 0, 4, 0); - addrReg.subnr = 16; - - brw_dp_READ_4_vs(p, - const2_reg, /* writeback dest */ - 1, /* oword */ - relAddr, /* relative indexing? */ - addrReg, /* address register */ - 16 * src->Index, /* byte offset */ - SURF_INDEX_VERT_CONST_BUFFER - ); - } } - const_reg = c->current_const[argIndex].reg; + /* replicate lower four floats into upper half (to get XYZWXYZW) */ + const_reg = stride(const_reg, 0, 4, 0); + const_reg.subnr = 0; - if (relAddr) { - /* merge the two Owords into the constant register */ - /* const_reg[7..4] = const2_reg[7..4] */ - brw_MOV(p, - suboffset(stride(const_reg, 0, 4, 1), 4), - suboffset(stride(const2_reg, 0, 4, 1), 4)); - release_tmp(c, const2_reg); - } - else { - /* replicate lower four floats into upper half (to get XYZWXYZW) */ - const_reg = stride(const_reg, 0, 4, 0); - const_reg.subnr = 0; - } + return const_reg; +} + +static struct brw_reg +get_reladdr_constant(struct brw_vs_compile *c, + const struct prog_instruction *inst, + GLuint argIndex) +{ + const struct prog_src_register *src = &inst->SrcReg[argIndex]; + struct brw_compile *p = &c->func; + struct brw_reg const_reg = c->current_const[argIndex].reg; + struct brw_reg const2_reg; + struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0]; + + assert(argIndex < 3); + + /* Can't reuse a reladdr constant load. */ + c->current_const[argIndex].index = -1; + + #if 0 + printf(" fetch const[a0.x+%d] for arg %d into reg %d\n", + src->Index, argIndex, c->current_const[argIndex].reg.nr); +#endif + + /* fetch the first vec4 */ + brw_dp_READ_4_vs(p, + const_reg, /* writeback dest */ + 0, /* oword */ + 1, /* relative indexing? */ + addrReg, /* address register */ + 16 * src->Index, /* byte offset */ + SURF_INDEX_VERT_CONST_BUFFER /* binding table index */ + ); + /* second vec4 */ + const2_reg = get_tmp(c); + + /* use upper half of address reg for second read */ + addrReg = stride(addrReg, 0, 4, 0); + addrReg.subnr = 16; + + brw_dp_READ_4_vs(p, + const2_reg, /* writeback dest */ + 1, /* oword */ + 1, /* relative indexing? */ + addrReg, /* address register */ + 16 * src->Index, /* byte offset */ + SURF_INDEX_VERT_CONST_BUFFER + ); + + /* merge the two Owords into the constant register */ + /* const_reg[7..4] = const2_reg[7..4] */ + brw_MOV(p, + suboffset(stride(const_reg, 0, 4, 1), 4), + suboffset(stride(const2_reg, 0, 4, 1), 4)); + release_tmp(c, const2_reg); return const_reg; } @@ -928,7 +993,13 @@ get_src_reg( struct brw_vs_compile *c, case PROGRAM_ENV_PARAM: case PROGRAM_LOCAL_PARAM: if (c->vp->use_const_buffer) { - return get_constant(c, inst, argIndex); + if (!relAddr && c->constant_map[index] != -1) { + assert(c->regs[PROGRAM_STATE_VAR][c->constant_map[index]].nr != 0); + return c->regs[PROGRAM_STATE_VAR][c->constant_map[index]]; + } else if (relAddr) + return get_reladdr_constant(c, inst, argIndex); + else + return get_constant(c, inst, argIndex); } else if (relAddr) { return deref(c, c->regs[PROGRAM_STATE_VAR][0], index); @@ -1367,7 +1438,7 @@ void brw_vs_emit(struct brw_vs_compile *c ) GLuint insn, if_depth = 0, loop_depth = 0; GLuint end_offset = 0; struct brw_instruction *end_inst, *last_inst; - struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH]; + struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH] = { 0 }; const struct brw_indirect stack_index = brw_indirect(0, 0); GLuint index; GLuint file; @@ -1380,12 +1451,14 @@ void brw_vs_emit(struct brw_vs_compile *c ) brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_access_mode(p, BRW_ALIGN_16); - - /* Message registers can't be read, so copy the output into GRF register - if they are used in source registers */ + for (insn = 0; insn < nr_insns; insn++) { GLuint i; struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn]; + + /* Message registers can't be read, so copy the output into GRF + * register if they are used in source registers + */ for (i = 0; i < 3; i++) { struct prog_src_register *src = &inst->SrcReg[i]; GLuint index = src->Index; @@ -1393,12 +1466,23 @@ void brw_vs_emit(struct brw_vs_compile *c ) if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS) c->output_regs[index].used_in_src = GL_TRUE; } + + switch (inst->Opcode) { + case OPCODE_CAL: + case OPCODE_RET: + c->needs_stack = GL_TRUE; + break; + default: + break; + } } /* Static register allocation */ brw_vs_alloc_regs(c); - brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); + + if (c->needs_stack) + brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); for (insn = 0; insn < nr_insns; insn++) { diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c index 345ffa7ee1..fd9f2fee42 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_state.c @@ -164,8 +164,7 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) bo = brw_upload_cache(&brw->cache, BRW_VS_UNIT, key, sizeof(*key), &brw->vs.prog_bo, 1, - &vs, sizeof(vs), - NULL, NULL); + &vs, sizeof(vs)); /* Emit VS program relocation */ dri_bo_emit_reloc(bo, diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c index 3bc9840a97..ead623fc0e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -35,7 +35,6 @@ #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" /* Creates a new VS constant buffer reflecting the current VS program's * constants, if needed by the VS program. @@ -156,7 +155,7 @@ brw_vs_get_binding_table(struct brw_context *brw) if (bind_bo == NULL) { GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint); - uint32_t *data = malloc(data_size); + uint32_t data[BRW_VS_MAX_SURF]; int i; for (i = 0; i < BRW_VS_MAX_SURF; i++) @@ -168,8 +167,7 @@ brw_vs_get_binding_table(struct brw_context *brw) bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->vs.surf_bo, BRW_VS_MAX_SURF, - data, data_size, - NULL, NULL); + data, data_size); /* Emit binding table relocations to surface state */ for (i = 0; i < BRW_VS_MAX_SURF; i++) { @@ -182,8 +180,6 @@ brw_vs_get_binding_table(struct brw_context *brw) I915_GEM_DOMAIN_INSTRUCTION, 0); } } - - free(data); } return bind_bo; diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 72749b3859..681319dedf 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -44,7 +44,6 @@ #include "brw_state.h" #include "brw_draw.h" #include "brw_state.h" -#include "brw_fallback.h" #include "brw_vs.h" #include "brw_wm.h" @@ -140,6 +139,12 @@ static void brw_finish_batch(struct intel_context *intel) { struct brw_context *brw = brw_context(&intel->ctx); brw_emit_query_end(brw); + + if (brw->curbe.curbe_bo) { + intel_bo_unmap_gtt_preferred(intel, brw->curbe.curbe_bo); + drm_intel_bo_unreference(brw->curbe.curbe_bo); + brw->curbe.curbe_bo = NULL; + } } @@ -150,8 +155,6 @@ static void brw_new_batch( struct intel_context *intel ) { struct brw_context *brw = brw_context(&intel->ctx); - brw->curbe.need_new_bo = GL_TRUE; - /* Mark all context state as needing to be re-emitted. * This is probably not as severe as on 915, since almost all of our state * is just in referenced buffers. @@ -172,12 +175,6 @@ static void brw_new_batch( struct intel_context *intel ) } } - -static void brw_note_fence( struct intel_context *intel, GLuint fence ) -{ - brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE; -} - static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) { /* nothing */ @@ -193,7 +190,6 @@ void brwInitVtbl( struct brw_context *brw ) brw->intel.vtbl.update_texture_state = 0; brw->intel.vtbl.invalidate_state = brw_invalidate_state; - brw->intel.vtbl.note_fence = brw_note_fence; brw->intel.vtbl.new_batch = brw_new_batch; brw->intel.vtbl.finish_batch = brw_finish_batch; brw->intel.vtbl.destroy = brw_destroy_context; diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 6895f64410..9191c81755 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -30,7 +30,6 @@ */ #include "brw_context.h" -#include "brw_util.h" #include "brw_wm.h" #include "brw_state.h" @@ -199,12 +198,13 @@ static void do_wm_prog( struct brw_context *brw, program = brw_get_program(&c->func, &program_size); dri_bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_upload_cache( &brw->cache, BRW_WM_PROG, - &c->key, sizeof(c->key), - NULL, 0, - program, program_size, - &c->prog_data, - &brw->wm.prog_data ); + brw->wm.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_WM_PROG, + &c->key, sizeof(c->key), + NULL, 0, + program, program_size, + &c->prog_data, + sizeof(c->prog_data), + &brw->wm.prog_data); } @@ -336,11 +336,7 @@ static void brw_wm_populate_key( struct brw_context *brw, * drawable height in order to invert the Y axis. */ if (fp->program.Base.InputsRead & FRAG_BIT_WPOS) { - if (brw->intel.driDrawable != NULL) { - key->origin_x = brw->intel.driDrawable->x; - key->origin_y = brw->intel.driDrawable->y; - key->drawable_height = brw->intel.driDrawable->h; - } + key->drawable_height = ctx->DrawBuffer->Height; } key->nr_color_regions = brw->state.nr_color_regions; diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index b9b987ea70..88d84ee82f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -76,7 +76,6 @@ struct brw_wm_prog_key { GLushort tex_swizzles[BRW_MAX_TEX_UNIT]; - GLushort origin_x, origin_y; GLushort drawable_height; GLbitfield64 vp_outputs_written; GLuint program_string_id:32; diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index f316e0cda4..fa0898c586 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -138,19 +138,43 @@ void emit_wpos_xy(struct brw_wm_compile *c, * X and Y channels. */ if (mask & WRITEMASK_X) { - /* X' = X - origin */ - brw_ADD(p, - dst[0], - retype(arg0[0], BRW_REGISTER_TYPE_W), - brw_imm_d(0 - c->key.origin_x)); + if (c->fp->program.PixelCenterInteger) { + /* X' = X */ + brw_MOV(p, + dst[0], + retype(arg0[0], BRW_REGISTER_TYPE_W)); + } else { + /* X' = X + 0.5 */ + brw_ADD(p, + dst[0], + retype(arg0[0], BRW_REGISTER_TYPE_W), + brw_imm_f(0.5)); + } } if (mask & WRITEMASK_Y) { - /* Y' = height - (Y - origin_y) = height + origin_y - Y */ - brw_ADD(p, - dst[1], - negate(retype(arg0[1], BRW_REGISTER_TYPE_W)), - brw_imm_d(c->key.origin_y + c->key.drawable_height - 1)); + if (c->fp->program.OriginUpperLeft) { + if (c->fp->program.PixelCenterInteger) { + /* Y' = Y */ + brw_MOV(p, + dst[1], + retype(arg0[1], BRW_REGISTER_TYPE_W)); + } else { + /* Y' = Y + 0.5 */ + brw_ADD(p, + dst[1], + retype(arg0[1], BRW_REGISTER_TYPE_W), + brw_imm_f(0.5)); + } + } else { + float center_offset = c->fp->program.PixelCenterInteger ? 0.0 : 0.5; + + /* Y' = (height - 1) - Y + center */ + brw_ADD(p, + dst[1], + negate(retype(arg0[1], BRW_REGISTER_TYPE_W)), + brw_imm_f(c->key.drawable_height - 1 + center_offset)); + } } } diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index ad267a4e6a..87387b1e2d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -326,8 +326,7 @@ static void upload_wm_samplers( struct brw_context *brw ) brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER, &key, sizeof(key), brw->wm.sdc_bo, key.sampler_count, - &sampler, sizeof(sampler), - NULL, NULL); + &sampler, sizeof(sampler)); /* Emit SDC relocations */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index d3373ea79e..a7f80db554 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -210,8 +210,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, bo = brw_upload_cache(&brw->cache, BRW_WM_UNIT, key, sizeof(*key), reloc_bufs, 3, - &wm, sizeof(wm), - NULL, NULL); + &wm, sizeof(wm)); /* Emit WM program relocation */ dri_bo_emit_reloc(bo, diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f26cfabb7d..1db438ae7b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -256,8 +256,7 @@ brw_create_texture_surface( struct brw_context *brw, bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, key, sizeof(*key), &key->bo, key->bo ? 1 : 0, - &surf, sizeof(surf), - NULL, NULL); + &surf, sizeof(surf)); if (key->bo) { /* Emit relocation to surface contents */ @@ -351,8 +350,7 @@ brw_create_constant_surface( struct brw_context *brw, bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, key, sizeof(*key), &key->bo, key->bo ? 1 : 0, - &surf, sizeof(surf), - NULL, NULL); + &surf, sizeof(surf)); if (key->bo) { /* Emit relocation to surface contents. Section 5.1.1 of the gen4 @@ -579,7 +577,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, key.draw_y = 0; } /* _NEW_COLOR */ - memcpy(key.color_mask, ctx->Color.ColorMask[0], + memcpy(key.color_mask, ctx->Color.ColorMask[unit], sizeof(key.color_mask)); /* As mentioned above, disable writes to the alpha component when the @@ -589,7 +587,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, key.color_mask[3] = GL_FALSE; key.color_blend = (!ctx->Color._LogicOpEnabled && - ctx->Color.BlendEnabled); + (ctx->Color.BlendEnabled & (1 << unit))); dri_bo_unreference(brw->wm.surf_bo[unit]); brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, @@ -653,8 +651,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, BRW_SS_SURFACE, &key, sizeof(key), ®ion_bo, 1, - &surf, sizeof(surf), - NULL, NULL); + &surf, sizeof(surf)); if (region_bo != NULL) { /* We might sample from it, and we might render to it, so flag * them both. We might be able to figure out from other state @@ -701,8 +698,7 @@ brw_wm_get_binding_table(struct brw_context *brw) bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->wm.surf_bo, brw->wm.nr_surfaces, - data, data_size, - NULL, NULL); + data, data_size); /* Emit binding table relocations to surface state */ for (i = 0; i < BRW_WM_MAX_SURF; i++) { diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 3a4b21a844..ae0f8a16f9 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -32,44 +32,6 @@ #include "intel_bufmgr.h" #include "intel_buffers.h" -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - void intel_batchbuffer_reset(struct intel_batchbuffer *batch) { @@ -167,7 +129,8 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; - if (intel->first_post_swapbuffers_batch == NULL) { + if (!intel->using_dri2_swapbuffers && + intel->first_post_swapbuffers_batch == NULL) { intel->first_post_swapbuffers_batch = intel->batch->buf; drm_intel_bo_reference(intel->first_post_swapbuffers_batch); } diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 55bee0084c..1fd07e8b82 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -38,7 +38,6 @@ #include "intel_reg.h" #include "intel_regions.h" #include "intel_batchbuffer.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_BLIT @@ -103,7 +102,7 @@ intelEmitCopyBlit(struct intel_context *intel, return GL_FALSE; } - /* do space/cliprects check before going any further */ + /* do space check before going any further */ do { aper_array[0] = intel->batch->buf; aper_array[1] = dst_buffer; @@ -213,10 +212,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) struct intel_context *intel = intel_context(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint clear_depth; - GLbitfield skipBuffers = 0; - unsigned int num_cliprects; - struct drm_clip_rect *cliprects; - int x_off, y_off; + GLboolean all; + GLint cx, cy, cw, ch; BATCH_LOCALS; /* @@ -230,183 +227,144 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; } - /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in - * the loop below. - */ - if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { - skipBuffers = BUFFER_BIT_STENCIL; - } - - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects) { - GLint cx, cy, cw, ch; - drm_clip_rect_t clear; - int i; - - /* Get clear bounds after locking */ - cx = fb->_Xmin; + cx = fb->_Xmin; + if (fb->Name == 0) + cy = ctx->DrawBuffer->Height - fb->_Ymax; + else cy = fb->_Ymin; - cw = fb->_Xmax - cx; - ch = fb->_Ymax - cy; + cw = fb->_Xmax - fb->_Xmin; + ch = fb->_Ymax - fb->_Ymin; + + if (cw == 0 || ch == 0) + return; + + GLuint buf; + all = (cw == fb->Width && ch == fb->Height); + + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { + const GLbitfield bufBit = 1 << buf; + struct intel_renderbuffer *irb; + drm_intel_bo *write_buffer; + int x1, y1, x2, y2; + uint32_t clear_val; + uint32_t BR13, CMD; + int pitch, cpp; + drm_intel_bo *aper_array[2]; + + if (!(mask & bufBit)) + continue; + + /* OK, clear this renderbuffer */ + irb = intel_get_renderbuffer(fb, buf); + write_buffer = intel_region_buffer(intel, irb->region, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + x1 = cx + irb->region->draw_x; + y1 = cy + irb->region->draw_y; + x2 = cx + cw + irb->region->draw_x; + y2 = cy + ch + irb->region->draw_y; + + pitch = irb->region->pitch; + cpp = irb->region->cpp; + + DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", + __FUNCTION__, + irb->region->buffer, (pitch * cpp), + x1, y1, x2 - x1, y2 - y1); + + BR13 = 0xf0 << 16; + CMD = XY_COLOR_BLT_CMD; + + /* Setup the blit command */ + if (cpp == 4) { + BR13 |= BR13_8888; + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + if (mask & BUFFER_BIT_DEPTH) + CMD |= XY_BLT_WRITE_RGB; + if (mask & BUFFER_BIT_STENCIL) + CMD |= XY_BLT_WRITE_ALPHA; + } else { + /* clearing RGBA */ + CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + } + } else { + ASSERT(cpp == 2); + BR13 |= BR13_565; + } - if (fb->Name == 0) { - /* clearing a window */ + assert(irb->region->tiling != I915_TILING_Y); - /* flip top to bottom */ - clear.x1 = cx + x_off; - clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; +#ifndef I915 + if (irb->region->tiling != I915_TILING_NONE) { + CMD |= XY_DST_TILED; + pitch /= 4; } - else { - /* clearing FBO */ - assert(num_cliprects == 1); - assert(cliprects == &intel->fboRect); - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; - /* no change to mask */ +#endif + BR13 |= (pitch * cpp); + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clear_val = clear_depth; + } else { + uint8_t clear[4]; + GLclampf *color = ctx->Color.ClearColor; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + switch (irb->Base.Format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + clear_val = PACK_COLOR_8888(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_RGB565: + clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB4444: + clear_val = PACK_COLOR_4444(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB1555: + clear_val = PACK_COLOR_1555(clear[3], clear[0], + clear[1], clear[2]); + break; + default: + _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", + irb->Base.Format); + clear_val = 0; + } } - for (i = 0; i < num_cliprects; i++) { - const drm_clip_rect_t *box = &cliprects[i]; - drm_clip_rect_t b; - GLuint buf; - GLuint clearMask = mask; /* use copy, since we modify it below */ - GLboolean all = (cw == fb->Width && ch == fb->Height); - - if (!all) { - intel_intersect_cliprects(&b, &clear, box); - } - else { - b = *box; - } - - if (b.x1 >= b.x2 || b.y1 >= b.y2) - continue; - - if (0) - _mesa_printf("clear %d,%d..%d,%d, mask %x\n", - b.x1, b.y1, b.x2, b.y2, mask); - - /* Loop over all renderbuffers */ - for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { - const GLbitfield bufBit = 1 << buf; - if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { - /* OK, clear this renderbuffer */ - struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, buf); - dri_bo *write_buffer = - intel_region_buffer(intel, irb->region, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - int x1 = b.x1 + irb->region->draw_x; - int y1 = b.y1 + irb->region->draw_y; - int x2 = b.x2 + irb->region->draw_x; - int y2 = b.y2 + irb->region->draw_y; - - GLuint clearVal; - GLint pitch, cpp; - GLuint BR13, CMD; - - pitch = irb->region->pitch; - cpp = irb->region->cpp; - - DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", - __FUNCTION__, - irb->region->buffer, (pitch * cpp), - x1, y1, x2 - x1, y2 - y1); - - BR13 = 0xf0 << 16; - CMD = XY_COLOR_BLT_CMD; - - /* Setup the blit command */ - if (cpp == 4) { - BR13 |= BR13_8888; - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - if (clearMask & BUFFER_BIT_DEPTH) - CMD |= XY_BLT_WRITE_RGB; - if (clearMask & BUFFER_BIT_STENCIL) - CMD |= XY_BLT_WRITE_ALPHA; - } - else { - /* clearing RGBA */ - CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - } - } - else { - ASSERT(cpp == 2); - BR13 |= BR13_565; - } - - assert(irb->region->tiling != I915_TILING_Y); + assert(x1 < x2); + assert(y1 < y2); -#ifndef I915 - if (irb->region->tiling != I915_TILING_NONE) { - CMD |= XY_DST_TILED; - pitch /= 4; - } -#endif - BR13 |= (pitch * cpp); - - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - clearVal = clear_depth; - } - else { - uint8_t clear[4]; - GLclampf *color = ctx->Color.ClearColor; - - CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); - - switch (irb->Base.Format) { - case MESA_FORMAT_ARGB8888: - case MESA_FORMAT_XRGB8888: - clearVal = PACK_COLOR_8888(clear[3], clear[0], - clear[1], clear[2]); - break; - case MESA_FORMAT_RGB565: - clearVal = PACK_COLOR_565(clear[0], clear[1], clear[2]); - break; - case MESA_FORMAT_ARGB4444: - clearVal = PACK_COLOR_4444(clear[3], clear[0], - clear[1], clear[2]); - break; - case MESA_FORMAT_ARGB1555: - clearVal = PACK_COLOR_1555(clear[3], clear[0], - clear[1], clear[2]); - break; - default: - _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", - irb->Base.Format); - clearVal = 0; - } - } - - /* - _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", - buf, irb->Base.Name); - */ - - assert(x1 < x2); - assert(y1 < y2); - - BEGIN_BATCH(6); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((y1 << 16) | x1); - OUT_BATCH((y2 << 16) | x2); - OUT_RELOC(write_buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - OUT_BATCH(clearVal); - ADVANCE_BATCH(); - clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ - } - } + /* do space check before going any further */ + aper_array[0] = intel->batch->buf; + aper_array[1] = write_buffer; + + if (drm_intel_bufmgr_check_aperture_space(aper_array, + ARRAY_SIZE(aper_array)) != 0) { + intel_batchbuffer_flush(intel->batch); } + + BEGIN_BATCH(6); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y1 << 16) | x1); + OUT_BATCH((y2 << 16) | x2); + OUT_RELOC(write_buffer, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + 0); + OUT_BATCH(clear_val); + ADVANCE_BATCH(); + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) + mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + else + mask &= ~bufBit; /* turn off bit, for faster loop exit */ } } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 7c4b79f743..2f03e45005 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -28,45 +28,7 @@ #include "intel_context.h" #include "intel_buffers.h" #include "intel_fbo.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" #include "main/framebuffer.h" -#include "drirenderbuffer.h" - - -/** - * XXX move this into a new dri/common/cliprects.c file. - */ -GLboolean -intel_intersect_cliprects(drm_clip_rect_t * dst, - const drm_clip_rect_t * a, - const drm_clip_rect_t * b) -{ - GLint bx = b->x1; - GLint by = b->y1; - GLint bw = b->x2 - bx; - GLint bh = b->y2 - by; - - if (bx < a->x1) - bw -= a->x1 - bx, bx = a->x1; - if (by < a->y1) - bh -= a->y1 - by, by = a->y1; - if (bx + bw > a->x2) - bw = a->x2 - bx; - if (by + bh > a->y2) - bh = a->y2 - by; - if (bw <= 0) - return GL_FALSE; - if (bh <= 0) - return GL_FALSE; - - dst->x1 = bx; - dst->y1 = by; - dst->x2 = bx + bw; - dst->y2 = by + bh; - - return GL_TRUE; -} /** * Return pointer to current color drawing region, or NULL. @@ -96,24 +58,6 @@ intel_readbuf_region(struct intel_context *intel) return NULL; } -void -intel_get_cliprects(struct intel_context *intel, - struct drm_clip_rect **cliprects, - unsigned int *num_cliprects, - int *x_off, int *y_off) -{ - intel->fboRect.x1 = 0; - intel->fboRect.y1 = 0; - intel->fboRect.x2 = intel->ctx.DrawBuffer->Width; - intel->fboRect.y2 = intel->ctx.DrawBuffer->Height; - - *cliprects = &intel->fboRect; - *num_cliprects = 1; - *x_off = 0; - *y_off = 0; -} - - /** * Check if we're about to draw into the front color buffer. * If so, set the intel->front_buffer_dirty field to true. diff --git a/src/mesa/drivers/dri/intel/intel_buffers.h b/src/mesa/drivers/dri/intel/intel_buffers.h index d7800f2ca2..abb86aade6 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.h +++ b/src/mesa/drivers/dri/intel/intel_buffers.h @@ -35,12 +35,6 @@ struct intel_context; struct intel_framebuffer; - -extern GLboolean -intel_intersect_cliprects(drm_clip_rect_t * dest, - const drm_clip_rect_t * a, - const drm_clip_rect_t * b); - extern struct intel_region *intel_readbuf_region(struct intel_context *intel); extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 956f2339ff..ca78681538 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -33,12 +33,9 @@ #include "intel_context.h" #include "intel_blit.h" -#include "intel_chipset.h" #include "intel_clear.h" #include "intel_fbo.h" -#include "intel_pixel.h" #include "intel_regions.h" -#include "intel_batchbuffer.h" #define FILE_DEBUG_FLAG DEBUG_BLIT diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 13a28f0419..0adee6131e 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/context.h" -#include "main/arrayobj.h" #include "main/extensions.h" #include "main/framebuffer.h" #include "main/imports.h" @@ -52,13 +51,11 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" #include "intel_fbo.h" -#include "intel_decode.h" #include "intel_bufmgr.h" #include "intel_screen.h" #include "drirenderbuffer.h" #include "utils.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ #ifndef INTEL_DEBUG @@ -70,8 +67,6 @@ int INTEL_DEBUG = (0); #define DRIVER_DATE_GEM "GEM " DRIVER_DATE -static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); - static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -378,6 +373,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) } } + drawable->validBuffers = GL_TRUE; driUpdateFramebufferSize(&intel->ctx, drawable); } @@ -461,7 +457,7 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) intel->vtbl.invalidate_state( intel, new_state ); } -static void +void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) { struct intel_context *intel = intel_context(ctx); @@ -523,7 +519,8 @@ intel_glFlush(GLcontext *ctx) * and getting our hands on that doesn't seem worth it, so we just us the * first batch we emitted after the last swap. */ - if (intel->first_post_swapbuffers_batch != NULL) { + if (!intel->using_dri2_swapbuffers && + intel->first_post_swapbuffers_batch != NULL) { drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); intel->first_post_swapbuffers_batch = NULL; diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index c7b7235836..36abef470a 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -107,7 +107,6 @@ struct intel_context void (*finish_batch) (struct intel_context * intel); void (*new_batch) (struct intel_context * intel); void (*emit_invarient_state) (struct intel_context * intel); - void (*note_fence) (struct intel_context *intel, GLuint fence); void (*update_texture_state) (struct intel_context * intel); void (*render_start) (struct intel_context * intel); @@ -125,40 +124,6 @@ struct intel_context void (*invalidate_state) (struct intel_context *intel, GLuint new_state); - - /* Metaops: - */ - void (*install_meta_state) (struct intel_context * intel); - void (*leave_meta_state) (struct intel_context * intel); - - void (*meta_draw_region) (struct intel_context * intel, - struct intel_region * draw_region, - struct intel_region * depth_region); - - void (*meta_color_mask) (struct intel_context * intel, GLboolean); - - void (*meta_stencil_replace) (struct intel_context * intel, - GLuint mask, GLuint clear); - - void (*meta_depth_replace) (struct intel_context * intel); - - void (*meta_texture_blend_replace) (struct intel_context * intel); - - void (*meta_no_stencil_write) (struct intel_context * intel); - void (*meta_no_depth_write) (struct intel_context * intel); - void (*meta_no_texture) (struct intel_context * intel); - - void (*meta_import_pixel_state) (struct intel_context * intel); - void (*meta_frame_buffer_texture) (struct intel_context *intel, - GLint xoff, GLint yoff); - - GLboolean(*meta_tex_rect_source) (struct intel_context * intel, - dri_bo * buffer, - GLuint offset, - GLuint pitch, - GLuint height, - GLenum format, GLenum type); - void (*assert_not_dirty) (struct intel_context *intel); void (*debug_batch)(struct intel_context *intel); @@ -187,6 +152,7 @@ struct intel_context struct intel_batchbuffer *batch; drm_intel_bo *first_post_swapbuffers_batch; GLboolean no_batch_wrap; + GLboolean using_dri2_swapbuffers; struct { @@ -273,10 +239,6 @@ struct intel_context GLboolean use_texture_tiling; GLboolean use_early_z; - drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ - - drm_clip_rect_t draw_rect; - drm_clip_rect_t scissor_rect; int driFd; @@ -412,6 +374,7 @@ extern GLboolean intelInitContext(struct intel_context *intel, extern void intelFinish(GLcontext * ctx); extern void intelFlush(GLcontext * ctx); +extern void intel_flush(GLcontext * ctx, GLboolean needs_mi_flush); extern void intelInitDriverFunctions(struct dd_function_table *functions); diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c index 5ac5ce10af..84c8d013e3 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.c +++ b/src/mesa/drivers/dri/intel/intel_extensions.c @@ -48,6 +48,7 @@ #define need_GL_EXT_blend_func_separate #define need_GL_EXT_blend_minmax #define need_GL_EXT_cull_vertex +#define need_GL_EXT_draw_buffers2 #define need_GL_EXT_fog_coord #define need_GL_EXT_framebuffer_object #define need_GL_EXT_framebuffer_blit @@ -154,12 +155,14 @@ static const struct dri_extension brw_extensions[] = { { "GL_ARB_fragment_program_shadow", NULL }, { "GL_ARB_fragment_shader", NULL }, { "GL_ARB_framebuffer_object", GL_ARB_framebuffer_object_functions}, + { "GL_ARB_half_float_vertex", NULL }, { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, { "GL_ARB_point_sprite", NULL }, { "GL_ARB_seamless_cube_map", NULL }, { "GL_ARB_shadow", NULL }, { "GL_MESA_texture_signed_rgba", NULL }, { "GL_ARB_texture_non_power_of_two", NULL }, + { "GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions }, { "GL_EXT_shadow_funcs", NULL }, { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions }, { "GL_EXT_texture_sRGB", NULL }, diff --git a/src/mesa/drivers/dri/intel/intel_extensions.h b/src/mesa/drivers/dri/intel/intel_extensions.h index 1d1c97a4a9..e78e07356e 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.h +++ b/src/mesa/drivers/dri/intel/intel_extensions.h @@ -32,5 +32,8 @@ extern void intelInitExtensions(GLcontext *ctx); +extern void +intelFlushDrawable(__DRIdrawable *drawable); + #endif diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 82e4150c6a..cb5a341050 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -29,7 +29,6 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_tex_layout.h" -#include "intel_chipset.h" #ifndef I915 #include "brw_state.h" #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index 5142f3dcd9..cb088e4032 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -29,14 +29,7 @@ #include "main/state.h" #include "main/bufferobj.h" #include "main/context.h" -#include "main/enable.h" -#include "main/matrix.h" -#include "main/texstate.h" -#include "main/varray.h" -#include "main/viewport.h" #include "swrast/swrast.h" -#include "shader/arbprogram.h" -#include "shader/program.h" #include "intel_context.h" #include "intel_pixel.h" diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 85e5ad2cdd..1e517650b7 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -37,7 +37,6 @@ #include "main/polygon.h" #include "main/state.h" #include "main/teximage.h" -#include "main/texenv.h" #include "main/texobj.h" #include "main/texstate.h" #include "main/texparam.h" @@ -46,7 +45,6 @@ #include "main/enable.h" #include "main/viewport.h" #include "shader/arbprogram.h" -#include "glapi/dispatch.h" #include "swrast/swrast.h" #include "intel_screen.h" @@ -54,7 +52,6 @@ #include "intel_batchbuffer.h" #include "intel_blit.h" #include "intel_regions.h" -#include "intel_buffer_objects.h" #include "intel_buffers.h" #include "intel_pixel.h" #include "intel_reg.h" @@ -106,7 +103,7 @@ static void set_bit( GLubyte *dest, GLuint bit ) } /* Extract a rectangle's worth of data from the bitmap. Called - * per-cliprect. + * per chunk of HW-sized bitmap. */ static GLuint get_bitmap_rect(GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, @@ -191,11 +188,12 @@ do_blit_bitmap( GLcontext *ctx, GLfloat tmpColor[4]; GLubyte ubcolor[4]; GLuint color; - unsigned int num_cliprects; - drm_clip_rect_t *cliprects; - int x_off, y_off; GLsizei bitmap_width = width; GLsizei bitmap_height = height; + GLint px, py; + GLuint stipple[32]; + GLint orig_dstx = dstx; + GLint orig_dsty = dsty; /* Update draw buffer bounds */ _mesa_update_state(ctx); @@ -236,90 +234,60 @@ do_blit_bitmap( GLcontext *ctx, if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F)) return GL_FALSE; - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects != 0) { - GLuint i; - GLint orig_dstx = dstx; - GLint orig_dsty = dsty; - - /* Clip to buffer bounds and scissor. */ - if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, - fb->_Xmax, fb->_Ymax, - &dstx, &dsty, &width, &height)) - goto out; - - dstx = x_off + dstx; - dsty = y_off + y_flip(fb, dsty, height); - - for (i = 0; i < num_cliprects; i++) { - int box_x, box_y, box_w, box_h; - GLint px, py; - GLuint stipple[32]; - - box_x = dstx; - box_y = dsty; - box_w = width; - box_h = height; - - /* Clip to drawable cliprect */ - if (!_mesa_clip_to_region(cliprects[i].x1, - cliprects[i].y1, - cliprects[i].x2, - cliprects[i].y2, - &box_x, &box_y, &box_w, &box_h)) - continue; + /* Clip to buffer bounds and scissor. */ + if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, + fb->_Xmax, fb->_Ymax, + &dstx, &dsty, &width, &height)) + goto out; + + dsty = y_flip(fb, dsty, height); #define DY 32 #define DX 32 - /* Then, finally, chop it all into chunks that can be - * digested by hardware: + /* Chop it all into chunks that can be digested by hardware: */ + for (py = 0; py < height; py += DY) { + for (px = 0; px < width; px += DX) { + int h = MIN2(DY, height - py); + int w = MIN2(DX, width - px); + GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; + GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY; + + assert(sz <= sizeof(stipple)); + memset(stipple, 0, sz); + + /* May need to adjust this when padding has been introduced in + * sz above: + * + * Have to translate destination coordinates back into source + * coordinates. */ - for (py = 0; py < box_h; py += DY) { - for (px = 0; px < box_w; px += DX) { - int h = MIN2(DY, box_h - py); - int w = MIN2(DX, box_w - px); - GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; - GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY; - - assert(sz <= sizeof(stipple)); - memset(stipple, 0, sz); - - /* May need to adjust this when padding has been introduced in - * sz above: - * - * Have to translate destination coordinates back into source - * coordinates. - */ - if (get_bitmap_rect(bitmap_width, bitmap_height, unpack, - bitmap, - -orig_dstx + (box_x + px - x_off), - -orig_dsty + y_flip(fb, - box_y + py - y_off, h), - w, h, - (GLubyte *)stipple, - 8, - fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) - continue; - - if (!intelEmitImmediateColorExpandBlit(intel, - dst->cpp, - (GLubyte *)stipple, - sz, - color, - dst->pitch, - dst->buffer, - 0, - dst->tiling, - box_x + px, - box_y + py, - w, h, - logic_op)) { - return GL_FALSE; - } - } - } + if (get_bitmap_rect(bitmap_width, bitmap_height, unpack, + bitmap, + -orig_dstx + (dstx + px), + -orig_dsty + y_flip(fb, dsty + py, h), + w, h, + (GLubyte *)stipple, + 8, + fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) + continue; + + if (!intelEmitImmediateColorExpandBlit(intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color, + dst->pitch, + dst->buffer, + 0, + dst->tiling, + dstx + px, + dsty + py, + w, h, + logic_op)) { + return GL_FALSE; + } } } out: diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index e002516cdd..87c293d8b0 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -112,9 +112,10 @@ do_blit_copypixels(GLcontext * ctx, struct intel_region *src = copypix_src_region(intel, type); struct gl_framebuffer *fb = ctx->DrawBuffer; struct gl_framebuffer *read_fb = ctx->ReadBuffer; - unsigned int num_cliprects; - drm_clip_rect_t *cliprects; - int x_off, y_off; + GLint orig_dstx; + GLint orig_dsty; + GLint orig_srcx; + GLint orig_srcy; if (type == GL_DEPTH || type == GL_STENCIL) { if (INTEL_DEBUG & DEBUG_FALLBACKS) @@ -135,94 +136,56 @@ do_blit_copypixels(GLcontext * ctx, if (!src || !dst) return GL_FALSE; - - intelFlush(&intel->ctx); - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects != 0) { - GLint delta_x; - GLint delta_y; - GLint orig_dstx; - GLint orig_dsty; - GLint orig_srcx; - GLint orig_srcy; - GLuint i; - - /* XXX: We fail to handle different inversion between read and draw framebuffer. */ - - /* Clip to destination buffer. */ - orig_dstx = dstx; - orig_dsty = dsty; - if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, - fb->_Xmax, fb->_Ymax, - &dstx, &dsty, &width, &height)) - goto out; - /* Adjust src coords for our post-clipped destination origin */ - srcx += dstx - orig_dstx; - srcy += dsty - orig_dsty; - - /* Clip to source buffer. */ - orig_srcx = srcx; - orig_srcy = srcy; - if (!_mesa_clip_to_region(0, 0, - read_fb->Width, read_fb->Height, - &srcx, &srcy, &width, &height)) - goto out; - /* Adjust dst coords for our post-clipped source origin */ - dstx += srcx - orig_srcx; - dsty += srcy - orig_srcy; - - /* Convert from GL to hardware coordinates: - */ - if (fb->Name == 0) { - /* copypixels to a system framebuffer */ - dstx = x_off + dstx; - dsty = y_off + (fb->Height - dsty - height); - } else { - /* copypixels to a user framebuffer object */ - dstx = x_off + dstx; - dsty = y_off + dsty; - } - - /* Flip source Y if it's a system framebuffer. */ - if (read_fb->Name == 0) { - srcx = intel->driReadDrawable->x + srcx; - srcy = intel->driReadDrawable->y + (fb->Height - srcy - height); - } - - delta_x = srcx - dstx; - delta_y = srcy - dsty; - /* Could do slightly more clipping: Eg, take the intersection of - * the destination cliprects and the read drawable cliprects - * - * This code will not overwrite other windows, but will - * introduce garbage when copying from obscured window regions. - */ - for (i = 0; i < num_cliprects; i++) { - GLint clip_x = dstx; - GLint clip_y = dsty; - GLint clip_w = width; - GLint clip_h = height; - - if (!_mesa_clip_to_region(cliprects[i].x1, cliprects[i].y1, - cliprects[i].x2, cliprects[i].y2, - &clip_x, &clip_y, &clip_w, &clip_h)) - continue; - - if (!intel_region_copy(intel, - dst, 0, clip_x, clip_y, - src, 0, clip_x + delta_x, clip_y + delta_y, - clip_w, clip_h, - ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY)) { - DBG("%s: blit failure\n", __FUNCTION__); - return GL_FALSE; - } - } + /* XXX: We fail to handle different inversion between read and draw framebuffer. */ + + /* Clip to destination buffer. */ + orig_dstx = dstx; + orig_dsty = dsty; + if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, + fb->_Xmax, fb->_Ymax, + &dstx, &dsty, &width, &height)) + goto out; + /* Adjust src coords for our post-clipped destination origin */ + srcx += dstx - orig_dstx; + srcy += dsty - orig_dsty; + + /* Clip to source buffer. */ + orig_srcx = srcx; + orig_srcy = srcy; + if (!_mesa_clip_to_region(0, 0, + read_fb->Width, read_fb->Height, + &srcx, &srcy, &width, &height)) + goto out; + /* Adjust dst coords for our post-clipped source origin */ + dstx += srcx - orig_srcx; + dsty += srcy - orig_srcy; + + /* Convert from GL to hardware coordinates: */ + if (fb->Name == 0) { + /* copypixels to a system framebuffer */ + dsty = fb->Height - dsty - height; + } else { + /* copypixels to a user framebuffer object */ + dsty = dsty; } -out: + /* Flip source Y if it's a system framebuffer. */ + if (read_fb->Name == 0) + srcy = fb->Height - srcy - height; + + if (!intel_region_copy(intel, + dst, 0, dstx, dsty, + src, 0, srcx, srcy, + width, height, + ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY)) { + DBG("%s: blit failure\n", __FUNCTION__); + return GL_FALSE; + } + +out: intel_check_front_buffer_rendering(intel); DBG("%s: success\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index b870e9315e..10177228bd 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -46,10 +46,6 @@ #include "drivers/common/meta.h" #include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_regions.h" #include "intel_pixel.h" #include "intel_fbo.h" diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c index 9c0fdc6067..a98e8e16c2 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_read.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -36,7 +36,6 @@ #include "intel_screen.h" #include "intel_context.h" -#include "intel_batchbuffer.h" #include "intel_blit.h" #include "intel_buffers.h" #include "intel_regions.h" @@ -65,99 +64,6 @@ * any case. */ - -static GLboolean -do_texture_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - struct intel_region *dest_region) -{ -#if 0 - struct intel_context *intel = intel_context(ctx); - intelScreenPrivate *screen = intel->intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawable *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (ctx->_ImageTransferState || - pack->SwapBytes || pack->LsbFirst || !pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); - - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: couldn't set dest %s/%s\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(format)); - return GL_FALSE; - } - - if (intel->driDrawable->numClipRects) { - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - SET_STATE(i830, state); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); - - - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); - - - /* Set the 3d engine to draw into the destination region: - */ - - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ - - - /* Draw a single quad, no cliprects: - */ - intel->vtbl.meta_disable_cliprects(intel); - - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, x, x + width, y, y + height); - - intel->vtbl.leave_meta_state(intel); - } - - intel_region_wait_fence(ctx, dest_region); /* required by GL */ - return GL_TRUE; -#endif - - return GL_FALSE; -} - - - - static GLboolean do_blit_readpixels(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height, @@ -169,6 +75,9 @@ do_blit_readpixels(GLcontext * ctx, struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); GLuint dst_offset; GLuint rowLength; + drm_intel_bo *dst_buffer; + GLboolean all; + GLint dst_x, dst_y; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -209,56 +118,42 @@ do_blit_readpixels(GLcontext * ctx, return GL_FALSE; } else { - rowLength = -rowLength; + if (ctx->ReadBuffer->Name == 0) + rowLength = -rowLength; } dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height, format, type, 0, 0, 0); + if (!_mesa_clip_copytexsubimage(ctx, + &dst_x, &dst_y, + &x, &y, + &width, &height)) { + return GL_TRUE; + } - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects are correct. - */ - intelFlush(&intel->ctx); - - if (intel->driReadDrawable->numClipRects) { - GLboolean all = (width * height * src->cpp == dst->Base.Size && - x == 0 && dst_offset == 0); - - dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - __DRIdrawable *dPriv = intel->driReadDrawable; - int nbox = dPriv->numClipRects; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t src_rect; - int i; - - src_rect.x1 = dPriv->x + x; - src_rect.y1 = dPriv->y + dPriv->h - (y + height); - src_rect.x2 = src_rect.x1 + width; - src_rect.y2 = src_rect.y1 + height; + all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + dst_x = 0; + dst_y = 0; + dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) - continue; + if (ctx->ReadBuffer->Name == 0) + y = ctx->ReadBuffer->Height - (y + height); - if (!intelEmitCopyBlit(intel, - src->cpp, - src->pitch, src->buffer, 0, src->tiling, - rowLength, dst_buffer, dst_offset, GL_FALSE, - rect.x1, - rect.y1, - rect.x1 - src_rect.x1, - rect.y2 - src_rect.y2, - rect.x2 - rect.x1, rect.y2 - rect.y1, - GL_COPY)) { - return GL_FALSE; - } - } + if (!intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, src->tiling, + rowLength, dst_buffer, dst_offset, GL_FALSE, + x, y, + dst_x, dst_y, + width, height, + GL_COPY)) { + return GL_FALSE; } if (INTEL_DEBUG & DEBUG_PIXEL) @@ -282,15 +177,6 @@ intelReadPixels(GLcontext * ctx, (ctx, x, y, width, height, format, type, pack, pixels)) return; -#ifdef I915 - if (do_texture_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; -#else - (void)do_blit_readpixels; - (void)do_texture_readpixels; -#endif - if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 61aefa01b8..301c3df17c 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -48,7 +48,6 @@ #include "intel_buffer_objects.h" #include "intel_bufmgr.h" #include "intel_batchbuffer.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_REGION @@ -443,6 +442,7 @@ intel_region_attach_pbo(struct intel_context *intel, region->pbo->region = region; dri_bo_reference(buffer); region->buffer = buffer; + region->tiling = I915_TILING_NONE; } diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 5165716e09..c9ef1647a3 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -37,15 +37,11 @@ #include "intel_buffers.h" #include "intel_bufmgr.h" #include "intel_chipset.h" -#include "intel_extensions.h" #include "intel_fbo.h" -#include "intel_regions.h" #include "intel_screen.h" -#include "intel_span.h" #include "intel_tex.h" #include "i915_drm.h" -#include "i830_dri.h" #define DRI_CONF_TEXTURE_TILING(def) \ DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \ @@ -113,10 +109,42 @@ static const __DRItexBufferExtension intelTexBufferExtension = { intelSetTexBuffer2, }; +static void +intelDRI2Flush(__DRIdrawable *drawable) +{ + struct intel_context *intel = drawable->driContextPriv->driverPrivate; + + if (intel->gen < 4) + INTEL_FIREVERTICES(intel); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); +} + +static void +intelDRI2FlushInvalidate(__DRIdrawable *drawable) +{ + struct intel_context *intel = drawable->driContextPriv->driverPrivate; + + intel->using_dri2_swapbuffers = GL_TRUE; + + intelDRI2Flush(drawable); + drawable->validBuffers = GL_FALSE; + + intel_update_renderbuffers(intel->driContext, drawable); +} + +static const struct __DRI2flushExtensionRec intelFlushExtension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + intelDRI2Flush, + intelDRI2FlushInvalidate, +}; + static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, &intelTexOffsetExtension.base, &intelTexBufferExtension.base, + &intelFlushExtension.base, NULL }; @@ -174,7 +202,7 @@ intelCreateBuffer(__DRIscreen * driScrnPriv, if (!fb) return GL_FALSE; - _mesa_initialize_framebuffer(fb, mesaVis); + _mesa_initialize_window_framebuffer(fb, mesaVis); if (mesaVis->redBits == 5) rgbFormat = MESA_FORMAT_RGB565; @@ -311,11 +339,10 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) intelScreenPrivate *intelScreen; GLenum fb_format[3]; GLenum fb_type[3]; - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ + static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + GLX_NONE, GLX_SWAP_UNDEFINED_OML, + GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML }; uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; int color; diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index 605734d8e5..d925cb9997 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -259,36 +259,20 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define DBG 0 #define LOCAL_VARS \ - struct intel_context *intel = intel_context(ctx); \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\ - unsigned int num_cliprects; \ - struct drm_clip_rect *cliprects; \ - int x_off, y_off; \ + int minx = 0, miny = 0; \ + int maxx = ctx->DrawBuffer->Width; \ + int maxy = ctx->DrawBuffer->Height; \ int pitch = irb->region->pitch * irb->region->cpp; \ void *buf = irb->region->buffer->virtual; \ GLuint p; \ (void) p; \ (void)buf; (void)pitch; /* unused for non-gttmap. */ \ - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); -/* XXX FBO: this is identical to the macro in spantmp2.h except we get - * the cliprect info from the context, not the driDrawable. - * Move this into spantmp2.h someday. - */ -#define HW_CLIPLOOP() \ - do { \ - int _nc = num_cliprects; \ - while ( _nc-- ) { \ - int minx = cliprects[_nc].x1 - x_off; \ - int miny = cliprects[_nc].y1 - y_off; \ - int maxx = cliprects[_nc].x2 - x_off; \ - int maxy = cliprects[_nc].y2 - y_off; - -#if 0 - }} -#endif +#define HW_CLIPLOOP() +#define HW_ENDCLIPLOOP() #define Y_FLIP(_y) ((_y) * yScale + yBias) @@ -297,9 +281,9 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define HW_UNLOCK() /* Convenience macros to avoid typing the swizzle argument over and over */ -#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off) -#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off) -#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off) +#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X), (_Y)) +#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X), (_Y)) +#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X), (_Y)) /* r5g6b5 color span and pixel functions */ #define INTEL_PIXEL_FMT GL_RGB @@ -342,18 +326,15 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #include "intel_spantmp.h" #define LOCAL_DEPTH_VARS \ - struct intel_context *intel = intel_context(ctx); \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\ - unsigned int num_cliprects; \ - struct drm_clip_rect *cliprects; \ - int x_off, y_off; \ + int minx = 0, miny = 0; \ + int maxx = ctx->DrawBuffer->Width; \ + int maxy = ctx->DrawBuffer->Height; \ int pitch = irb->region->pitch * irb->region->cpp; \ void *buf = irb->region->buffer->virtual; \ (void)buf; (void)pitch; /* unused for non-gttmap. */ \ - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS diff --git a/src/mesa/drivers/dri/intel/intel_state.c b/src/mesa/drivers/dri/intel/intel_state.c index aefae53eb2..c5ef909dbf 100644 --- a/src/mesa/drivers/dri/intel/intel_state.c +++ b/src/mesa/drivers/dri/intel/intel_state.c @@ -35,8 +35,6 @@ #include "intel_screen.h" #include "intel_context.h" -#include "intel_regions.h" -#include "swrast/swrast.h" int intel_translate_shadow_compare_func(GLenum func) diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index d8e71093c4..d67451cf8e 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -36,7 +36,6 @@ #include "intel_screen.h" #include "intel_context.h" -#include "intel_batchbuffer.h" #include "intel_buffers.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" @@ -114,8 +113,6 @@ do_copy_texsubimage(struct intel_context *intel, drm_intel_bo *dst_bo = intel_region_buffer(intel, intelImage->mt->region, INTEL_WRITE_PART); - const GLint orig_x = x; - const GLint orig_y = y; GLuint image_x, image_y; GLshort src_pitch; @@ -125,9 +122,6 @@ do_copy_texsubimage(struct intel_context *intel, intelImage->face, 0, &image_x, &image_y); - /* Update dst for clipped src. Need to also clip the source rect. */ - dstx += x - orig_x; - dsty += y - orig_y; /* Can't blit to tiled buffers with non-tile-aligned offset. */ if (intelImage->mt->region->tiling == I915_TILING_Y) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c index a7c6c45ffe..7be5231eae 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_format.c +++ b/src/mesa/drivers/dri/intel/intel_tex_format.c @@ -1,6 +1,5 @@ #include "intel_context.h" #include "intel_tex.h" -#include "intel_chipset.h" #include "main/enums.h" diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 307669f87e..6402141170 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -7,7 +7,6 @@ #include "main/convolve.h" #include "main/context.h" #include "main/formats.h" -#include "main/image.h" #include "main/texcompress.h" #include "main/texstore.h" #include "main/texgetimage.h" @@ -178,6 +177,7 @@ check_pbo_format(GLint internalFormat, switch (internalFormat) { case 4: case GL_RGBA: + case GL_RGBA8: return (format == GL_BGRA && (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) && @@ -187,6 +187,11 @@ check_pbo_format(GLint internalFormat, return (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && mesa_format == MESA_FORMAT_RGB565); + case 1: + case GL_LUMINANCE: + return (format == GL_LUMINANCE && + type == GL_UNSIGNED_BYTE && + mesa_format == MESA_FORMAT_L8); case GL_YCBCR_MESA: return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); default: @@ -241,7 +246,8 @@ try_pbo_upload(struct intel_context *intel, if (!intelEmitCopyBlit(intel, intelImage->mt->cpp, src_stride, src_buffer, src_offset, GL_FALSE, - dst_stride, dst_buffer, 0, GL_FALSE, + dst_stride, dst_buffer, 0, + intelImage->mt->region->tiling, 0, 0, dst_x, dst_y, width, height, GL_COPY)) { return GL_FALSE; @@ -742,7 +748,8 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, if (!intelObj) return; - intel_update_renderbuffers(pDRICtx, dPriv); + if (!dPriv->validBuffers) + intel_update_renderbuffers(pDRICtx, dPriv); rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); /* If the region isn't set, then intel_update_renderbuffers was unable diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index c9a24ac398..ed5c5d896b 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -2,10 +2,8 @@ #include "main/macros.h" #include "intel_context.h" -#include "intel_batchbuffer.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_TEXTURE diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index 3b4ef7ffd8..11bce31b12 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -33,8 +33,6 @@ #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" -#include "main/extensions.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_dd.c b/src/mesa/drivers/dri/mach64/mach64_dd.c index e400e9a918..ca713e2de5 100644 --- a/src/mesa/drivers/dri/mach64/mach64_dd.c +++ b/src/mesa/drivers/dri/mach64/mach64_dd.c @@ -31,12 +31,9 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" -#include "mach64_vb.h" #include "mach64_dd.h" #include "main/context.h" -#include "main/framebuffer.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_lock.c b/src/mesa/drivers/dri/mach64/mach64_lock.c index 8653c77da5..1a95a8f619 100644 --- a/src/mesa/drivers/dri/mach64/mach64_lock.c +++ b/src/mesa/drivers/dri/mach64/mach64_lock.c @@ -32,7 +32,6 @@ #include "mach64_context.h" #include "mach64_state.h" #include "mach64_lock.h" -#include "mach64_tex.h" #include "drirenderbuffer.h" #if DEBUG_LOCKING diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index 1ed3b0b70e..5cbfb85627 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -31,8 +31,6 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_tris.h" -#include "mach64_vb.h" #include "mach64_span.h" #include "main/context.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_span.c b/src/mesa/drivers/dri/mach64/mach64_span.c index b4ba2a41c9..0c52c0c88c 100644 --- a/src/mesa/drivers/dri/mach64/mach64_span.c +++ b/src/mesa/drivers/dri/mach64/mach64_span.c @@ -31,7 +31,6 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" #include "mach64_span.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c index df7cbc8670..b9093b5a13 100644 --- a/src/mesa/drivers/dri/mach64/mach64_state.c +++ b/src/mesa/drivers/dri/mach64/mach64_state.c @@ -36,7 +36,6 @@ #include "mach64_vb.h" #include "mach64_tex.h" -#include "main/context.h" #include "main/enums.h" #include "main/colormac.h" #include "swrast/swrast.h" @@ -44,8 +43,6 @@ #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" - /* ============================================================= * Alpha blending diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.c b/src/mesa/drivers/dri/mach64/mach64_tex.c index 6627d3c38a..1bce967d58 100644 --- a/src/mesa/drivers/dri/mach64/mach64_tex.c +++ b/src/mesa/drivers/dri/mach64/mach64_tex.c @@ -31,13 +31,8 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" -#include "mach64_vb.h" -#include "mach64_tris.h" #include "mach64_tex.h" -#include "main/context.h" -#include "main/macros.h" #include "main/simple_list.h" #include "main/enums.h" #include "main/texstore.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_texmem.c b/src/mesa/drivers/dri/mach64/mach64_texmem.c index b97e9eec25..46cee4320d 100644 --- a/src/mesa/drivers/dri/mach64/mach64_texmem.c +++ b/src/mesa/drivers/dri/mach64/mach64_texmem.c @@ -37,10 +37,7 @@ #include "main/imports.h" #include "mach64_context.h" -#include "mach64_state.h" #include "mach64_ioctl.h" -#include "mach64_vb.h" -#include "mach64_tris.h" #include "mach64_tex.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_texstate.c b/src/mesa/drivers/dri/mach64/mach64_texstate.c index df0a09a5c1..adf774ec19 100644 --- a/src/mesa/drivers/dri/mach64/mach64_texstate.c +++ b/src/mesa/drivers/dri/mach64/mach64_texstate.c @@ -36,8 +36,6 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" -#include "mach64_vb.h" #include "mach64_tris.h" #include "mach64_tex.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_vb.c b/src/mesa/drivers/dri/mach64/mach64_vb.c index e58812e902..00da835376 100644 --- a/src/mesa/drivers/dri/mach64/mach64_vb.c +++ b/src/mesa/drivers/dri/mach64/mach64_vb.c @@ -42,7 +42,6 @@ #include "mach64_vb.h" #include "mach64_ioctl.h" #include "mach64_tris.h" -#include "mach64_state.h" #define MACH64_TEX1_BIT 0x1 diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index f835cb8bd6..e7813b6372 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -35,7 +35,6 @@ #include "mga_drm.h" #include "mga_xmesa.h" #include "main/context.h" -#include "main/matrix.h" #include "main/simple_list.h" #include "main/imports.h" #include "main/framebuffer.h" @@ -64,7 +63,6 @@ #include "utils.h" #include "vblank.h" -#include "main/extensions.h" #include "drirenderbuffer.h" #include "GL/internal/dri_interface.h" diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c index 3b1ea22b60..2f23c0e514 100644 --- a/src/mesa/drivers/dri/mga/mgadd.c +++ b/src/mesa/drivers/dri/mga/mgadd.c @@ -32,11 +32,6 @@ #include "mgacontext.h" #include "mgadd.h" -#include "mgastate.h" -#include "mgaspan.h" -#include "mgatex.h" -#include "mgatris.h" -#include "mgavb.h" #include "mga_xmesa.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index 8ce5d802ab..259358eaa3 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -42,10 +42,7 @@ #include "mgacontext.h" #include "mgadd.h" #include "mgastate.h" -#include "mgatex.h" -#include "mgavb.h" #include "mgaioctl.h" -#include "mgatris.h" #include "vblank.h" diff --git a/src/mesa/drivers/dri/mga/mgarender.c b/src/mesa/drivers/dri/mga/mgarender.c index 517c3b8f82..8b8fc485d3 100644 --- a/src/mesa/drivers/dri/mga/mgarender.c +++ b/src/mesa/drivers/dri/mga/mgarender.c @@ -48,7 +48,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mgacontext.h" #include "mgatris.h" -#include "mgastate.h" #include "mgaioctl.h" #include "mgavb.h" diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c index 62a9317cd4..ca3dd4b013 100644 --- a/src/mesa/drivers/dri/mga/mgatex.c +++ b/src/mesa/drivers/dri/mga/mgatex.c @@ -40,11 +40,8 @@ #include "mgacontext.h" #include "mgatex.h" #include "mgaregs.h" -#include "mgatris.h" #include "mgaioctl.h" -#include "swrast/swrast.h" - #include "xmlpool.h" /** diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c index c1bcd4b853..4c58c3bdb0 100644 --- a/src/mesa/drivers/dri/mga/mgatris.c +++ b/src/mesa/drivers/dri/mga/mgatris.c @@ -38,7 +38,6 @@ #include "mgaioctl.h" #include "mgatris.h" #include "mgavb.h" -#include "mgastate.h" static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim ); diff --git a/src/mesa/drivers/dri/mga/mgavb.c b/src/mesa/drivers/dri/mga/mgavb.c index 1c635b23a6..def5109863 100644 --- a/src/mesa/drivers/dri/mga/mgavb.c +++ b/src/mesa/drivers/dri/mga/mgavb.c @@ -39,7 +39,6 @@ #include "main/colormac.h" #include "tnl/t_context.h" -#include "swrast_setup/swrast_setup.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile new file mode 100644 index 0000000000..7c895a2e4b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -0,0 +1,59 @@ +# src/mesa/drivers/dri/nouveau/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +CFLAGS += $(shell pkg-config libdrm libdrm_nouveau --cflags) +DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) + +LIBNAME = nouveau_vieux_dri.so + +MINIGLX_SOURCES = + +DRIVER_SOURCES = \ + nouveau_screen.c \ + nouveau_context.c \ + nouveau_fbo.c \ + nouveau_driver.c \ + nouveau_state.c \ + nouveau_bufferobj.c \ + nouveau_span.c \ + nouveau_bo_state.c \ + nouveau_texture.c \ + nouveau_surface.c \ + nv04_context.c \ + nv04_screen.c \ + nv04_render.c \ + nv04_state_fb.c \ + nv04_state_raster.c \ + nv04_state_tex.c \ + nv04_state_frag.c \ + nv04_surface.c \ + nv10_context.c \ + nv10_screen.c \ + nv10_render.c \ + nv10_state_fb.c \ + nv10_state_polygon.c \ + nv10_state_raster.c \ + nv10_state_tex.c \ + nv10_state_frag.c \ + nv10_state_tnl.c \ + nv20_context.c \ + nv20_screen.c \ + nv20_render.c \ + nv20_state_fb.c \ + nv20_state_polygon.c \ + nv20_state_raster.c \ + nv20_state_tex.c \ + nv20_state_tnl.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + +include ../Makefile.template + +symlinks: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c new file mode 100644 index 0000000000..664632f407 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" + +static GLboolean +nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m, + uint32_t flags) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_pushbuf *push = chan->pushbuf; + uint32_t packet; + + if (m->gr->bound == NOUVEAU_GROBJ_UNBOUND) + nouveau_grobj_autobind(m->gr); + + if (MARK_RING(chan, 2, 2)) + return GL_FALSE; + + push->remaining -= 2; + packet = (m->gr->subc << 13) | (1 << 18) | m->mthd; + + if (flags) { + if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, + packet, 0, flags | + (m->flags & (NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | + NOUVEAU_BO_RDWR)), + 0, 0)) + goto fail; + } else { + *(push->cur++) = packet; + } + + if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, m->data, + m->data2, flags | m->flags, + m->vor, m->tor)) + goto fail; + + return GL_TRUE; + +fail: + MARK_UNDO(chan); + return GL_FALSE; +} + +static GLboolean +nouveau_bo_context_grow(struct nouveau_bo_context *bctx) +{ + struct nouveau_bo_marker *marker = bctx->marker; + int allocated = bctx->allocated + 1; + + marker = realloc(marker, allocated * sizeof(struct nouveau_bo_marker)); + if (!marker) + return GL_FALSE; + + bctx->marker = marker; + bctx->allocated = allocated; + + return GL_TRUE; +} + +GLboolean +nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr, + uint32_t mthd, struct nouveau_bo *bo, + uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor, + uint32_t flags) +{ + struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo; + struct nouveau_bo_marker *m; + + if (bctx->count == bctx->allocated) { + if (!nouveau_bo_context_grow(bctx)) + goto fail; + } + + m = &bctx->marker[bctx->count]; + + *m = (struct nouveau_bo_marker) { + .gr = gr, + .mthd = mthd, + .data = data, + .data2 = data2, + .vor = vor, + .tor = tor, + .flags = flags, + }; + nouveau_bo_ref(bo, &m->bo); + + s->count++; + bctx->count++; + + if (!nouveau_bo_marker_emit(bctx->ctx, m, 0)) + goto fail; + + return GL_TRUE; + +fail: + nouveau_bo_context_reset(bctx); + return GL_FALSE; +} + +void +nouveau_bo_context_reset(struct nouveau_bo_context *bctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo; + int i; + + for (i = 0; i < bctx->count; i++) + nouveau_bo_ref(NULL, &bctx->marker[i].bo); + + s->count -= bctx->count; + bctx->count = 0; +} + +GLboolean +nouveau_bo_state_emit(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i, j; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) { + struct nouveau_bo_context *bctx = &s->context[i]; + + for (j = 0; j < bctx->count; j++) { + if (!nouveau_bo_marker_emit(ctx, &bctx->marker[j], + NOUVEAU_BO_DUMMY)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +void +nouveau_bo_state_init(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) + s->context[i].ctx = ctx; +} + +void +nouveau_bo_state_destroy(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i, j; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) { + struct nouveau_bo_context *bctx = &s->context[i]; + + for (j = 0; j < bctx->count; j++) + nouveau_bo_ref(NULL, &bctx->marker[j].bo); + + if (bctx->marker) + free(bctx->marker); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h new file mode 100644 index 0000000000..da0a3a5c6f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_BO_STATE_H__ +#define __NOUVEAU_BO_STATE_H__ + +enum { + NOUVEAU_BO_CONTEXT_FRAMEBUFFER = 0, + NOUVEAU_BO_CONTEXT_LMA_DEPTH, + NOUVEAU_BO_CONTEXT_SURFACE, + NOUVEAU_BO_CONTEXT_TEXTURE0, + NOUVEAU_BO_CONTEXT_TEXTURE1, + NOUVEAU_BO_CONTEXT_TEXTURE2, + NOUVEAU_BO_CONTEXT_TEXTURE3, + NOUVEAU_BO_CONTEXT_VERTEX, + NUM_NOUVEAU_BO_CONTEXT +}; + +struct nouveau_bo_marker { + struct nouveau_grobj *gr; + uint32_t mthd; + + struct nouveau_bo *bo; + uint32_t data; + uint32_t data2; + uint32_t vor; + uint32_t tor; + uint32_t flags; +}; + +struct nouveau_bo_context { + GLcontext *ctx; + + struct nouveau_bo_marker *marker; + int allocated; + int count; +}; + +struct nouveau_bo_state { + struct nouveau_bo_context context[NUM_NOUVEAU_BO_CONTEXT]; + int count; +}; + +GLboolean +nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr, + uint32_t mthd, struct nouveau_bo *bo, + uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor, + uint32_t flags); + +#define nouveau_bo_markl(bctx, gr, mthd, bo, data, flags) \ + nouveau_bo_mark(bctx, gr, mthd, bo, data, 0, 0, 0, \ + flags | NOUVEAU_BO_LOW); + +#define nouveau_bo_marko(bctx, gr, mthd, bo, flags) \ + nouveau_bo_mark(bctx, gr, mthd, bo, 0, 0, \ + context_chan(ctx)->vram->handle, \ + context_chan(ctx)->gart->handle, \ + flags | NOUVEAU_BO_OR); + +void +nouveau_bo_context_reset(struct nouveau_bo_context *bctx); + +GLboolean +nouveau_bo_state_emit(GLcontext *ctx); + +void +nouveau_bo_state_init(GLcontext *ctx); + +void +nouveau_bo_state_destroy(GLcontext *ctx); + +#define __context_bctx(ctx, i) \ + ({ \ + struct nouveau_context *nctx = to_nouveau_context(ctx); \ + struct nouveau_bo_context *bctx = &nctx->bo.context[i]; \ + nouveau_bo_context_reset(bctx); \ + bctx; \ + }) +#define context_bctx(ctx, s) \ + __context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s) +#define context_bctx_i(ctx, s, i) \ + __context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s##0 + (i)) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c new file mode 100644 index 0000000000..1118b96de1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_bufferobj.h" +#include "nouveau_context.h" + +#include "main/bufferobj.h" + +static struct gl_buffer_object * +nouveau_bufferobj_new(GLcontext *ctx, GLuint buffer, GLenum target) +{ + struct nouveau_bufferobj *nbo; + + nbo = CALLOC_STRUCT(nouveau_bufferobj); + if (!nbo) + return NULL; + + _mesa_initialize_buffer_object(&nbo->base, buffer, target); + + return &nbo->base; +} + +static void +nouveau_bufferobj_del(GLcontext *ctx, struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_ref(NULL, &nbo->bo); + FREE(nbo); +} + +static GLboolean +nouveau_bufferobj_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size, + const GLvoid *data, GLenum usage, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + int ret; + + obj->Size = size; + obj->Usage = usage; + + nouveau_bo_ref(NULL, &nbo->bo); + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, + size, &nbo->bo); + assert(!ret); + + if (data) { + nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR); + _mesa_memcpy(nbo->bo->map, data, size); + nouveau_bo_unmap(nbo->bo); + } + + return GL_TRUE; +} + +static void +nouveau_bufferobj_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid *data, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR); + _mesa_memcpy(nbo->bo->map + offset, data, size); + nouveau_bo_unmap(nbo->bo); +} + +static void +nouveau_bufferobj_get_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, GLvoid *data, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_map(nbo->bo, NOUVEAU_BO_RD); + _mesa_memcpy(data, nbo->bo->map + offset, size); + nouveau_bo_unmap(nbo->bo); +} + +static void * +nouveau_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, + struct gl_buffer_object *obj) +{ + return ctx->Driver.MapBufferRange(ctx, target, 0, obj->Size, access, + obj); +} + +static void * +nouveau_bufferobj_map_range(GLcontext *ctx, GLenum target, GLintptr offset, + GLsizeiptr length, GLenum access, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + uint32_t flags = 0; + + assert(!obj->Pointer); + + if (!nbo->bo) + return NULL; + + if (access == GL_READ_ONLY_ARB || + access == GL_READ_WRITE_ARB) + flags |= NOUVEAU_BO_RD; + if (access == GL_WRITE_ONLY_ARB || + access == GL_READ_WRITE_ARB) + flags |= NOUVEAU_BO_WR; + + nouveau_bo_map_range(nbo->bo, offset, length, flags); + + obj->Pointer = nbo->bo->map; + obj->Offset = offset; + obj->Length = length; + obj->AccessFlags = access; + + return obj->Pointer; +} + +static GLboolean +nouveau_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + assert(obj->Pointer); + + nouveau_bo_unmap(nbo->bo); + + obj->Pointer = NULL; + obj->Offset = 0; + obj->Length = 0; + obj->AccessFlags = 0; + + return GL_TRUE; +} + +void +nouveau_bufferobj_functions_init(struct dd_function_table *functions) +{ + functions->NewBufferObject = nouveau_bufferobj_new; + functions->DeleteBuffer = nouveau_bufferobj_del; + functions->BufferData = nouveau_bufferobj_data; + functions->BufferSubData = nouveau_bufferobj_subdata; + functions->GetBufferSubData = nouveau_bufferobj_get_subdata; + functions->MapBuffer = nouveau_bufferobj_map; + functions->MapBufferRange = nouveau_bufferobj_map_range; + functions->UnmapBuffer = nouveau_bufferobj_unmap; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h new file mode 100644 index 0000000000..acfc4cb9a9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_BUFFEROBJ_H__ +#define __NOUVEAU_BUFFEROBJ_H__ + +struct nouveau_bufferobj { + struct gl_buffer_object base; + struct nouveau_bo *bo; +}; +#define to_nouveau_bufferobj(x) ((struct nouveau_bufferobj *)(x)) + +void +nouveau_bufferobj_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c new file mode 100644 index 0000000000..b87b8dbdd0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_bufferobj.h" +#include "nouveau_fbo.h" + +#include "main/dd.h" +#include "main/framebuffer.h" +#include "main/light.h" +#include "main/state.h" +#include "drivers/common/meta.h" +#include "drivers/common/driverfuncs.h" +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" + +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_fog_coord + +#include "main/remap_helper.h" + +static const struct dri_extension nouveau_extensions[] = { + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { "GL_ARB_multitexture", NULL }, + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_dot3", NULL }, + { "GL_ARB_texture_env_add", NULL }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { NULL, NULL } +}; + +GLboolean +nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx, + void *share_ctx) +{ + __DRIscreen *dri_screen = dri_ctx->driScreenPriv; + struct nouveau_screen *screen = dri_screen->private; + struct nouveau_context *nctx; + GLcontext *ctx; + + ctx = screen->driver->context_create(screen, visual, share_ctx); + if (!ctx) + return GL_FALSE; + + nctx = to_nouveau_context(ctx); + nctx->dri_context = dri_ctx; + dri_ctx->driverPrivate = ctx; + + return GL_TRUE; +} + +GLboolean +nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen, + const GLvisual *visual, GLcontext *share_ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct dd_function_table functions; + + nctx->screen = screen; + nctx->fallback = HWTNL; + + /* Initialize the function pointers */ + _mesa_init_driver_functions(&functions); + nouveau_driver_functions_init(&functions); + nouveau_bufferobj_functions_init(&functions); + nouveau_texture_functions_init(&functions); + nouveau_fbo_functions_init(&functions); + + /* Initialize the mesa context */ + _mesa_initialize_context(ctx, visual, share_ctx, &functions, NULL); + + nouveau_state_init(ctx); + nouveau_bo_state_init(ctx); + _mesa_meta_init(ctx); + _swrast_CreateContext(ctx); + _vbo_CreateContext(ctx); + _tnl_CreateContext(ctx); + nouveau_span_functions_init(ctx); + _mesa_allow_light_in_model(ctx, GL_FALSE); + + /* Enable any supported extensions */ + driInitExtensions(ctx, nouveau_extensions, GL_TRUE); + + return GL_TRUE; +} + +void +nouveau_context_destroy(__DRIcontext *dri_ctx) +{ + struct nouveau_context *nctx = dri_ctx->driverPrivate; + GLcontext *ctx = &nctx->base; + + if (nctx->screen->context == nctx) + nctx->screen->context = NULL; + + _tnl_DestroyContext(ctx); + _vbo_DestroyContext(ctx); + _swrast_DestroyContext(ctx); + _mesa_meta_free(ctx); + nouveau_bo_state_destroy(ctx); + context_drv(ctx)->context_destroy(ctx); +} + +static void +nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + unsigned int *stamp) +{ + struct nouveau_context *nctx = context->driverPrivate; + GLcontext *ctx = &nctx->base; + __DRIscreen *screen = context->driScreenPriv; + struct gl_framebuffer *fb = drawable->driverPrivate; + unsigned int attachments[10]; + __DRIbuffer *buffers = NULL; + int i = 0, count, ret; + + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (fb->Visual.doubleBufferMode) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (fb->Visual.haveDepthBuffer && fb->Visual.haveStencilBuffer) + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + else if (fb->Visual.haveDepthBuffer) + attachments[i++] = __DRI_BUFFER_DEPTH; + else if (fb->Visual.haveStencilBuffer) + attachments[i++] = __DRI_BUFFER_STENCIL; + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, &drawable->h, + attachments, i, &count, + drawable->loaderPrivate); + if (buffers == NULL) + return; + + for (i = 0; i < count; i++) { + struct gl_renderbuffer *rb; + struct nouveau_surface *s; + uint32_t old_handle; + int index; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + case __DRI_BUFFER_FAKE_FRONT_LEFT: + index = BUFFER_FRONT_LEFT; + break; + case __DRI_BUFFER_BACK_LEFT: + index = BUFFER_BACK_LEFT; + break; + case __DRI_BUFFER_DEPTH: + case __DRI_BUFFER_DEPTH_STENCIL: + index = BUFFER_DEPTH; + break; + case __DRI_BUFFER_STENCIL: + index = BUFFER_STENCIL; + break; + default: + assert(0); + } + + rb = fb->Attachment[index].Renderbuffer; + s = &to_nouveau_renderbuffer(rb)->surface; + + s->width = drawable->w; + s->height = drawable->h; + s->pitch = buffers[i].pitch; + s->cpp = buffers[i].cpp; + + /* Don't bother to reopen the bo if it happens to be + * the same. */ + if (s->bo) { + ret = nouveau_bo_handle_get(s->bo, &old_handle); + assert(!ret); + } + + if (!s->bo || old_handle != buffers[i].name) { + nouveau_bo_ref(NULL, &s->bo); + ret = nouveau_bo_handle_ref(context_dev(ctx), + buffers[i].name, &s->bo); + assert(!ret); + + context_dirty(ctx, FRAMEBUFFER); + } + } + + _mesa_resize_framebuffer(ctx, fb, drawable->w, drawable->h); +} + +GLboolean +nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw, + __DRIdrawable *dri_read) +{ + if (dri_ctx) { + struct nouveau_context *nctx = dri_ctx->driverPrivate; + GLcontext *ctx = &nctx->base; + + if (nctx->screen->context != nctx) { + nctx->screen->context = nctx; + BITSET_ONES(nctx->dirty); + } + + /* Ask the X server for new renderbuffers. */ + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable.d_stamp); + if (dri_draw != dri_read) + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->drawable.r_stamp); + + /* Pass it down to mesa. */ + _mesa_make_current(ctx, dri_draw->driverPrivate, + dri_read->driverPrivate); + _mesa_update_state(ctx); + + FIRE_RING(context_chan(ctx)); + + } else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +GLboolean +nouveau_context_unbind(__DRIcontext *dri_ctx) +{ + return GL_TRUE; +} + +void +nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nctx->fallback = MAX2(HWTNL, mode); + + if (mode < SWRAST) + nouveau_state_emit(ctx); + else + FIRE_RING(context_chan(ctx)); +} + +void +nouveau_validate_framebuffer(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + /* Someone's planning to draw something really soon. */ + nctx->drawable.dirty = GL_TRUE; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h new file mode 100644 index 0000000000..9812963e1a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "nouveau_screen.h" +#include "nouveau_state.h" +#include "nouveau_bo_state.h" +#include "nouveau_render.h" + +#include "main/bitset.h" + +enum nouveau_fallback { + HWTNL = 0, + SWTNL, + SWRAST, +}; + +struct nouveau_drawable_state { + GLboolean dirty; + unsigned int d_stamp; + unsigned int r_stamp; +}; + +struct nouveau_context { + GLcontext base; + __DRIcontext *dri_context; + struct nouveau_screen *screen; + + BITSET_DECLARE(dirty, MAX_NOUVEAU_STATE); + enum nouveau_fallback fallback; + + struct nouveau_bo_state bo; + struct nouveau_render_state render; + struct nouveau_drawable_state drawable; +}; + +#define to_nouveau_context(ctx) ((struct nouveau_context *)(ctx)) + +#define context_dev(ctx) \ + (to_nouveau_context(ctx)->screen->device) +#define context_chipset(ctx) \ + (context_dev(ctx)->chipset) +#define context_chan(ctx) \ + (to_nouveau_context(ctx)->screen->chan) +#define context_eng3d(ctx) \ + (to_nouveau_context(ctx)->screen->eng3d) +#define context_drv(ctx) \ + (to_nouveau_context(ctx)->screen->driver) +#define context_dirty(ctx, s) \ + BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s) +#define context_dirty_i(ctx, s, i) \ + BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s##0 + i) + +GLboolean +nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx, + void *share_ctx); + +GLboolean +nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen, + const GLvisual *visual, GLcontext *share_ctx); + +void +nouveau_context_destroy(__DRIcontext *dri_ctx); + +GLboolean +nouveau_context_make_current(__DRIcontext *dri_ctx, + __DRIdrawable *ddraw, + __DRIdrawable *rdraw); + +GLboolean +nouveau_context_unbind(__DRIcontext *dri_ctx); + +void +nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode); + +void +nouveau_validate_framebuffer(GLcontext *ctx); + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c new file mode 100644 index 0000000000..bf0e20ca81 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" + +#include "drivers/common/meta.h" + +static const GLubyte * +nouveau_get_string(GLcontext *ctx, GLenum name) +{ + static char buffer[128]; + char hardware_name[32]; + + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Nouveau"; + + case GL_RENDERER: + sprintf(hardware_name, "nv%02X", context_chipset(ctx)); + driGetRendererString(buffer, hardware_name, DRIVER_DATE, 0); + + return (GLubyte *)buffer; + default: + return NULL; + } +} + +static void +nouveau_flush(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + + FIRE_RING(chan); + + if (ctx->DrawBuffer->Name == 0 && + ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + __DRIscreen *screen = nctx->screen->dri_screen; + __DRIdri2LoaderExtension *dri2 = screen->dri2.loader; + __DRIdrawable *drawable = nctx->dri_context->driDrawablePriv; + + dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); + } + + nctx->drawable.dirty = GL_FALSE; +} + +static void +nouveau_finish(GLcontext *ctx) +{ + nouveau_flush(ctx); +} + +void +nouveau_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + int x, y, w, h; + int i, buf; + + nouveau_validate_framebuffer(ctx); + get_scissors(fb, &x, &y, &w, &h); + + for (i = 0; i < BUFFER_COUNT; i++) { + struct nouveau_surface *s; + unsigned mask, value; + + buf = buffers & (1 << i); + if (!buf) + continue; + + s = &to_nouveau_renderbuffer( + fb->Attachment[i].Renderbuffer->Wrapped)->surface; + + if (buf & BUFFER_BITS_COLOR) { + mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]); + value = pack_rgba_f(s->format, ctx->Color.ClearColor); + + if (mask) + context_drv(ctx)->surface_fill( + ctx, s, mask, value, x, y, w, h); + + buffers &= ~buf; + + } else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { + mask = pack_zs_i(s->format, + (buffers & BUFFER_BIT_DEPTH && + ctx->Depth.Mask) ? ~0 : 0, + (buffers & BUFFER_BIT_STENCIL && + ctx->Stencil.WriteMask[0]) ? ~0 : 0); + value = pack_zs_f(s->format, + ctx->Depth.Clear, + ctx->Stencil.Clear); + + if (mask) + context_drv(ctx)->surface_fill( + ctx, s, mask, value, x, y, w, h); + + buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + } + } + + if (buffers) + _mesa_meta_Clear(ctx, buffers); +} + +void +nouveau_driver_functions_init(struct dd_function_table *functions) +{ + functions->GetString = nouveau_get_string; + functions->Flush = nouveau_flush; + functions->Finish = nouveau_finish; + functions->Clear = nouveau_clear; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h new file mode 100644 index 0000000000..3b4d332d74 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_DRIVER_H__ +#define __NOUVEAU_DRIVER_H__ + +#include "main/imports.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/formats.h" +#include "utils.h" +#include "dri_util.h" + +#undef NDEBUG +#include <assert.h> + +#include "nouveau_device.h" +#include "nouveau_pushbuf.h" +#include "nouveau_grobj.h" +#include "nouveau_channel.h" +#include "nouveau_bo.h" +#include "nouveau_notifier.h" +#include "nouveau_screen.h" +#include "nouveau_state.h" +#include "nouveau_surface.h" + +#define DRIVER_DATE "20091015" +#define DRIVER_AUTHOR "Nouveau" + +struct nouveau_driver { + void (*screen_destroy)(struct nouveau_screen *screen); + + GLcontext *(*context_create)(struct nouveau_screen *screen, + const GLvisual *visual, + GLcontext *share_ctx); + void (*context_destroy)(GLcontext *ctx); + + void (*surface_copy)(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, int w, int h); + void (*surface_fill)(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h); + + nouveau_state_func *emit; + int num_emit; +}; + +#define nouveau_error(format, ...) \ + _mesa_fprintf(stderr, "%s: " format, __func__, ## __VA_ARGS__) + +void +nouveau_clear(GLcontext *ctx, GLbitfield buffers); + +void +nouveau_span_functions_init(GLcontext *ctx); + +void +nouveau_driver_functions_init(struct dd_function_table *functions); + +void +nouveau_texture_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c new file mode 100644 index 0000000000..91eade8d63 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_fbo.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/fbobject.h" + +static GLboolean +set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + rb->InternalFormat = internalFormat; + + switch (internalFormat) { + case GL_RGB: + case GL_RGB8: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_XRGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; + case GL_RGBA: + case GL_RGBA8: + rb->_BaseFormat = GL_RGBA; + rb->Format = MESA_FORMAT_ARGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; + case GL_RGB5: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_RGB565; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z16; + rb->DataType = GL_UNSIGNED_SHORT; + s->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + case GL_STENCIL_INDEX8_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z24_S8; + rb->DataType = GL_UNSIGNED_INT; + s->cpp = 4; + break; + default: + return GL_FALSE; + } + + s->format = rb->Format; + + return GL_TRUE; +} + +static GLboolean +nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; + + rb->Width = width; + rb->Height = height; + + nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, + rb->Format, width, height); + + context_dirty(ctx, FRAMEBUFFER); + return GL_TRUE; +} + +static void +nouveau_renderbuffer_del(struct gl_renderbuffer *rb) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + nouveau_surface_ref(NULL, s); + FREE(rb); +} + +static struct gl_renderbuffer * +nouveau_renderbuffer_new(GLcontext *ctx, GLuint name) +{ + struct gl_renderbuffer *rb; + + rb = (struct gl_renderbuffer *) + CALLOC_STRUCT(nouveau_renderbuffer); + if (!rb) + return NULL; + + _mesa_init_renderbuffer(rb, name); + + rb->AllocStorage = nouveau_renderbuffer_storage; + rb->Delete = nouveau_renderbuffer_del; + + return rb; +} + +static GLboolean +nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; + + rb->Width = width; + rb->Height = height; + + context_dirty(ctx, FRAMEBUFFER); + return GL_TRUE; +} + +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable) +{ + struct gl_renderbuffer *rb; + + rb = nouveau_renderbuffer_new(NULL, 0); + if (!rb) + return NULL; + + rb->AllocStorage = nouveau_renderbuffer_dri_storage; + + if (!set_renderbuffer_format(rb, format)) { + nouveau_renderbuffer_del(rb); + return NULL; + } + + return rb; +} + +static struct gl_framebuffer * +nouveau_framebuffer_new(GLcontext *ctx, GLuint name) +{ + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_user_framebuffer(&nfb->base, name); + + return &nfb->base; +} + +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual) +{ + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_window_framebuffer(&nfb->base, visual); + + return &nfb->base; +} + +static void +nouveau_bind_framebuffer(GLcontext *ctx, GLenum target, + struct gl_framebuffer *dfb, + struct gl_framebuffer *rfb) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + + context_dirty(ctx, FRAMEBUFFER); +} + +static GLenum +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return GL_RGBA8; + case MESA_FORMAT_RGB565: + return GL_RGB5; + default: + assert(0); + } +} + +static void +nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + 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. */ + if (!rb) { + rb = nouveau_renderbuffer_new(ctx, 0); + assert(rb); + + rb->AllocStorage = NULL; + _mesa_reference_renderbuffer(&att->Renderbuffer, rb); + } + + /* Update the renderbuffer fields from the texture. */ + ret = set_renderbuffer_format(rb, get_tex_format(ti)); + assert(ret); + + rb->Width = ti->Width; + rb->Height = ti->Height; + nouveau_surface_ref(&to_nouveau_teximage(ti)->surface, + &to_nouveau_renderbuffer(rb)->surface); + + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_finish_render_texture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att) +{ + struct nouveau_renderbuffer *nrb + = to_nouveau_renderbuffer(att->Renderbuffer); + + texture_dirty(att->Texture); + nouveau_surface_ref(NULL, &nrb->surface); +} + +void +nouveau_fbo_functions_init(struct dd_function_table *functions) +{ + functions->NewFramebuffer = nouveau_framebuffer_new; + functions->NewRenderbuffer = nouveau_renderbuffer_new; + functions->BindFramebuffer = nouveau_bind_framebuffer; + functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer; + functions->RenderTexture = nouveau_render_texture; + functions->FinishRenderTexture = nouveau_finish_render_texture; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h new file mode 100644 index 0000000000..5ae984bbff --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_FBO_H__ +#define __NOUVEAU_FBO_H__ + +struct nouveau_framebuffer { + struct gl_framebuffer base; + struct nouveau_bo *lma_bo; +}; +#define to_nouveau_framebuffer(x) ((struct nouveau_framebuffer *)(x)) + +struct nouveau_renderbuffer { + struct gl_renderbuffer base; + struct nouveau_surface surface; +}; +#define to_nouveau_renderbuffer(x) ((struct nouveau_renderbuffer *)(x)) + +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual); + +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable); + +void +nouveau_fbo_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h new file mode 100644 index 0000000000..00007a9a35 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2007-2010 The Nouveau Project. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_GLDEFS_H__ +#define __NOUVEAU_GLDEFS_H__ + +static inline unsigned +nvgl_blend_func(unsigned func) +{ + switch (func) { + case GL_ZERO: + return 0x0000; + case GL_ONE: + return 0x0001; + case GL_SRC_COLOR: + return 0x0300; + case GL_ONE_MINUS_SRC_COLOR: + return 0x0301; + case GL_SRC_ALPHA: + return 0x0302; + case GL_ONE_MINUS_SRC_ALPHA: + return 0x0303; + case GL_DST_ALPHA: + return 0x0304; + case GL_ONE_MINUS_DST_ALPHA: + return 0x0305; + case GL_DST_COLOR: + return 0x0306; + case GL_ONE_MINUS_DST_COLOR: + return 0x0307; + case GL_SRC_ALPHA_SATURATE: + return 0x0308; + case GL_CONSTANT_COLOR: + return 0x8001; + case GL_ONE_MINUS_CONSTANT_COLOR: + return 0x8002; + case GL_CONSTANT_ALPHA: + return 0x8003; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return 0x8004; + default: + assert(0); + } +} + +static inline unsigned +nvgl_blend_eqn(unsigned eqn) +{ + switch (eqn) { + case GL_FUNC_ADD: + return 0x8006; + case GL_MIN: + return 0x8007; + case GL_MAX: + return 0x8008; + case GL_FUNC_SUBTRACT: + return 0x800a; + case GL_FUNC_REVERSE_SUBTRACT: + return 0x800b; + default: + assert(0); + } +} + +static inline unsigned +nvgl_logicop_func(unsigned func) +{ + switch (func) { + case GL_CLEAR: + return 0x1500; + case GL_NOR: + return 0x1508; + case GL_AND_INVERTED: + return 0x1504; + case GL_COPY_INVERTED: + return 0x150c; + case GL_AND_REVERSE: + return 0x1502; + case GL_INVERT: + return 0x150a; + case GL_XOR: + return 0x1506; + case GL_NAND: + return 0x150e; + case GL_AND: + return 0x1501; + case GL_EQUIV: + return 0x1509; + case GL_NOOP: + return 0x1505; + case GL_OR_INVERTED: + return 0x150d; + case GL_COPY: + return 0x1503; + case GL_OR_REVERSE: + return 0x150b; + case GL_OR: + return 0x1507; + case GL_SET: + return 0x150f; + default: + assert(0); + } +} + +static inline unsigned +nvgl_comparison_op(unsigned op) +{ + switch (op) { + case GL_NEVER: + return 0x0200; + case GL_LESS: + return 0x0201; + case GL_EQUAL: + return 0x0202; + case GL_LEQUAL: + return 0x0203; + case GL_GREATER: + return 0x0204; + case GL_NOTEQUAL: + return 0x0205; + case GL_GEQUAL: + return 0x0206; + case GL_ALWAYS: + return 0x0207; + default: + assert(0); + } +} + +static inline unsigned +nvgl_polygon_mode(unsigned mode) +{ + switch (mode) { + case GL_POINT: + return 0x1b00; + case GL_LINE: + return 0x1b01; + case GL_FILL: + return 0x1b02; + default: + assert(0); + } +} + +static inline unsigned +nvgl_stencil_op(unsigned op) +{ + switch (op) { + case GL_ZERO: + return 0x0000; + case GL_INVERT: + return 0x150a; + case GL_KEEP: + return 0x1e00; + case GL_REPLACE: + return 0x1e01; + case GL_INCR: + return 0x1e02; + case GL_DECR: + return 0x1e03; + case GL_INCR_WRAP_EXT: + return 0x8507; + case GL_DECR_WRAP_EXT: + return 0x8508; + default: + assert(0); + } +} + +static inline unsigned +nvgl_primitive(unsigned prim) +{ + switch (prim) { + case GL_POINTS: + return 0x0001; + case GL_LINES: + return 0x0002; + case GL_LINE_LOOP: + return 0x0003; + case GL_LINE_STRIP: + return 0x0004; + case GL_TRIANGLES: + return 0x0005; + case GL_TRIANGLE_STRIP: + return 0x0006; + case GL_TRIANGLE_FAN: + return 0x0007; + case GL_QUADS: + return 0x0008; + case GL_QUAD_STRIP: + return 0x0009; + case GL_POLYGON: + return 0x000a; + default: + assert(0); + } +} + +static inline unsigned +nvgl_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP_TO_EDGE: + return 0x3; + case GL_CLAMP_TO_BORDER: + return 0x4; + case GL_CLAMP: + return 0x5; + default: + assert(0); + } +} + +static inline unsigned +nvgl_filter_mode(unsigned filter) +{ + switch (filter) { + case GL_NEAREST: + return 0x1; + case GL_LINEAR: + return 0x2; + case GL_NEAREST_MIPMAP_NEAREST: + return 0x3; + case GL_LINEAR_MIPMAP_NEAREST: + return 0x4; + case GL_NEAREST_MIPMAP_LINEAR: + return 0x5; + case GL_LINEAR_MIPMAP_LINEAR: + return 0x6; + default: + assert(0); + } +} + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render.h b/src/mesa/drivers/dri/nouveau/nouveau_render.h new file mode 100644 index 0000000000..bff0ccfd76 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_render.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_RENDER_H__ +#define __NOUVEAU_RENDER_H__ + +#include "vbo/vbo_context.h" + +struct nouveau_array_state; + +typedef void (*dispatch_t)(GLcontext *, unsigned int, int, unsigned int); +typedef unsigned (*extract_u_t)(struct nouveau_array_state *a, int i, int j); +typedef float (*extract_f_t)(struct nouveau_array_state *a, int i, int j); + +struct nouveau_attr_info { + int vbo_index; + int imm_method; + int imm_fields; + + void (*emit)(GLcontext *, struct nouveau_array_state *, const void *); +}; + +struct nouveau_array_state { + int attr; + int stride, fields, type; + + struct nouveau_bo *bo; + unsigned offset; + const void *buf; + + extract_u_t extract_u; + extract_f_t extract_f; +}; + +#define RENDER_SCRATCH_COUNT 32 +#define RENDER_SCRATCH_SIZE 64*1024 + +struct nouveau_scratch_state { + struct nouveau_bo *bo[RENDER_SCRATCH_COUNT]; + + int index; + int offset; + void *buf; +}; + +struct nouveau_swtnl_state { + struct nouveau_bo *vbo; + void *buf; + unsigned vertex_count; + GLenum primitive; +}; + +struct nouveau_render_state { + enum { + VBO, + IMM + } mode; + + struct nouveau_array_state ib; + struct nouveau_array_state attrs[VERT_ATTRIB_MAX]; + + /* Maps a HW VBO index or IMM emission order to an index in + * the attrs array above (or -1 if unused). */ + int map[VERT_ATTRIB_MAX]; + + int attr_count; + int vertex_size; + + struct nouveau_scratch_state scratch; + struct nouveau_swtnl_state swtnl; +}; + +#define to_render_state(ctx) (&to_nouveau_context(ctx)->render) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render_t.c b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c new file mode 100644 index 0000000000..c0505781cf --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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. + * + */ + +/* + * Vertex submission helper definitions shared among the software and + * hardware TnL paths. + */ + +#include "nouveau_gldefs.h" + +#include "main/light.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" + +#define OUT_INDICES_L(r, i, d, n) \ + BATCH_OUT_L(i + d, n); \ + (void)r +#define OUT_INDICES_I16(r, i, d, n) \ + BATCH_OUT_I16(r->ib.extract_u(&r->ib, 0, i) + d, \ + r->ib.extract_u(&r->ib, 0, i + 1) + d) +#define OUT_INDICES_I32(r, i, d, n) \ + BATCH_OUT_I32(r->ib.extract_u(&r->ib, 0, i) + d) + +/* + * Emit <n> vertices using BATCH_OUT_<out>, MAX_OUT_<out> at a time, + * grouping them in packets of length MAX_PACKET. + * + * out: hardware index data type. + * ctx: GL context. + * start: element within the index buffer to begin with. + * delta: integer correction that will be added to each index found in + * the index buffer. + */ +#define EMIT_VBO(out, ctx, start, delta, n) do { \ + struct nouveau_render_state *render = to_render_state(ctx); \ + int npush = n; \ + \ + while (npush) { \ + int npack = MIN2(npush, MAX_PACKET * MAX_OUT_##out); \ + npush -= npack; \ + \ + BATCH_PACKET_##out((npack + MAX_OUT_##out - 1) \ + / MAX_OUT_##out); \ + while (npack) { \ + int nout = MIN2(npack, MAX_OUT_##out); \ + npack -= nout; \ + \ + OUT_INDICES_##out(render, start, delta, \ + nout); \ + start += nout; \ + } \ + } \ + } while (0) + +/* + * Emit the <n>-th element of the array <a>, using IMM_OUT. + */ +#define EMIT_IMM(ctx, a, n) do { \ + struct nouveau_attr_info *info = \ + &TAG(vertex_attrs)[(a)->attr]; \ + int m; \ + \ + if (!info->emit) { \ + IMM_PACKET(info->imm_method, info->imm_fields); \ + \ + for (m = 0; m < (a)->fields; m++) \ + IMM_OUT((a)->extract_f(a, n, m)); \ + \ + for (m = (a)->fields; m < info->imm_fields; m++) \ + IMM_OUT(((float []){0, 0, 0, 1})[m]); \ + \ + } else { \ + info->emit(ctx, a, (a)->buf + n * (a)->stride); \ + } \ + } while (0) + +/* + * Select an appropriate dispatch function for the given index buffer. + */ +static void +get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) +{ + if (!a->fields) { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(L, ctx, start, delta, n); + }; + + *dispatch = f; + + } else if (a->type == GL_UNSIGNED_INT) { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(I32, ctx, start, delta, n); + }; + + *dispatch = f; + + } else { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(I32, ctx, start, delta, n & 1); + EMIT_VBO(I16, ctx, start, delta, n & ~1); + }; + + *dispatch = f; + } +} + +/* + * Select appropriate element extraction functions for the given + * array. + */ +static void +get_array_extract(struct nouveau_array_state *a, + extract_u_t *extract_u, extract_f_t *extract_f) +{ +#define EXTRACT(in_t, out_t, k) \ + ({ \ + auto out_t f(struct nouveau_array_state *, int, int); \ + out_t f(struct nouveau_array_state *a, int i, int j) { \ + in_t x = ((in_t *)(a->buf + i * a->stride))[j]; \ + \ + return (out_t)x / (k); \ + }; \ + f; \ + }); + + switch (a->type) { + case GL_BYTE: + *extract_u = EXTRACT(char, unsigned, 1); + *extract_f = EXTRACT(char, float, SCHAR_MAX); + break; + case GL_UNSIGNED_BYTE: + *extract_u = EXTRACT(unsigned char, unsigned, 1); + *extract_f = EXTRACT(unsigned char, float, UCHAR_MAX); + break; + case GL_SHORT: + *extract_u = EXTRACT(short, unsigned, 1); + *extract_f = EXTRACT(short, float, SHRT_MAX); + break; + case GL_UNSIGNED_SHORT: + *extract_u = EXTRACT(unsigned short, unsigned, 1); + *extract_f = EXTRACT(unsigned short, float, USHRT_MAX); + break; + case GL_INT: + *extract_u = EXTRACT(int, unsigned, 1); + *extract_f = EXTRACT(int, float, INT_MAX); + break; + case GL_UNSIGNED_INT: + *extract_u = EXTRACT(unsigned int, unsigned, 1); + *extract_f = EXTRACT(unsigned int, float, UINT_MAX); + break; + case GL_FLOAT: + *extract_u = EXTRACT(float, unsigned, 1.0 / UINT_MAX); + *extract_f = EXTRACT(float, float, 1); + break; + + default: + assert(0); + } +} + +/* + * Returns a pointer to a chunk of <size> bytes long GART memory. <bo> + * will be updated with the buffer object the memory is located in. + * + * If <offset> is provided, it will be updated with the offset within + * <bo> of the allocated memory. Otherwise the returned memory will + * always be located right at the beginning of <bo>. + */ +static inline void * +get_scratch_vbo(GLcontext *ctx, unsigned size, struct nouveau_bo **bo, + unsigned *offset) +{ + struct nouveau_scratch_state *scratch = &to_render_state(ctx)->scratch; + void *buf; + + if (scratch->buf && offset && + size <= RENDER_SCRATCH_SIZE - scratch->offset) { + nouveau_bo_ref(scratch->bo[scratch->index], bo); + + buf = scratch->buf + scratch->offset; + *offset = scratch->offset; + scratch->offset += size; + + } else if (size <= RENDER_SCRATCH_SIZE) { + scratch->index = (scratch->index + 1) % RENDER_SCRATCH_COUNT; + nouveau_bo_ref(scratch->bo[scratch->index], bo); + + nouveau_bo_map(*bo, NOUVEAU_BO_WR); + buf = scratch->buf = (*bo)->map; + nouveau_bo_unmap(*bo); + + if (offset) + *offset = 0; + scratch->offset = size; + + } else { + nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_MAP | NOUVEAU_BO_GART, 0, size, bo); + + nouveau_bo_map(*bo, NOUVEAU_BO_WR); + buf = (*bo)->map; + nouveau_bo_unmap(*bo); + + if (offset) + *offset = 0; + } + + return buf; +} + +/* + * Returns how many vertices you can draw using <n> pushbuf dwords. + */ +static inline unsigned +get_max_vertices(GLcontext *ctx, const struct _mesa_index_buffer *ib, + unsigned n) +{ + struct nouveau_render_state *render = to_render_state(ctx); + + if (render->mode == IMM) { + return MAX2(0, n - 4) / (render->vertex_size / 4 + + render->attr_count); + } else { + unsigned max_out; + + if (ib) { + switch (ib->type) { + case GL_UNSIGNED_INT: + max_out = MAX_OUT_I32; + break; + + case GL_UNSIGNED_SHORT: + max_out = MAX_OUT_I16; + break; + + case GL_UNSIGNED_BYTE: + max_out = MAX_OUT_I16; + break; + } + } else { + max_out = MAX_OUT_L; + } + + return MAX2(0, n - 7) * max_out * MAX_PACKET / (1 + MAX_PACKET); + } +} + +#include "nouveau_vbo_t.c" +#include "nouveau_swtnl_t.c" + +static void +TAG(emit_material)(GLcontext *ctx, struct nouveau_array_state *a, + const void *v) +{ + const int attr = a->attr - VERT_ATTRIB_GENERIC0; + const int state = ((int []) { + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE, + NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE, + NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR, + NOUVEAU_STATE_MATERIAL_BACK_SPECULAR, + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_SHININESS, + NOUVEAU_STATE_MATERIAL_BACK_SHININESS + }) [attr]; + + COPY_4V(ctx->Light.Material.Attrib[attr], (float *)v); + _mesa_update_material(ctx, 1 << attr); + + context_drv(ctx)->emit[state](ctx, state); +} + +static void +TAG(render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nouveau_validate_framebuffer(ctx); + + if (nctx->fallback == HWTNL) + TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib, + index_bounds_valid, min_index, max_index); + + if (nctx->fallback == SWTNL) + _tnl_vbo_draw_prims(ctx, arrays, prims, nr_prims, ib, + index_bounds_valid, min_index, max_index); +} + +void +TAG(render_init)(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_scratch_state *scratch = &render->scratch; + int ret, i; + + for (i = 0; i < RENDER_SCRATCH_COUNT; i++) { + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_MAP | NOUVEAU_BO_GART, + 0, RENDER_SCRATCH_SIZE, &scratch->bo[i]); + assert(!ret); + } + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + render->map[i] = -1; + + TAG(swtnl_init)(ctx); + vbo_set_draw_func(ctx, TAG(render_prims)); +} + +void +TAG(render_destroy)(GLcontext *ctx) +{ + TAG(swtnl_destroy)(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..de6328251e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_drmif.h" +#include "nv04_driver.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" + +static const __DRIextension *nouveau_screen_extensions[]; + +static void +nouveau_destroy_screen(__DRIscreen *dri_screen); + +static void +nouveau_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_screen *screen = chan->user_private; + struct nouveau_context *nctx = screen->context; + + if (nctx && nctx->fallback < SWRAST) + nouveau_state_emit(&nctx->base); +} + +static const __DRIconfig ** +nouveau_get_configs(void) +{ + __DRIconfig **configs = NULL; + int i; + + const uint8_t depth_bits[] = { 0, 16, 24, 24 }; + const uint8_t stencil_bits[] = { 0, 0, 0, 8 }; + const uint8_t msaa_samples[] = { 0 }; + + const struct { + GLenum format; + GLenum type; + } fb_formats[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML + }; + + for (i = 0; i < Elements(fb_formats); i++) { + __DRIconfig **config; + + config = driCreateConfigs(fb_formats[i].format, + fb_formats[i].type, + depth_bits, stencil_bits, + Elements(depth_bits), + back_buffer_modes, + Elements(back_buffer_modes), + msaa_samples, + Elements(msaa_samples)); + assert(config); + + configs = configs ? driConcatConfigs(configs, config) + : config; + } + + return (const __DRIconfig **)configs; +} + +static const __DRIconfig ** +nouveau_init_screen2(__DRIscreen *dri_screen) +{ + const __DRIconfig **configs; + struct nouveau_screen *screen; + int ret; + + /* Allocate the screen. */ + screen = CALLOC_STRUCT(nouveau_screen); + if (!screen) + return NULL; + + dri_screen->private = screen; + dri_screen->extensions = nouveau_screen_extensions; + screen->dri_screen = dri_screen; + + /* Open the DRM device. */ + ret = nouveau_device_open_existing(&screen->device, 0, dri_screen->fd, + 0); + if (ret) { + nouveau_error("Error opening the DRM device.\n"); + goto fail; + } + + ret = nouveau_channel_alloc(screen->device, 0xbeef0201, 0xbeef0202, + &screen->chan); + if (ret) { + nouveau_error("Error initializing the FIFO.\n"); + goto fail; + } + screen->chan->flush_notify = nouveau_channel_flush_notify; + screen->chan->user_private = screen; + + /* Do the card specific initialization */ + switch (screen->device->chipset & 0xf0) { + case 0x00: + ret = nv04_screen_init(screen); + break; + case 0x10: + ret = nv10_screen_init(screen); + break; + case 0x20: + ret = nv20_screen_init(screen); + break; + default: + assert(0); + } + if (!ret) { + nouveau_error("Error initializing the hardware.\n"); + goto fail; + } + + configs = nouveau_get_configs(); + if (!configs) { + nouveau_error("Error creating the framebuffer configs.\n"); + goto fail; + } + + return configs; +fail: + nouveau_destroy_screen(dri_screen); + return NULL; + +} + +static void +nouveau_destroy_screen(__DRIscreen *dri_screen) +{ + struct nouveau_screen *screen = dri_screen->private; + + if (!screen) + return; + + screen->driver->screen_destroy(screen); + + if (screen->chan) { + screen->chan->flush_notify = NULL; + nouveau_channel_free(&screen->chan); + } + + if (screen->device) + nouveau_device_close(&screen->device); + + FREE(screen); + dri_screen->private = NULL; +} + +static GLboolean +nouveau_create_buffer(__DRIscreen *dri_screen, + __DRIdrawable *drawable, + const __GLcontextModes *visual, + GLboolean is_pixmap) +{ + struct gl_renderbuffer *rb; + struct gl_framebuffer *fb; + GLenum color_format; + + if (is_pixmap) + return GL_FALSE; /* not implemented */ + + if (visual->redBits == 5) + color_format = GL_RGB5; + else if (visual->alphaBits == 0) + color_format = GL_RGB8; + else + color_format = GL_RGBA8; + + fb = nouveau_framebuffer_dri_new(visual); + if (!fb) + return GL_FALSE; + + /* Front buffer. */ + rb = nouveau_renderbuffer_dri_new(color_format, drawable); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb); + + /* Back buffer */ + if (visual->doubleBufferMode) { + rb = nouveau_renderbuffer_dri_new(color_format, drawable); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb); + } + + /* Depth/stencil buffer. */ + if (visual->depthBits == 24 && visual->stencilBits == 8) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); + + } else if (visual->depthBits == 24) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + + } else if (visual->depthBits == 16) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + } + + /* Software renderbuffers. */ + _mesa_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE, + visual->accumRedBits > 0, + GL_FALSE, GL_FALSE); + + drawable->driverPrivate = fb; + + return GL_TRUE; +} + +static void +nouveau_destroy_buffer(__DRIdrawable *drawable) +{ + _mesa_reference_framebuffer( + (struct gl_framebuffer **)&drawable->driverPrivate, NULL); +} + +static const __DRIextension *nouveau_screen_extensions[] = { + NULL +}; + +const struct __DriverAPIRec driDriverAPI = { + .InitScreen2 = nouveau_init_screen2, + .DestroyScreen = nouveau_destroy_screen, + .CreateBuffer = nouveau_create_buffer, + .DestroyBuffer = nouveau_destroy_buffer, + .CreateContext = nouveau_context_create, + .DestroyContext = nouveau_context_destroy, + .MakeCurrent = nouveau_context_make_current, + .UnbindContext = nouveau_context_unbind, +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driDRI2Extension.base, + NULL +}; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..5d45039b9e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +struct nouveau_context; + +struct nouveau_screen { + __DRIscreen *dri_screen; + + struct nouveau_device *device; + struct nouveau_channel *chan; + + struct nouveau_notifier *ntfy; + struct nouveau_grobj *eng3d; + struct nouveau_grobj *eng3dm; + struct nouveau_grobj *surf3d; + struct nouveau_grobj *m2mf; + struct nouveau_grobj *surf2d; + struct nouveau_grobj *rop; + struct nouveau_grobj *patt; + struct nouveau_grobj *rect; + struct nouveau_grobj *swzsurf; + struct nouveau_grobj *sifm; + + const struct nouveau_driver *driver; + struct nouveau_context *context; +}; + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c new file mode 100644 index 0000000000..dbbbf15b09 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_fbo.h" +#include "nouveau_context.h" +#include "nouveau_bo.h" + +#include "swrast/swrast.h" + +#define LOCAL_VARS \ + struct gl_framebuffer *fb = ctx->DrawBuffer; \ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; \ + GLuint p; \ + (void)p; + +#define LOCAL_DEPTH_VARS LOCAL_VARS + +#define HW_LOCK() +#define HW_UNLOCK() + +#define HW_CLIPLOOP() { \ + int minx = 0; \ + int miny = 0; \ + int maxx = fb->Width; \ + int maxy = fb->Height; + +#define HW_ENDCLIPLOOP() } + +#define Y_FLIP(y) (fb->Name ? (y) : rb->Height - 1 - (y)) + +/* RGB565 span functions */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 +#define TAG(x) nouveau_##x##_rgb565 +#define TAG2(x, y) nouveau_##x##_rgb565##y +#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp) + +#include "spantmp2.h" + +/* ARGB8888 span functions */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV +#define TAG(x) nouveau_##x##_argb8888 +#define TAG2(x, y) nouveau_##x##_argb8888##y +#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp) + +#include "spantmp2.h" + +/* Z16 span functions */ +#define VALUE_TYPE uint16_t +#define READ_DEPTH(v, x, y) \ + v = *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp); +#define WRITE_DEPTH(x, y, v) \ + *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v +#define TAG(x) nouveau_##x##_z16 + +#include "depthtmp.h" + +/* Z24S8 span functions */ +#define VALUE_TYPE uint32_t +#define READ_DEPTH(v, x, y) \ + v = *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp); +#define WRITE_DEPTH(x, y, v) \ + *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v +#define TAG(x) nouveau_##x##_z24s8 + +#include "depthtmp.h" + +static void +renderbuffer_map_unmap(struct gl_renderbuffer *rb, GLboolean map) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + if (map) { + switch (rb->Format) { + case MESA_FORMAT_RGB565: + nouveau_InitPointers_rgb565(rb); + break; + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + nouveau_InitPointers_argb8888(rb); + break; + case MESA_FORMAT_Z16: + nouveau_InitDepthPointers_z16(rb); + break; + case MESA_FORMAT_Z24_S8: + nouveau_InitDepthPointers_z24s8(rb); + break; + default: + assert(0); + } + + nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); + } else { + nouveau_bo_unmap(s->bo); + } +} + +static void +texture_unit_map_unmap(GLcontext *ctx, struct gl_texture_unit *u, GLboolean map) +{ + if (!u->_ReallyEnabled) + return; + + if (map) + ctx->Driver.MapTexture(ctx, u->_Current); + else + ctx->Driver.UnmapTexture(ctx, u->_Current); +} + +static void +span_map_unmap(GLcontext *ctx, GLboolean map) +{ + int i; + + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) + renderbuffer_map_unmap(ctx->DrawBuffer->_ColorDrawBuffers[i], map); + + renderbuffer_map_unmap(ctx->DrawBuffer->_ColorReadBuffer, map); + + if (ctx->DrawBuffer->_DepthBuffer) + renderbuffer_map_unmap(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + texture_unit_map_unmap(ctx, &ctx->Texture.Unit[i], map); +} + +static void +nouveau_span_start(GLcontext *ctx) +{ + nouveau_fallback(ctx, SWRAST); + span_map_unmap(ctx, GL_TRUE); +} + +static void +nouveau_span_finish(GLcontext *ctx) +{ + span_map_unmap(ctx, GL_FALSE); + nouveau_fallback(ctx, HWTNL); +} + +void +nouveau_span_functions_init(GLcontext *ctx) +{ + struct swrast_device_driver *swdd = + _swrast_GetDeviceDriverReference(ctx); + + swdd->SpanRenderStart = nouveau_span_start; + swdd->SpanRenderFinish = nouveau_span_finish; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c new file mode 100644 index 0000000000..d727822175 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" + +#include "swrast/swrast.h" +#include "tnl/tnl.h" + +static void +nouveau_alpha_func(GLcontext *ctx, GLenum func, GLfloat ref) +{ + context_dirty(ctx, ALPHA_FUNC); +} + +static void +nouveau_blend_color(GLcontext *ctx, const GLfloat color[4]) +{ + context_dirty(ctx, BLEND_COLOR); +} + +static void +nouveau_blend_equation_separate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + context_dirty(ctx, BLEND_EQUATION); +} + +static void +nouveau_blend_func_separate(GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) +{ + context_dirty(ctx, BLEND_FUNC); +} + +static void +nouveau_clip_plane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0); +} + +static void +nouveau_color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask) +{ + context_dirty(ctx, COLOR_MASK); +} + +static void +nouveau_color_material(GLcontext *ctx, GLenum face, GLenum mode) +{ + context_dirty(ctx, COLOR_MATERIAL); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); +} + +static void +nouveau_cull_face(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, CULL_FACE); +} + +static void +nouveau_front_face(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, FRONT_FACE); +} + +static void +nouveau_depth_func(GLcontext *ctx, GLenum func) +{ + context_dirty(ctx, DEPTH); +} + +static void +nouveau_depth_mask(GLcontext *ctx, GLboolean flag) +{ + context_dirty(ctx, DEPTH); +} + +static void +nouveau_depth_range(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + context_dirty(ctx, VIEWPORT); +} + +static void +nouveau_draw_buffer(GLcontext *ctx, GLenum buffer) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_draw_buffers(GLcontext *ctx, GLsizei n, const GLenum *buffers) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + int i; + + switch (cap) { + case GL_ALPHA_TEST: + context_dirty(ctx, ALPHA_FUNC); + break; + case GL_BLEND: + context_dirty(ctx, BLEND_EQUATION); + break; + case GL_COLOR_LOGIC_OP: + context_dirty(ctx, LOGIC_OPCODE); + break; + case GL_COLOR_MATERIAL: + context_dirty(ctx, COLOR_MATERIAL); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + break; + case GL_COLOR_SUM_EXT: + context_dirty(ctx, FRAG); + break; + case GL_CULL_FACE: + context_dirty(ctx, CULL_FACE); + break; + case GL_DEPTH_TEST: + context_dirty(ctx, DEPTH); + break; + case GL_DITHER: + context_dirty(ctx, DITHER); + break; + case GL_FOG: + context_dirty(ctx, FOG); + context_dirty(ctx, FRAG); + context_dirty(ctx, MODELVIEW); + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + break; + case GL_LIGHTING: + context_dirty(ctx, FRAG); + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + + for (i = 0; i < MAX_LIGHTS; i++) { + if (ctx->Light.Light[i].Enabled) + context_dirty_i(ctx, LIGHT_SOURCE, i); + } + + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + break; + case GL_LINE_SMOOTH: + context_dirty(ctx, LINE_MODE); + break; + case GL_NORMALIZE: + context_dirty(ctx, LIGHT_ENABLE); + break; + case GL_POINT_SMOOTH: + context_dirty(ctx, POINT_MODE); + break; + case GL_POLYGON_OFFSET_POINT: + case GL_POLYGON_OFFSET_LINE: + case GL_POLYGON_OFFSET_FILL: + context_dirty(ctx, POLYGON_OFFSET); + break; + case GL_POLYGON_SMOOTH: + context_dirty(ctx, POLYGON_MODE); + break; + case GL_SCISSOR_TEST: + context_dirty(ctx, SCISSOR); + break; + case GL_STENCIL_TEST: + context_dirty(ctx, STENCIL_FUNC); + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_fog(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, FOG); +} + +static void +nouveau_index_mask(GLcontext *ctx, GLuint mask) +{ + context_dirty(ctx, INDEX_MASK); +} + +static void +nouveau_light(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params) +{ + switch (pname) { + case GL_AMBIENT: + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + break; + case GL_DIFFUSE: + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + break; + case GL_SPECULAR: + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + break; + case GL_SPOT_CUTOFF: + case GL_POSITION: + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0); + break; + default: + context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0); + break; + } +} + +static void +nouveau_light_model(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, LIGHT_MODEL); + context_dirty(ctx, MODELVIEW); +} + +static void +nouveau_line_stipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + context_dirty(ctx, LINE_STIPPLE); +} + +static void +nouveau_line_width(GLcontext *ctx, GLfloat width) +{ + context_dirty(ctx, LINE_MODE); +} + +static void +nouveau_logic_opcode(GLcontext *ctx, GLenum opcode) +{ + context_dirty(ctx, LOGIC_OPCODE); +} + +static void +nouveau_point_parameter(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, POINT_PARAMETER); +} + +static void +nouveau_point_size(GLcontext *ctx, GLfloat size) +{ + context_dirty(ctx, POINT_MODE); +} + +static void +nouveau_polygon_mode(GLcontext *ctx, GLenum face, GLenum mode) +{ + context_dirty(ctx, POLYGON_MODE); +} + +static void +nouveau_polygon_offset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + context_dirty(ctx, POLYGON_OFFSET); +} + +static void +nouveau_polygon_stipple(GLcontext *ctx, const GLubyte *mask) +{ + context_dirty(ctx, POLYGON_STIPPLE); +} + +static void +nouveau_render_mode(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, RENDER_MODE); +} + +static void +nouveau_scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + context_dirty(ctx, SCISSOR); +} + +static void +nouveau_shade_model(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, SHADE_MODEL); +} + +static void +nouveau_stencil_func_separate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + context_dirty(ctx, STENCIL_FUNC); +} + +static void +nouveau_stencil_mask_separate(GLcontext *ctx, GLenum face, GLuint mask) +{ + context_dirty(ctx, STENCIL_MASK); +} + +static void +nouveau_stencil_op_separate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + context_dirty(ctx, STENCIL_OP); +} + +static void +nouveau_tex_gen(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params) +{ + context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit); +} + +static void +nouveau_tex_env(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param) +{ + switch (target) { + case GL_TEXTURE_FILTER_CONTROL_EXT: + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + default: + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_tex_parameter(GLcontext *ctx, GLenum target, + struct gl_texture_object *t, GLenum pname, + const GLfloat *params) +{ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + case GL_TEXTURE_LOD_BIAS: + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + texture_dirty(t); + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + context_dirty(ctx, VIEWPORT); +} + +void +nouveau_emit_nothing(GLcontext *ctx, int emit) +{ +} + +int +nouveau_next_dirty_state(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + int i = BITSET_FFS(nctx->dirty) - 1; + + if (i < 0 || i >= context_drv(ctx)->num_emit) + return -1; + + return i; +} + +void +nouveau_state_emit(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + const struct nouveau_driver *drv = context_drv(ctx); + int i; + + while ((i = nouveau_next_dirty_state(ctx)) >= 0) { + BITSET_CLEAR(nctx->dirty, i); + drv->emit[i](ctx, i); + } + + BITSET_ZERO(nctx->dirty); + + nouveau_bo_state_emit(ctx); +} + +static void +nouveau_update_state(GLcontext *ctx, GLbitfield new_state) +{ + if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW)) + context_dirty(ctx, PROJECTION); + + if (new_state & _NEW_MODELVIEW) + context_dirty(ctx, MODELVIEW); + + if (new_state & _NEW_CURRENT_ATTRIB && + new_state & _NEW_LIGHT) { + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + } + + _swrast_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + + nouveau_state_emit(ctx); +} + +void +nouveau_state_init(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + ctx->Driver.AlphaFunc = nouveau_alpha_func; + ctx->Driver.BlendColor = nouveau_blend_color; + ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate; + ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate; + ctx->Driver.ClipPlane = nouveau_clip_plane; + ctx->Driver.ColorMask = nouveau_color_mask; + ctx->Driver.ColorMaterial = nouveau_color_material; + ctx->Driver.CullFace = nouveau_cull_face; + ctx->Driver.FrontFace = nouveau_front_face; + ctx->Driver.DepthFunc = nouveau_depth_func; + ctx->Driver.DepthMask = nouveau_depth_mask; + ctx->Driver.DepthRange = nouveau_depth_range; + ctx->Driver.DrawBuffer = nouveau_draw_buffer; + ctx->Driver.DrawBuffers = nouveau_draw_buffers; + ctx->Driver.Enable = nouveau_enable; + ctx->Driver.Fogfv = nouveau_fog; + ctx->Driver.IndexMask = nouveau_index_mask; + ctx->Driver.Lightfv = nouveau_light; + ctx->Driver.LightModelfv = nouveau_light_model; + ctx->Driver.LineStipple = nouveau_line_stipple; + ctx->Driver.LineWidth = nouveau_line_width; + ctx->Driver.LogicOpcode = nouveau_logic_opcode; + ctx->Driver.PointParameterfv = nouveau_point_parameter; + ctx->Driver.PointSize = nouveau_point_size; + ctx->Driver.PolygonMode = nouveau_polygon_mode; + ctx->Driver.PolygonOffset = nouveau_polygon_offset; + ctx->Driver.PolygonStipple = nouveau_polygon_stipple; + ctx->Driver.RenderMode = nouveau_render_mode; + ctx->Driver.Scissor = nouveau_scissor; + ctx->Driver.ShadeModel = nouveau_shade_model; + ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate; + ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate; + ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate; + ctx->Driver.TexGen = nouveau_tex_gen; + ctx->Driver.TexEnv = nouveau_tex_env; + ctx->Driver.TexParameter = nouveau_tex_parameter; + ctx->Driver.Viewport = nouveau_viewport; + + ctx->Driver.UpdateState = nouveau_update_state; + + BITSET_ONES(nctx->dirty); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h new file mode 100644 index 0000000000..d001fa259a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_STATE_H__ +#define __NOUVEAU_STATE_H__ + +enum { + NOUVEAU_STATE_ALPHA_FUNC, + NOUVEAU_STATE_BLEND_COLOR, + NOUVEAU_STATE_BLEND_EQUATION, + NOUVEAU_STATE_BLEND_FUNC, + NOUVEAU_STATE_CLIP_PLANE0, + NOUVEAU_STATE_CLIP_PLANE1, + NOUVEAU_STATE_CLIP_PLANE2, + NOUVEAU_STATE_CLIP_PLANE3, + NOUVEAU_STATE_CLIP_PLANE4, + NOUVEAU_STATE_CLIP_PLANE5, + NOUVEAU_STATE_COLOR_MASK, + NOUVEAU_STATE_COLOR_MATERIAL, + NOUVEAU_STATE_CULL_FACE, + NOUVEAU_STATE_FRONT_FACE, + NOUVEAU_STATE_DEPTH, + NOUVEAU_STATE_DITHER, + NOUVEAU_STATE_FRAG, + NOUVEAU_STATE_FRAMEBUFFER, + NOUVEAU_STATE_FOG, + NOUVEAU_STATE_INDEX_MASK, + NOUVEAU_STATE_LIGHT_ENABLE, + NOUVEAU_STATE_LIGHT_MODEL, + NOUVEAU_STATE_LIGHT_SOURCE0, + NOUVEAU_STATE_LIGHT_SOURCE1, + NOUVEAU_STATE_LIGHT_SOURCE2, + NOUVEAU_STATE_LIGHT_SOURCE3, + NOUVEAU_STATE_LIGHT_SOURCE4, + NOUVEAU_STATE_LIGHT_SOURCE5, + NOUVEAU_STATE_LIGHT_SOURCE6, + NOUVEAU_STATE_LIGHT_SOURCE7, + NOUVEAU_STATE_LINE_STIPPLE, + NOUVEAU_STATE_LINE_MODE, + NOUVEAU_STATE_LOGIC_OPCODE, + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE, + NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE, + NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR, + NOUVEAU_STATE_MATERIAL_BACK_SPECULAR, + NOUVEAU_STATE_MATERIAL_FRONT_SHININESS, + NOUVEAU_STATE_MATERIAL_BACK_SHININESS, + NOUVEAU_STATE_MODELVIEW, + NOUVEAU_STATE_POINT_MODE, + NOUVEAU_STATE_POINT_PARAMETER, + NOUVEAU_STATE_POLYGON_MODE, + NOUVEAU_STATE_POLYGON_OFFSET, + NOUVEAU_STATE_POLYGON_STIPPLE, + NOUVEAU_STATE_PROJECTION, + NOUVEAU_STATE_RENDER_MODE, + NOUVEAU_STATE_SCISSOR, + NOUVEAU_STATE_SHADE_MODEL, + NOUVEAU_STATE_STENCIL_FUNC, + NOUVEAU_STATE_STENCIL_MASK, + NOUVEAU_STATE_STENCIL_OP, + NOUVEAU_STATE_TEX_ENV0, + NOUVEAU_STATE_TEX_ENV1, + NOUVEAU_STATE_TEX_ENV2, + NOUVEAU_STATE_TEX_ENV3, + NOUVEAU_STATE_TEX_GEN0, + NOUVEAU_STATE_TEX_GEN1, + NOUVEAU_STATE_TEX_GEN2, + NOUVEAU_STATE_TEX_GEN3, + NOUVEAU_STATE_TEX_OBJ0, + NOUVEAU_STATE_TEX_OBJ1, + NOUVEAU_STATE_TEX_OBJ2, + NOUVEAU_STATE_TEX_OBJ3, + NOUVEAU_STATE_VIEWPORT, + NUM_NOUVEAU_STATE, + + /* Room for card-specific states. */ + + MAX_NOUVEAU_STATE = NUM_NOUVEAU_STATE + 16, +}; + +typedef void (*nouveau_state_func)(GLcontext *ctx, int emit); + +void +nouveau_state_init(GLcontext *ctx); + +void +nouveau_emit_nothing(GLcontext *ctx, int emit); + +int +nouveau_next_dirty_state(GLcontext *ctx); + +void +nouveau_state_emit(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.c b/src/mesa/drivers/dri/nouveau/nouveau_surface.c new file mode 100644 index 0000000000..33393970a0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" + +void +nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s, + enum nouveau_surface_layout layout, + unsigned flags, unsigned format, + unsigned width, unsigned height) +{ + unsigned tile_mode, cpp = _mesa_get_format_bytes(format); + int ret; + + nouveau_bo_ref(NULL, &s->bo); + + *s = (struct nouveau_surface) { + .layout = layout, + .format = format, + .width = width, + .height = height, + .cpp = cpp, + .pitch = width * cpp, + }; + + if (layout == TILED) { + s->pitch = align(s->pitch, 256); + tile_mode = s->pitch; + } else { + s->pitch = align(s->pitch, 64); + tile_mode = 0; + } + + ret = nouveau_bo_new_tile(context_dev(ctx), flags, 0, s->pitch * height, + tile_mode, 0, &s->bo); + assert(!ret); +} + +void +nouveau_surface_ref(struct nouveau_surface *src, + struct nouveau_surface *dst) +{ + if (src) { + dst->offset = src->offset; + dst->layout = src->layout; + dst->format = src->format; + dst->width = src->width; + dst->height = src->height; + dst->cpp = src->cpp; + dst->pitch = src->pitch; + nouveau_bo_ref(src->bo, &dst->bo); + + } else { + nouveau_bo_ref(NULL, &dst->bo); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.h b/src/mesa/drivers/dri/nouveau/nouveau_surface.h new file mode 100644 index 0000000000..ebdc89afb4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_SURFACE_H__ +#define __NOUVEAU_SURFACE_H__ + +enum nouveau_surface_layout { + LINEAR = 0, + TILED, + SWIZZLED, +}; + +struct nouveau_surface { + struct nouveau_bo *bo; + unsigned offset; + + enum nouveau_surface_layout layout; + + gl_format format; + unsigned cpp, pitch; + + unsigned width, height; +}; + +void +nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s, + enum nouveau_surface_layout layout, + unsigned flags, unsigned format, + unsigned width, unsigned height); + +void +nouveau_surface_ref(struct nouveau_surface *src, + struct nouveau_surface *dst); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c new file mode 100644 index 0000000000..8fa922f422 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +static enum tnl_attr_format +swtnl_get_format(int type, int fields) { + switch (type) { + case GL_FLOAT: + switch (fields){ + case 1: + return EMIT_1F; + case 2: + return EMIT_2F; + case 3: + return EMIT_3F; + case 4: + return EMIT_4F; + default: + assert(0); + } + case GL_UNSIGNED_BYTE: + switch (fields) { + case 4: + return EMIT_4UB_4F_RGBA; + default: + assert(0); + } + default: + assert(0); + } +} + +static struct swtnl_attr_info { + int type; + int fields; +} swtnl_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .type = GL_FLOAT, + .fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_COLOR0] = { + .type = GL_UNSIGNED_BYTE, + .fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .type = GL_UNSIGNED_BYTE, + .fields = 4, + }, + [VERT_ATTRIB_FOG] = { + .type = GL_FLOAT, + .fields = 1, + }, + [VERT_ATTRIB_TEX0] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX1] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX2] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX3] = { + .type = GL_FLOAT, + .fields = -1, + }, +}; + +static void +swtnl_choose_attrs(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct tnl_clipspace *vtx = &tnl->clipspace; + static struct tnl_attr_map map[NUM_VERTEX_ATTRS]; + int fields, i, n = 0; + + render->mode = VBO; + render->attr_count = NUM_VERTEX_ATTRS; + + /* We always want non Ndc coords format */ + tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.ClipPtr; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + struct nouveau_attr_info *ha = &TAG(vertex_attrs)[i]; + struct swtnl_attr_info *sa = &swtnl_attrs[i]; + struct nouveau_array_state *a = &render->attrs[i]; + + if (!sa->fields) + continue; /* Unsupported attribute. */ + + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, i)) { + if (sa->fields > 0) + fields = sa->fields; + else + fields = tnl->vb.AttribPtr[i]->size; + + map[n++] = (struct tnl_attr_map) { + .attrib = i, + .format = swtnl_get_format(sa->type, fields), + }; + + render->map[ha->vbo_index] = i; + a->attr = i; + a->fields = fields; + a->type = sa->type; + } + } + + _tnl_install_attrs(ctx, map, n, NULL, 0); + + for (i = 0; i < vtx->attr_count; i++) { + struct tnl_clipspace_attr *ta = &vtx->attr[i]; + struct nouveau_array_state *a = &render->attrs[ta->attrib]; + + a->stride = vtx->vertex_size; + a->offset = ta->vertoffset; + } + + TAG(render_set_format)(ctx); +} + +static void +swtnl_alloc_vertices(GLcontext *ctx) +{ + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; + + nouveau_bo_ref(NULL, &swtnl->vbo); + swtnl->buf = get_scratch_vbo(ctx, RENDER_SCRATCH_SIZE, + &swtnl->vbo, NULL); + swtnl->vertex_count = 0; +} + +static void +swtnl_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_swtnl_state *swtnl = &render->swtnl; + int i; + + for (i = 0; i < render->attr_count; i++) { + int attr = render->map[i]; + + if (attr >= 0) + nouveau_bo_ref(swtnl->vbo, + &render->attrs[attr].bo); + } + + TAG(render_bind_vertices)(ctx); +} + +static void +swtnl_unbind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + for (i = 0; i < render->attr_count; i++) { + int *attr = &render->map[i]; + + if (*attr >= 0) { + nouveau_bo_ref(NULL, &render->attrs[*attr].bo); + *attr = -1; + } + } + + render->attr_count = 0; +} + +static void +swtnl_flush_vertices(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; + unsigned push, start = 0, count = swtnl->vertex_count; + RENDER_LOCALS(ctx); + + swtnl_bind_vertices(ctx); + + while (count) { + push = get_max_vertices(ctx, NULL, chan->pushbuf->remaining); + push = MIN2(push / 12 * 12, count); + count -= push; + + if (!push) { + FIRE_RING(chan); + continue; + } + + BATCH_BEGIN(nvgl_primitive(swtnl->primitive)); + EMIT_VBO(L, ctx, start, 0, push); + BATCH_END(); + + FIRE_RING(chan); + } + + swtnl_alloc_vertices(ctx); +} + +/* TnL renderer entry points */ + +static void +swtnl_start(GLcontext *ctx) +{ + swtnl_choose_attrs(ctx); +} + +static void +swtnl_finish(GLcontext *ctx) +{ + swtnl_flush_vertices(ctx); + swtnl_unbind_vertices(ctx); +} + +static void +swtnl_primitive(GLcontext *ctx, GLenum mode) +{ +} + +static void +swtnl_reset_stipple(GLcontext *ctx) +{ +} + +/* Primitive rendering */ + +#define BEGIN_PRIMITIVE(p, n) \ + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; \ + int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size; \ + \ + if (swtnl->vertex_count + (n) > swtnl->vbo->size/vertex_len \ + || (swtnl->vertex_count && swtnl->primitive != p)) \ + swtnl_flush_vertices(ctx); \ + \ + swtnl->primitive = p; + +#define OUT_VERTEX(i) do { \ + memcpy(swtnl->buf + swtnl->vertex_count * vertex_len, \ + _tnl_get_vertex(ctx, (i)), vertex_len); \ + swtnl->vertex_count++; \ + } while (0) + +static void +swtnl_points(GLcontext *ctx, GLuint first, GLuint last) +{ + int i, count; + + while (first < last) { + BEGIN_PRIMITIVE(GL_POINTS, last - first); + + count = MIN2(swtnl->vbo->size / vertex_len, last - first); + for (i = 0; i < count; i++) + OUT_VERTEX(first + i); + + first += count; + } +} + +static void +swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2) +{ + BEGIN_PRIMITIVE(GL_LINES, 2); + OUT_VERTEX(v1); + OUT_VERTEX(v2); +} + +static void +swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3) +{ + BEGIN_PRIMITIVE(GL_TRIANGLES, 3); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); +} + +static void +swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4) +{ + BEGIN_PRIMITIVE(GL_QUADS, 4); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + OUT_VERTEX(v4); +} + +/* TnL initialization. */ +static void +TAG(swtnl_init)(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + + tnl->Driver.Render.Start = swtnl_start; + tnl->Driver.Render.Finish = swtnl_finish; + tnl->Driver.Render.PrimitiveNotify = swtnl_primitive; + tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple; + + tnl->Driver.Render.Points = swtnl_points; + tnl->Driver.Render.Line = swtnl_line; + tnl->Driver.Render.Triangle = swtnl_triangle; + tnl->Driver.Render.Quad = swtnl_quad; + + _tnl_init_vertices(ctx, tnl->vb.Size, + NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat)); + _tnl_need_projected_coords(ctx, GL_FALSE); + _tnl_allow_vertex_fog(ctx, GL_FALSE); + _tnl_wakeup(ctx); + + swtnl_alloc_vertices(ctx); +} + +static void +TAG(swtnl_destroy)(GLcontext *ctx) +{ + nouveau_bo_ref(NULL, &to_render_state(ctx)->swtnl.vbo); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c new file mode 100644 index 0000000000..ab6e93cceb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" + +#include "main/texobj.h" +#include "main/texstore.h" +#include "main/texformat.h" +#include "main/texcompress.h" +#include "main/texgetimage.h" +#include "main/mipmap.h" +#include "main/texfetch.h" + +static struct gl_texture_object * +nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target) +{ + struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture); + + _mesa_initialize_texture_object(&nt->base, name, target); + + return &nt->base; +} + +static void +nouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_texture *nt = to_nouveau_texture(t); + int i; + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + nouveau_surface_ref(NULL, &nt->surfaces[i]); + + _mesa_delete_texture_object(ctx, t); +} + +static struct gl_texture_image * +nouveau_teximage_new(GLcontext *ctx) +{ + struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage); + + return &nti->base; +} + +static void +nouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_teximage *nti = to_nouveau_teximage(ti); + + nouveau_surface_ref(NULL, &nti->surface); +} + +static void +nouveau_teximage_map(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + int ret; + + ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); + assert(!ret); + + ti->Data = s->bo->map; +} + +static void +nouveau_teximage_unmap(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + + nouveau_bo_unmap(s->bo); + ti->Data = NULL; +} + +static gl_format +nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType) +{ + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + case GL_RGBA8: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return MESA_FORMAT_ARGB8888; + case GL_RGB5_A1: + return MESA_FORMAT_ARGB1555; + case GL_RGBA2: + case GL_RGBA4: + return MESA_FORMAT_ARGB4444; + + case 3: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + return MESA_FORMAT_RGB565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_ALPHA8: + return MESA_FORMAT_A8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_LUMINANCE8: + return MESA_FORMAT_L8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_LUMINANCE8_ALPHA8: + return MESA_FORMAT_ARGB8888; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_INTENSITY8: + return MESA_FORMAT_ARGB8888; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + case GL_COLOR_INDEX8_EXT: + return MESA_FORMAT_CI8; + + default: + assert(0); + } +} + +static void +nouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + unsigned bo_flags = NOUVEAU_BO_GART | NOUVEAU_BO_RDWR | NOUVEAU_BO_MAP; + int ret; + + /* Allocate a new bo for the image. */ + nouveau_surface_alloc(ctx, s, LINEAR, bo_flags, ti->TexFormat, + width, height); + ti->RowStride = s->pitch / s->cpp; + + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, + format, type, pixels, packing, + "glTexImage"); + if (!pixels) + return; + + /* Store the pixel data. */ + nouveau_teximage_map(ctx, ti); + + ret = _mesa_texstore(ctx, dims, ti->_BaseFormat, + ti->TexFormat, ti->Data, + 0, 0, 0, s->pitch, + ti->ImageOffsets, + width, height, depth, + format, type, pixels, packing); + assert(ret); + + nouveau_teximage_unmap(ctx, ti); + _mesa_unmap_teximage_pbo(ctx, packing); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_teximage_1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 1, target, level, internalFormat, + width, 1, 1, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_teximage_2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 2, target, level, internalFormat, + width, height, 1, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_teximage_3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 3, target, level, internalFormat, + width, height, depth, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_texsubimage_3d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_texsubimage_2d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_texsubimage_1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint width, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage1d(ctx, target, level, xoffset, + width, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_get_teximage(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_get_teximage(ctx, target, level, format, type, pixels, + t, ti); + nouveau_teximage_unmap(ctx, ti); +} + +static void +nouveau_bind_texture(GLcontext *ctx, GLenum target, + struct gl_texture_object *t) +{ + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); +} + +static void +nouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t) +{ + int i; + + for (i = t->BaseLevel; i < t->_MaxLevel; i++) { + if (t->Image[0][i]) + nouveau_teximage_map(ctx, t->Image[0][i]); + } +} + +static void +nouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t) +{ + int i; + + for (i = t->BaseLevel; i < t->_MaxLevel; i++) { + if (t->Image[0][i]) + nouveau_teximage_unmap(ctx, t->Image[0][i]); + } +} + +static void +relayout_miptree(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces; + unsigned last_level, offset = 0; + unsigned size; + int i, ret; + + if (t->MinFilter == GL_NEAREST || + t->MinFilter == GL_LINEAR) + last_level = t->BaseLevel; + else + last_level = t->_MaxLevel; + + /* Deallocate the old storage. */ + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + nouveau_bo_ref(NULL, &ss[i].bo); + + /* Relayout the mipmap tree. */ + for (i = t->BaseLevel; i <= last_level; i++) { + struct nouveau_surface *s = + &to_nouveau_teximage(t->Image[0][i])->surface; + + size = s->width * s->height * s->cpp; + + /* Images larger than 16B have to be aligned. */ + if (size > 16) + offset = align(offset, 64); + + ss[i] = (struct nouveau_surface) { + .offset = offset, + .layout = SWIZZLED, + .format = s->format, + .width = s->width, + .height = s->height, + .cpp = s->cpp, + .pitch = s->width * s->cpp, + }; + + offset += size; + } + + /* Get new storage. */ + size = align(offset, 64); + + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM, + 0, size, &ss[last_level].bo); + assert(!ret); + + for (i = t->BaseLevel; i < last_level; i++) + nouveau_bo_ref(ss[last_level].bo, &ss[i].bo); +} + +void +nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_texture *nt = to_nouveau_texture(t); + int i; + + if (!nt->dirty) + return; + + nt->dirty = GL_FALSE; + + relayout_miptree(ctx, t); + + /* Copy the teximages to the actual swizzled miptree. */ + for (i = t->BaseLevel; i < MAX_TEXTURE_LEVELS; i++) { + struct gl_texture_image *ti = t->Image[0][i]; + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + + if (!nt->surfaces[i].bo) + break; + + context_drv(ctx)->surface_copy(ctx, &nt->surfaces[i], s, + 0, 0, 0, 0, + s->width, s->height); + } +} + +void +nouveau_texture_functions_init(struct dd_function_table *functions) +{ + functions->NewTextureObject = nouveau_texture_new; + functions->DeleteTexture = nouveau_texture_free; + functions->NewTextureImage = nouveau_teximage_new; + functions->FreeTexImageData = nouveau_teximage_free; + functions->ChooseTextureFormat = nouveau_choose_tex_format; + functions->TexImage1D = nouveau_teximage_1d; + functions->TexImage2D = nouveau_teximage_2d; + functions->TexImage3D = nouveau_teximage_3d; + functions->TexSubImage1D = nouveau_texsubimage_1d; + functions->TexSubImage2D = nouveau_texsubimage_2d; + functions->TexSubImage3D = nouveau_texsubimage_3d; + functions->GetTexImage = nouveau_get_teximage; + functions->BindTexture = nouveau_bind_texture; + functions->MapTexture = nouveau_texture_map; + functions->UnmapTexture = nouveau_texture_unmap; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.h b/src/mesa/drivers/dri/nouveau/nouveau_texture.h new file mode 100644 index 0000000000..695c0897b5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_TEXTURE_H__ +#define __NOUVEAU_TEXTURE_H__ + +struct nouveau_teximage { + struct gl_texture_image base; + struct nouveau_surface surface; +}; +#define to_nouveau_teximage(x) ((struct nouveau_teximage *)(x)) + +struct nouveau_texture { + struct gl_texture_object base; + struct nouveau_surface surfaces[MAX_TEXTURE_LEVELS]; + GLboolean dirty; +}; +#define to_nouveau_texture(x) ((struct nouveau_texture *)(x)) + +#define texture_dirty(t) \ + to_nouveau_texture(t)->dirty = GL_TRUE; + +void +nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_util.h b/src/mesa/drivers/dri/nouveau/nouveau_util.h new file mode 100644 index 0000000000..076f225fed --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_util.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NOUVEAU_UTIL_H__ +#define __NOUVEAU_UTIL_H__ + +#include "main/formats.h" +#include "main/colormac.h" + +static inline unsigned +pack_rgba_i(gl_format f, uint8_t c[]) +{ + switch (f) { + case MESA_FORMAT_ARGB8888: + return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]); + case MESA_FORMAT_ARGB8888_REV: + return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]); + case MESA_FORMAT_XRGB8888: + return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]); + case MESA_FORMAT_XRGB8888_REV: + return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0); + case MESA_FORMAT_RGBA8888: + return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]); + case MESA_FORMAT_RGBA8888_REV: + return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]); + case MESA_FORMAT_RGB565: + return PACK_COLOR_565(c[RCOMP], c[GCOMP], c[BCOMP]); + default: + assert(0); + } +} + +static inline unsigned +pack_zs_i(gl_format f, uint32_t z, uint8_t s) +{ + switch (f) { + case MESA_FORMAT_Z24_S8: + return (z & 0xffffff00) | (s & 0xff); + case MESA_FORMAT_Z24_X8: + return (z & 0xffffff00); + case MESA_FORMAT_Z16: + return (z & 0xffff0000) >> 16; + default: + assert(0); + } +} + +static inline unsigned +pack_rgba_f(gl_format f, float c[]) +{ + return pack_rgba_i(f, (uint8_t []) { + FLOAT_TO_UBYTE(c[RCOMP]), + FLOAT_TO_UBYTE(c[GCOMP]), + FLOAT_TO_UBYTE(c[BCOMP]), + FLOAT_TO_UBYTE(c[ACOMP]) }); +} + +static inline unsigned +pack_zs_f(gl_format f, float z, uint8_t s) +{ + return pack_zs_i(f, FLOAT_TO_UINT(z), s); +} + +/* Integer base-2 logarithm, rounded towards zero. */ +static inline unsigned +log2i(unsigned i) +{ + unsigned r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +static inline unsigned +align(unsigned x, unsigned m) +{ + return (x + m - 1) & ~(m - 1); +} + +static inline void +get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h) +{ + *w = fb->_Xmax - fb->_Xmin; + *h = fb->_Ymax - fb->_Ymin; + *x = fb->_Xmin; + *y = (fb->Name ? fb->_Ymin : + /* Window system FBO: Flip the Y coordinate. */ + fb->Height - fb->_Ymax); +} + +static inline void +get_viewport_scale(GLcontext *ctx, float a[16]) +{ + struct gl_viewport_attrib *vp = &ctx->Viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + a[MAT_SX] = (float)vp->Width / 2; + + if (fb->Name) + a[MAT_SY] = (float)vp->Height / 2; + else + /* Window system FBO: Flip the Y coordinate. */ + a[MAT_SY] = - (float)vp->Height / 2; + + a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2; +} + +static inline void +get_viewport_translate(GLcontext *ctx, float a[4]) +{ + struct gl_viewport_attrib *vp = &ctx->Viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + a[0] = (float)vp->Width / 2 + vp->X; + + if (fb->Name) + a[1] = (float)vp->Height / 2 + vp->Y; + else + /* Window system FBO: Flip the Y coordinate. */ + a[1] = fb->Height - (float)vp->Height / 2 - vp->Y; + + a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2; +} + +static inline void +OUT_RINGm(struct nouveau_channel *chan, float m[16]) +{ + int i, j; + + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m[4*j + i]); +} + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c new file mode 100644 index 0000000000..ba1192a170 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "main/bufferobj.h" +#include "nouveau_bufferobj.h" + +/* Arbitrary pushbuf length we can assume we can get with a single + * WAIT_RING. */ +#define PUSHBUF_DWORDS 2048 + +/* Functions to set up struct nouveau_array_state from something like + * a GL array or index buffer. */ + +static void +vbo_init_array(struct nouveau_array_state *a, int attr, int stride, + int fields, int type, struct gl_buffer_object *obj, + const void *ptr, GLboolean map) +{ + a->attr = attr; + a->stride = stride; + a->fields = fields; + a->type = type; + + if (_mesa_is_bufferobj(obj)) { + nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &a->bo); + a->offset = (intptr_t)ptr; + + if (map) { + nouveau_bo_map(a->bo, NOUVEAU_BO_RD); + a->buf = a->bo->map + a->offset; + } else { + a->buf = NULL; + } + + } else { + nouveau_bo_ref(NULL, &a->bo); + a->offset = 0; + a->buf = ptr; + } + + if (a->buf) + get_array_extract(a, &a->extract_u, &a->extract_f); +} + +static void +vbo_deinit_array(struct nouveau_array_state *a) +{ + if (a->bo) { + if (a->bo->map) + nouveau_bo_unmap(a->bo); + nouveau_bo_ref(NULL, &a->bo); + } + + a->buf = NULL; + a->fields = 0; +} + +static void +vbo_init_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib, + const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + if (ib) + vbo_init_array(&render->ib, 0, 0, ib->count, ib->type, + ib->obj, ib->ptr, GL_TRUE); + + for (i = 0; i < render->attr_count; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + const struct gl_client_array *array = arrays[attr]; + + vbo_init_array(&render->attrs[attr], attr, + array->StrideB, array->Size, + array->Type, array->BufferObj, + array->Ptr, render->mode == IMM); + } + } +} + +static void +vbo_deinit_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib, + const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + if (ib) + vbo_deinit_array(&render->ib); + + for (i = 0; i < render->attr_count; i++) { + int *attr = &render->map[i]; + + if (*attr >= 0) { + vbo_deinit_array(&render->attrs[*attr]); + *attr = -1; + } + } + + render->attr_count = 0; +} + +/* Make some rendering decisions from the GL context. */ + +static void +vbo_choose_render_mode(GLcontext *ctx, const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + render->mode = VBO; + + if (ctx->Light.Enabled) { + for (i = 0; i < MAT_ATTRIB_MAX; i++) { + if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) { + render->mode = IMM; + break; + } + } + } + + if (render->mode == VBO) + render->attr_count = NUM_VERTEX_ATTRS; + else + render->attr_count = 0; +} + +static void +vbo_emit_attr(GLcontext *ctx, const struct gl_client_array **arrays, int attr) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_render_state *render = to_render_state(ctx); + const struct gl_client_array *array = arrays[attr]; + struct nouveau_array_state *a = &render->attrs[attr]; + RENDER_LOCALS(ctx); + + if (!array->StrideB) { + if (attr >= VERT_ATTRIB_GENERIC0) + /* nouveau_update_state takes care of materials. */ + return; + + /* Constant attribute. */ + vbo_init_array(a, attr, array->StrideB, array->Size, + array->Type, array->BufferObj, array->Ptr, + GL_TRUE); + EMIT_IMM(ctx, a, 0); + vbo_deinit_array(a); + + } else { + /* Varying attribute. */ + struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr]; + + if (render->mode == VBO) { + render->map[info->vbo_index] = attr; + render->vertex_size += array->_ElementSize; + } else { + render->map[render->attr_count++] = attr; + render->vertex_size += 4 * info->imm_fields; + } + } +} + +#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a) + +static void +vbo_choose_attrs(GLcontext *ctx, const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + /* Reset the vertex size. */ + render->vertex_size = 0; + + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0); + if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1); + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture._EnabledCoordUnits & (1 << i)) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i); + } + + if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG); + + if (ctx->Light.Enabled) { + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL); + + vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS)); + + if (ctx->Light.Model.TwoSide) { + vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT)); + vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE)); + vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR)); + vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS)); + } + } + + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS); +} + +static void +TAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index); + +static GLboolean +vbo_maybe_split(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, GLuint max_index) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * nctx->bo.count, + vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail), + idx_avail = get_max_vertices(ctx, ib, pushbuf_avail); + + if ((ib && ib->count > idx_avail) || + (!ib && max_index - min_index > vert_avail)) { + struct split_limits limits = { + .max_verts = vert_avail, + .max_indices = idx_avail, + .max_vb_size = ~0, + }; + + vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index, + max_index, TAG(vbo_render_prims), &limits); + return GL_TRUE; + } + + return GL_FALSE; +} + +/* VBO rendering path. */ + +static void +vbo_bind_vertices(GLcontext *ctx, const struct gl_client_array **arrays, + GLint basevertex, GLuint min_index, GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + const struct gl_client_array *array = arrays[attr]; + struct nouveau_array_state *a = &render->attrs[attr]; + unsigned delta = (basevertex + min_index) * a->stride, + size = (max_index - min_index + 1) * a->stride; + + if (a->bo) { + a->offset = (intptr_t)array->Ptr + delta; + } else { + void *scratch = get_scratch_vbo(ctx, size, + &a->bo, + &a->offset); + + memcpy(scratch, a->buf + delta, size); + } + } + } + + TAG(render_bind_vertices)(ctx); +} + +static void +vbo_draw_vbo(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, GLuint min_index, + GLuint max_index) +{ + struct nouveau_channel *chan = context_chan(ctx); + dispatch_t dispatch; + int delta = -min_index, basevertex = 0, i; + RENDER_LOCALS(ctx); + + get_array_dispatch(&to_render_state(ctx)->ib, &dispatch); + + TAG(render_set_format)(ctx); + + for (i = 0; i < nr_prims; i++) { + unsigned start = prims[i].start, + count = prims[i].count; + + if (i == 0 || basevertex != prims[i].basevertex) { + basevertex = prims[i].basevertex; + vbo_bind_vertices(ctx, arrays, basevertex, + min_index, max_index); + } + + if (count > get_max_vertices(ctx, ib, chan->pushbuf->remaining)) + WAIT_RING(chan, PUSHBUF_DWORDS); + + BATCH_BEGIN(nvgl_primitive(prims[i].mode)); + dispatch(ctx, start, delta, count); + BATCH_END(); + } + + FIRE_RING(chan); +} + +/* Immediate rendering path. */ + +static unsigned +extract_id(struct nouveau_array_state *a, int i, int j) +{ + return j; +} + +static void +vbo_draw_imm(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, GLuint min_index, + GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + extract_u_t extract = ib ? render->ib.extract_u : extract_id; + int i, j, k; + RENDER_LOCALS(ctx); + + for (i = 0; i < nr_prims; i++) { + unsigned start = prims[i].start, + end = start + prims[i].count; + + if (prims[i].count > get_max_vertices(ctx, ib, + chan->pushbuf->remaining)) + WAIT_RING(chan, PUSHBUF_DWORDS); + + BATCH_BEGIN(nvgl_primitive(prims[i].mode)); + + for (; start < end; start++) { + j = prims[i].basevertex + + extract(&render->ib, 0, start); + + for (k = 0; k < render->attr_count; k++) + EMIT_IMM(ctx, &render->attrs[render->map[k]], + j); + } + + BATCH_END(); + } + + FIRE_RING(chan); +} + +/* draw_prims entry point when we're doing hw-tnl. */ + +static void +TAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + + if (!index_bounds_valid) + vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); + + vbo_choose_render_mode(ctx, arrays); + vbo_choose_attrs(ctx, arrays); + + if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index, + max_index)) + return; + + vbo_init_arrays(ctx, ib, arrays); + + if (render->mode == VBO) + vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index, + max_index); + else + vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index, + max_index); + + vbo_deinit_arrays(ctx, ib, arrays); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.c b/src/mesa/drivers/dri/nouveau/nv04_context.c new file mode 100644 index 0000000000..5548286a73 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_context.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +struct nouveau_grobj * +nv04_context_engine(GLcontext *ctx) +{ + struct nv04_context *nctx = to_nv04_context(ctx); + struct nouveau_screen *screen = nctx->base.screen; + struct nouveau_grobj *fahrenheit; + + if (ctx->Texture.Unit[0].EnvMode == GL_COMBINE || + ctx->Texture.Unit[0].EnvMode == GL_BLEND || + ctx->Texture.Unit[1]._ReallyEnabled || + ctx->Stencil.Enabled) + fahrenheit = screen->eng3dm; + else + fahrenheit = screen->eng3d; + + if (fahrenheit != nctx->eng3d) { + nctx->eng3d = fahrenheit; + + if (nv04_mtex_engine(fahrenheit)) { + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + } else { + context_bctx_i(ctx, TEXTURE, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + } + } + + return fahrenheit; +} + +static void +init_dummy_texture(GLcontext *ctx) +{ + struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture; + + nouveau_surface_alloc(ctx, s, SWIZZLED, + NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM, + MESA_FORMAT_ARGB8888, 1, 1); + + nouveau_bo_map(s->bo, NOUVEAU_BO_WR); + *(uint32_t *)s->bo->map = 0xffffffff; + nouveau_bo_unmap(s->bo); +} + +GLcontext * +nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nv04_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nv04_context); + if (!nctx) + return NULL; + + ctx = &nctx->base.base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2; + ctx->Const.MaxTextureLodBias = 15; + + init_dummy_texture(ctx); + nv04_render_init(ctx); + + return ctx; +} + +void +nv04_context_destroy(GLcontext *ctx) +{ + nv04_render_destroy(ctx); + nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture); + + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.h b/src/mesa/drivers/dri/nouveau/nv04_context.h new file mode 100644 index 0000000000..ed4eec9865 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_context.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NV04_CONTEXT_H__ +#define __NV04_CONTEXT_H__ + +#include "nouveau_context.h" + +struct nv04_context { + struct nouveau_context base; + struct nouveau_grobj *eng3d; + struct nouveau_surface dummy_texture; + float viewport[16]; +}; +#define to_nv04_context(ctx) ((struct nv04_context *)(ctx)) + +#define nv04_mtex_engine(obj) ((obj)->grclass == NV04_MULTITEX_TRIANGLE) + +struct nouveau_grobj * +nv04_context_engine(GLcontext *ctx); + +GLcontext * +nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv04_context_destroy(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv04_driver.h b/src/mesa/drivers/dri/nouveau/nv04_driver.h new file mode 100644 index 0000000000..00668710ac --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_driver.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NV04_DRIVER_H__ +#define __NV04_DRIVER_H__ + +#include "nv04_context.h" + +enum { + NOUVEAU_STATE_BLEND = NUM_NOUVEAU_STATE, + NOUVEAU_STATE_CONTROL, + NUM_NV04_STATE +}; + +#define NV04_TEXTURE_UNITS 2 + +/* nv04_screen.c */ +GLboolean +nv04_screen_init(struct nouveau_screen *screen); + +/* nv04_render.c */ +void +nv04_render_init(GLcontext *ctx); + +void +nv04_render_destroy(GLcontext *ctx); + +/* nv04_surface.c */ +GLboolean +nv04_surface_init(struct nouveau_screen *screen); + +void +nv04_surface_takedown(struct nouveau_screen *screen); + +void +nv04_surface_copy(GLcontext *ctx, + struct nouveau_surface *dst, struct nouveau_surface *src, + int dx, int dy, int sx, int sy, int w, int h); + +void +nv04_surface_fill(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h); + +/* nv04_state_fb.c */ +void +nv04_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv04_emit_scissor(GLcontext *ctx, int emit); + +/* nv04_state_raster.c */ +void +nv04_defer_control(GLcontext *ctx, int emit); + +void +nv04_emit_control(GLcontext *ctx, int emit); + +void +nv04_defer_blend(GLcontext *ctx, int emit); + +void +nv04_emit_blend(GLcontext *ctx, int emit); + +/* nv04_state_frag.c */ +void +nv04_emit_tex_env(GLcontext *ctx, int emit); + +/* nv04_state_tex.c */ +void +nv04_emit_tex_obj(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv04_render.c b/src/mesa/drivers/dri/nouveau/nv04_render.c new file mode 100644 index 0000000000..b5943d9987 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_render.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#define NUM_VERTEX_ATTRS 6 + +static void +swtnl_update_viewport(GLcontext *ctx) +{ + float *viewport = to_nv04_context(ctx)->viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + get_viewport_scale(ctx, viewport); + get_viewport_translate(ctx, &viewport[MAT_TX]); + + /* It wants normalized Z coordinates. */ + viewport[MAT_SZ] /= fb->_DepthMaxF; + viewport[MAT_TZ] /= fb->_DepthMaxF; +} + +static void +swtnl_emit_attr(GLcontext *ctx, struct tnl_attr_map *m, int attr, int emit) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, attr)) + *m = (struct tnl_attr_map) { + .attrib = attr, + .format = emit, + }; + else + *m = (struct tnl_attr_map) { + .format = EMIT_PAD, + .offset = _tnl_format_info[emit].attrsize, + }; +} + +static void +swtnl_choose_attrs(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct nv04_context *nctx = to_nv04_context(ctx); + static struct tnl_attr_map map[NUM_VERTEX_ATTRS]; + int n = 0; + + tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.NdcPtr; + + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_FOG, EMIT_1UB_1F); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX0, EMIT_2F); + if (nv04_mtex_engine(fahrenheit)) + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX1, EMIT_2F); + + swtnl_update_viewport(ctx); + + _tnl_install_attrs(ctx, map, n, nctx->viewport, 0); +} + +/* TnL renderer entry points */ + +static void +swtnl_start(GLcontext *ctx) +{ + swtnl_choose_attrs(ctx); +} + +static void +swtnl_finish(GLcontext *ctx) +{ + FIRE_RING(context_chan(ctx)); +} + +static void +swtnl_primitive(GLcontext *ctx, GLenum mode) +{ +} + +static void +swtnl_reset_stipple(GLcontext *ctx) +{ +} + +/* Primitive rendering */ + +#define BEGIN_PRIMITIVE(n) \ + struct nouveau_channel *chan = context_chan(ctx); \ + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); \ + int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4; \ + \ + if (nv04_mtex_engine(fahrenheit)) \ + BEGIN_RING(chan, fahrenheit, \ + NV04_MULTITEX_TRIANGLE_TLMTVERTEX_SX(0), \ + n * vertex_len); \ + else \ + BEGIN_RING(chan, fahrenheit, \ + NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0), \ + n * vertex_len); \ + +#define OUT_VERTEX(i) \ + OUT_RINGp(chan, _tnl_get_vertex(ctx, i), vertex_len); + +#define END_PRIMITIVE(draw) \ + if (nv04_mtex_engine(fahrenheit)) { \ + BEGIN_RING(chan, fahrenheit, \ + NV04_MULTITEX_TRIANGLE_DRAWPRIMITIVE(0), 1); \ + OUT_RING(chan, draw); \ + } else { \ + BEGIN_RING(chan, fahrenheit, \ + NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), 1); \ + OUT_RING(chan, draw); \ + } + +static void +swtnl_points(GLcontext *ctx, GLuint first, GLuint last) +{ +} + +static void +swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2) +{ +} + +static void +swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3) +{ + BEGIN_PRIMITIVE(3); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + END_PRIMITIVE(0x210); +} + +static void +swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4) +{ + BEGIN_PRIMITIVE(4); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + OUT_VERTEX(v4); + END_PRIMITIVE(0x320210); +} + +/* TnL initialization. */ +void +nv04_render_init(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + + tnl->Driver.Render.Start = swtnl_start; + tnl->Driver.Render.Finish = swtnl_finish; + tnl->Driver.Render.PrimitiveNotify = swtnl_primitive; + tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple; + + tnl->Driver.Render.Points = swtnl_points; + tnl->Driver.Render.Line = swtnl_line; + tnl->Driver.Render.Triangle = swtnl_triangle; + tnl->Driver.Render.Quad = swtnl_quad; + + _tnl_need_projected_coords(ctx, GL_TRUE); + _tnl_init_vertices(ctx, tnl->vb.Size, + NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat)); + _tnl_allow_pixel_fog(ctx, GL_FALSE); + _tnl_wakeup(ctx); +} + +void +nv04_render_destroy(GLcontext *ctx) +{ +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_screen.c b/src/mesa/drivers/dri/nouveau/nv04_screen.c new file mode 100644 index 0000000000..0fc0f4c391 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_screen.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static const struct nouveau_driver nv04_driver; + +static void +nv04_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *surf3d = screen->surf3d; + struct nouveau_grobj *eng3d = screen->eng3d; + struct nouveau_grobj *eng3dm = screen->eng3dm; + + BIND_RING(chan, surf3d, 7); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, eng3d, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + BEGIN_RING(chan, eng3dm, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + FIRE_RING(chan); +} + +static void +nv04_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_screen *screen = chan->user_private; + struct nouveau_context *nctx = screen->context; + + if (nctx && nctx->fallback < SWRAST) { + GLcontext *ctx = &nctx->base; + + /* Flushing seems to clobber the engine context. */ + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + + nouveau_state_emit(ctx); + } +} + +GLboolean +nv04_screen_init(struct nouveau_screen *screen) +{ + int ret; + + screen->driver = &nv04_driver; + screen->chan->flush_notify = nv04_channel_flush_notify; + + /* 2D engine. */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, + NV04_TEXTURED_TRIANGLE, &screen->eng3d); + if (ret) + return GL_FALSE; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0002, + NV04_MULTITEX_TRIANGLE, &screen->eng3dm); + if (ret) + return GL_FALSE; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0003, + NV04_CONTEXT_SURFACES_3D, &screen->surf3d); + if (ret) + return GL_FALSE; + + nv04_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv04_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + if (screen->eng3dm) + nouveau_grobj_free(&screen->eng3dm); + + if (screen->surf3d) + nouveau_grobj_free(&screen->surf3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv04_driver = { + .screen_destroy = nv04_screen_destroy, + .context_create = nv04_context_create, + .context_destroy = nv04_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_blend, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nv04_defer_control, + nouveau_emit_nothing, + nv04_emit_framebuffer, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_scissor, + nv04_defer_blend, + nv04_defer_control, + nv04_defer_control, + nv04_defer_control, + nv04_emit_tex_env, + nv04_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_tex_obj, + nv04_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_blend, + nv04_emit_control, + }, + .num_emit = NUM_NV04_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_fb.c b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c new file mode 100644 index 0000000000..e97eb2a03b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + default: + assert(0); + } +} + +void +nv04_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf3d = screen->surf3d; + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + uint32_t rt_format = NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_PITCH; + uint32_t rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, surf3d, + NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, surf3d, + NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, + s->bo, 0, bo_flags); + } + + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + OUT_RING(chan, rt_format); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_PITCH, 1); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + /* Recompute the scissor state. */ + context_dirty(ctx, SCISSOR); +} + +void +nv04_emit_scissor(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf3d = screen->surf3d; + int x, y, w, h; + + get_scissors(ctx->DrawBuffer, &x, &y, &w, &h); + + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING(chan, w << 16 | x); + OUT_RING(chan, h << 16 | y); + + /* Messing with surf3d invalidates some engine state. */ + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_frag.c b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c new file mode 100644 index 0000000000..34ee296202 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +#define COMBINER_SHIFT(in) \ + (NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##_SHIFT \ + - NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_SHIFT) +#define COMBINER_SOURCE(reg) \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_##reg +#define COMBINER_INVERT \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_INVERSE0 +#define COMBINER_ALPHA \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ALPHA0 + +struct combiner_state { + int unit; + GLboolean alpha; + + /* GL state */ + GLenum mode; + GLenum *source; + GLenum *operand; + GLuint logscale; + + /* Derived HW state */ + uint32_t hw; +}; + +#define __INIT_COMBINER_ALPHA_A GL_TRUE +#define __INIT_COMBINER_ALPHA_RGB GL_FALSE + +/* Initialize a combiner_state struct from the texture unit + * context. */ +#define INIT_COMBINER(chan, rc, i) do { \ + struct gl_tex_env_combine_state *c = \ + ctx->Texture.Unit[i]._CurrentCombine; \ + (rc)->alpha = __INIT_COMBINER_ALPHA_##chan; \ + (rc)->unit = i; \ + (rc)->mode = c->Mode##chan; \ + (rc)->source = c->Source##chan; \ + (rc)->operand = c->Operand##chan; \ + (rc)->logscale = c->ScaleShift##chan; \ + (rc)->hw = 0; \ + } while (0) + +/* Get the combiner source for the specified EXT_texture_env_combine + * argument. */ +static uint32_t +get_arg_source(struct combiner_state *rc, int arg) +{ + switch (rc->source[arg]) { + case GL_TEXTURE: + return rc->unit ? COMBINER_SOURCE(TEXTURE1) : + COMBINER_SOURCE(TEXTURE0); + + case GL_TEXTURE0: + return COMBINER_SOURCE(TEXTURE0); + + case GL_TEXTURE1: + return COMBINER_SOURCE(TEXTURE1); + + case GL_CONSTANT: + return COMBINER_SOURCE(CONSTANT); + + case GL_PRIMARY_COLOR: + return COMBINER_SOURCE(PRIMARY_COLOR); + + case GL_PREVIOUS: + return rc->unit ? COMBINER_SOURCE(PREVIOUS) : + COMBINER_SOURCE(PRIMARY_COLOR); + + default: + assert(0); + } +} + +/* Get the (possibly inverted) combiner input mapping for the + * specified argument. */ +#define INVERT 0x1 + +static uint32_t +get_arg_mapping(struct combiner_state *rc, int arg, int flags) +{ + int map = 0; + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + break; + + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + map |= rc->alpha ? 0 : COMBINER_ALPHA; + break; + } + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + map |= flags & INVERT ? COMBINER_INVERT : 0; + break; + + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + map |= flags & INVERT ? 0 : COMBINER_INVERT; + break; + } + + return map; +} + +/* Bind the combiner input <in> to the combiner source <src>, + * possibly inverted. */ +#define INPUT_SRC(rc, in, src, flags) \ + (rc)->hw |= ((flags & INVERT ? COMBINER_INVERT : 0) | \ + COMBINER_SOURCE(src)) << COMBINER_SHIFT(in) + +/* Bind the combiner input <in> to the EXT_texture_env_combine + * argument <arg>, possibly inverted. */ +#define INPUT_ARG(rc, in, arg, flags) \ + (rc)->hw |= (get_arg_source(rc, arg) | \ + get_arg_mapping(rc, arg, flags)) << COMBINER_SHIFT(in) + +#define UNSIGNED_OP(rc) \ + (rc)->hw |= ((rc)->logscale ? \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_SCALE2 : \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_IDENTITY) +#define SIGNED_OP(rc) \ + (rc)->hw |= ((rc)->logscale ? \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS_SCALE2 : \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS) + +static void +setup_combiner(struct combiner_state *rc) +{ + switch (rc->mode) { + case GL_REPLACE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_SRC(rc, 2, ZERO, 0); + INPUT_SRC(rc, 3, ZERO, 0); + UNSIGNED_OP(rc); + break; + + case GL_MODULATE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_ARG(rc, 1, 1, 0); + INPUT_SRC(rc, 2, ZERO, 0); + INPUT_SRC(rc, 3, ZERO, 0); + UNSIGNED_OP(rc); + break; + + case GL_ADD: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_ARG(rc, 2, 1, 0); + INPUT_SRC(rc, 3, ZERO, INVERT); + UNSIGNED_OP(rc); + break; + + case GL_INTERPOLATE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_ARG(rc, 1, 2, 0); + INPUT_ARG(rc, 2, 1, 0); + INPUT_ARG(rc, 3, 2, INVERT); + UNSIGNED_OP(rc); + break; + + case GL_ADD_SIGNED: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_ARG(rc, 2, 1, 0); + INPUT_SRC(rc, 3, ZERO, INVERT); + SIGNED_OP(rc); + break; + + default: + assert(0); + } +} + +void +nv04_emit_tex_env(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_ENV0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct combiner_state rc_a = {}, rc_c = {}; + + if (!nv04_mtex_engine(fahrenheit)) { + context_dirty(ctx, BLEND); + return; + } + + /* Compute the new combiner state. */ + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INIT_COMBINER(A, &rc_a, i); + setup_combiner(&rc_a); + + INIT_COMBINER(RGB, &rc_c, i); + setup_combiner(&rc_c); + + } else { + if (i == 0) { + INPUT_SRC(&rc_a, 0, PRIMARY_COLOR, 0); + INPUT_SRC(&rc_c, 0, PRIMARY_COLOR, 0); + } else { + INPUT_SRC(&rc_a, 0, PREVIOUS, 0); + INPUT_SRC(&rc_c, 0, PREVIOUS, 0); + } + + INPUT_SRC(&rc_a, 1, ZERO, INVERT); + INPUT_SRC(&rc_c, 1, ZERO, INVERT); + INPUT_SRC(&rc_a, 2, ZERO, 0); + INPUT_SRC(&rc_c, 2, ZERO, 0); + INPUT_SRC(&rc_a, 3, ZERO, 0); + INPUT_SRC(&rc_c, 3, ZERO, 0); + + UNSIGNED_OP(&rc_a); + UNSIGNED_OP(&rc_c); + } + + /* Write the register combiner state out to the hardware. */ + BEGIN_RING(chan, fahrenheit, + NV04_MULTITEX_TRIANGLE_COMBINE_ALPHA(i), 2); + OUT_RING(chan, rc_a.hw); + OUT_RING(chan, rc_c.hw); + + BEGIN_RING(chan, fahrenheit, + NV04_MULTITEX_TRIANGLE_COMBINE_FACTOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Texture.Unit[0].EnvColor)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c new file mode 100644 index 0000000000..5e3788d185 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static unsigned +get_comparison_op(unsigned op) +{ + switch (op) { + case GL_NEVER: + return 0x1; + case GL_LESS: + return 0x2; + case GL_EQUAL: + return 0x3; + case GL_LEQUAL: + return 0x4; + case GL_GREATER: + return 0x5; + case GL_NOTEQUAL: + return 0x6; + case GL_GEQUAL: + return 0x7; + case GL_ALWAYS: + return 0x8; + default: + assert(0); + } +} + +static unsigned +get_stencil_op(unsigned op) +{ + switch (op) { + case GL_KEEP: + return 0x1; + case GL_INCR: + return 0x4; + case GL_DECR: + return 0x5; + case GL_INVERT: + return 0x6; + default: + assert(0); + } +} + +static unsigned +get_texenv_mode(unsigned mode) +{ + switch (mode) { + case GL_REPLACE: + return 0x1; + case GL_ADD: + return 0x2; + case GL_DECAL: + return 0x3; + case GL_MODULATE: + return 0x4; + default: + assert(0); + } +} + +static unsigned +get_blend_func(unsigned func) +{ + switch (func) { + case GL_ZERO: + return 0x1; + case GL_ONE: + return 0x2; + case GL_SRC_COLOR: + return 0x3; + case GL_ONE_MINUS_SRC_COLOR: + return 0x4; + case GL_SRC_ALPHA: + return 0x5; + case GL_ONE_MINUS_SRC_ALPHA: + return 0x6; + case GL_DST_ALPHA: + return 0x7; + case GL_ONE_MINUS_DST_ALPHA: + return 0x8; + case GL_DST_COLOR: + return 0x9; + case GL_ONE_MINUS_DST_COLOR: + return 0xa; + case GL_SRC_ALPHA_SATURATE: + return 0xb; + default: + assert(0); + } +} + +void +nv04_defer_control(GLcontext *ctx, int emit) +{ + context_dirty(ctx, CONTROL); +} + +void +nv04_emit_control(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + + if (nv04_mtex_engine(fahrenheit)) { + int cull_mode = ctx->Polygon.CullFaceMode; + int front_face = ctx->Polygon.FrontFace; + uint32_t ctrl0 = 1 << 30 | + NV04_MULTITEX_TRIANGLE_CONTROL0_ORIGIN; + uint32_t ctrl1 = 0, ctrl2 = 0; + + /* Color mask. */ + if (ctx->Color.ColorMask[0][RCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE; + if (ctx->Color.ColorMask[0][GCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE; + if (ctx->Color.ColorMask[0][BCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE; + if (ctx->Color.ColorMask[0][ACOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE; + + /* Dithering. */ + if (ctx->Color.DitherFlag) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_DITHER_ENABLE; + + /* Cull mode. */ + if (!ctx->Polygon.CullFlag) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_NONE; + else if (cull_mode == GL_FRONT_AND_BACK) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_BOTH; + else + ctrl0 |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ? + NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CW : + NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CCW; + + /* Depth test. */ + if (ctx->Depth.Test) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE; + + if (ctx->Depth.Mask) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_WRITE; + + ctrl0 |= get_comparison_op(ctx->Depth.Func) << 16; + + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_ENABLE; + + ctrl0 |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + + /* Stencil test. */ + if (ctx->Stencil.WriteMask[0]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE; + + if (ctx->Stencil.Enabled) + ctrl1 |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE; + + ctrl1 |= get_comparison_op(ctx->Stencil.Function[0]) << 4 | + ctx->Stencil.Ref[0] << 8 | + ctx->Stencil.ValueMask[0] << 16 | + ctx->Stencil.WriteMask[0] << 24; + + ctrl2 |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 | + get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 | + get_stencil_op(ctx->Stencil.FailFunc[0]); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_CONTROL0, 3); + OUT_RING(chan, ctrl0); + OUT_RING(chan, ctrl1); + OUT_RING(chan, ctrl2); + + } else { + int cull_mode = ctx->Polygon.CullFaceMode; + int front_face = ctx->Polygon.FrontFace; + uint32_t ctrl = 1 << 30 | + NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN; + + /* Dithering. */ + if (ctx->Color.DitherFlag) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; + + /* Cull mode. */ + if (!ctx->Polygon.CullFlag) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE; + else if (cull_mode == GL_FRONT_AND_BACK) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH; + else + ctrl |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ? + NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW : + NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW; + + /* Depth test. */ + if (ctx->Depth.Test) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; + if (ctx->Depth.Mask) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; + + ctrl |= get_comparison_op(ctx->Depth.Func) << 16; + + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; + + ctrl |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(chan, ctrl); + } +} + +void +nv04_defer_blend(GLcontext *ctx, int emit) +{ + context_dirty(ctx, BLEND); +} + +void +nv04_emit_blend(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + + if (nv04_mtex_engine(fahrenheit)) { + uint32_t blend = 0x2 << 4 | + NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + + /* Alpha blending. */ + blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 | + get_blend_func(ctx->Color.BlendSrcRGB) << 24; + + if (ctx->Color.BlendEnabled) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_BLEND_ENABLE; + + /* Shade model. */ + if (ctx->Light.ShadeModel == GL_SMOOTH) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + else + blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_FLAT; + + /* Fog. */ + if (ctx->Fog.Enabled) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE; + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_BLEND, 1); + OUT_RING(chan, blend); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FOGCOLOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Fog.Color)); + + } else { + uint32_t blend = 0x2 << 4 | + NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + + /* Alpha blending. */ + blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 | + get_blend_func(ctx->Color.BlendSrcRGB) << 24; + + if (ctx->Color.BlendEnabled) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE; + + /* Shade model. */ + if (ctx->Light.ShadeModel == GL_SMOOTH) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + else + blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT; + + /* Texture environment. */ + blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode); + + /* Fog. */ + if (ctx->Fog.Enabled) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING(chan, blend); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Fog.Color)); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_tex.c b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c new file mode 100644 index 0000000000..99ea310c65 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_Y8; + case MESA_FORMAT_ARGB1555: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A1R5G5B5; + case MESA_FORMAT_ARGB4444: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A4R4G4B4; + case MESA_FORMAT_RGB565: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_R5G6B5; + case MESA_FORMAT_ARGB8888: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; + default: + assert(0); + } +} + +static inline unsigned +get_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return 0x3; + case GL_CLAMP_TO_BORDER: + return 0x4; + default: + assert(0); + } +} + +void +nv04_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct nouveau_surface *s; + uint32_t format = 0xa0, filter = 0x1010; + + if (i && !nv04_mtex_engine(fahrenheit)) + return; + + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *t = ctx->Texture.Unit[i]._Current; + struct gl_texture_image *ti = t->Image[0][t->BaseLevel]; + int lod_max = 1, lod_bias = 0; + + nouveau_texture_validate(ctx, t); + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + lod_max = CLAMP(MIN2(t->MaxLod, t->_MaxLambda), + 0, 15) + 1; + + lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias + + t->LodBias, 0, 15); + } + + format |= get_wrap_mode(t->WrapT) << 28 | + get_wrap_mode(t->WrapS) << 24 | + ti->HeightLog2 << 20 | + ti->WidthLog2 << 16 | + lod_max << 12 | + get_tex_format(ti); + + filter |= log2i(t->MaxAnisotropy) << 31 | + nvgl_filter_mode(t->MagFilter) << 28 | + log2i(t->MaxAnisotropy) << 27 | + nvgl_filter_mode(t->MinFilter) << 24 | + lod_bias << 16; + + } else { + s = &to_nv04_context(ctx)->dummy_texture; + + format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT | + NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT | + 1 << 12 | + NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; + + filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST | + NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; + } + + if (nv04_mtex_engine(fahrenheit)) { + nouveau_bo_markl(bctx, fahrenheit, + NV04_MULTITEX_TRIANGLE_OFFSET(i), + s->bo, 0, bo_flags); + + nouveau_bo_mark(bctx, fahrenheit, + NV04_MULTITEX_TRIANGLE_FORMAT(i), + s->bo, format, 0, + NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A, + NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B, + bo_flags | NOUVEAU_BO_OR); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FILTER(i), 1); + OUT_RING(chan, filter); + + } else { + nouveau_bo_markl(bctx, fahrenheit, + NV04_TEXTURED_TRIANGLE_OFFSET, + s->bo, 0, bo_flags); + + nouveau_bo_mark(bctx, fahrenheit, + NV04_TEXTURED_TRIANGLE_FORMAT, + s->bo, format, 0, + NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A, + NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B, + bo_flags | NOUVEAU_BO_OR); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1); + OUT_RING(chan, filter); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_surface.c b/src/mesa/drivers/dri/nouveau/nv04_surface.c new file mode 100644 index 0000000000..0d40349345 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_surface.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2007-2010 The Nouveau Project. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_class.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nv04_driver.h" + +static inline int +swzsurf_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8; + + default: + assert(0); + } +} + +static inline int +surf2d_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + + default: + assert(0); + } +} + +static inline int +rect_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + + default: + assert(0); + } +} + +static inline int +sifm_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + + default: + assert(0); + } +} + +static void +nv04_surface_copy_swizzle(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *swzsurf = screen->swzsurf; + struct nouveau_grobj *sifm = screen->sifm; + struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); + const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + /* Max width & height may not be the same on all HW, but must be POT */ + const unsigned max_w = 1024; + const unsigned max_h = 1024; + unsigned sub_w = w > max_w ? max_w : w; + unsigned sub_h = h > max_h ? max_h : h; + unsigned x, y; + + /* Swizzled surfaces must be POT */ + assert(_mesa_is_pow_two(dst->width) && + _mesa_is_pow_two(dst->height)); + + /* If area is too large to copy in one shot we must copy it in + * POT chunks to meet alignment requirements */ + assert(sub_w == w || _mesa_is_pow_two(sub_w)); + assert(sub_h == h || _mesa_is_pow_two(sub_h)); + + nouveau_bo_marko(bctx, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, + src->bo, bo_flags | NOUVEAU_BO_RD); + nouveau_bo_marko(bctx, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, + dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + nouveau_bo_markl(bctx, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, + dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); + OUT_RING (chan, swzsurf_format(dst->format) | + log2i(dst->width) << 16 | + log2i(dst->height) << 24); + + BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, swzsurf->handle); + + for (y = 0; y < h; y += sub_h) { + sub_h = MIN2(sub_h, h - y); + + for (x = 0; x < w; x += sub_w) { + sub_w = MIN2(sub_w, w - x); + /* Must be 64-byte aligned */ + assert(!(dst->offset & 63)); + + MARK_RING(chan, 15, 1); + + BEGIN_RING(chan, sifm, + NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 8); + OUT_RING(chan, sifm_format(src->format)); + OUT_RING(chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING(chan, (y + dy) << 16 | (x + dx)); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, (y + dy) << 16 | (x + dx)); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, 1 << 20); + OUT_RING(chan, 1 << 20); + + BEGIN_RING(chan, sifm, + NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, src->pitch | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, src->bo, src->offset + + (y + sy) * src->pitch + + (x + sx) * src->cpp, + bo_flags | NOUVEAU_BO_RD); + OUT_RING(chan, 0); + } + } + + nouveau_bo_context_reset(bctx); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +static void +nv04_surface_copy_m2mf(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *m2mf = screen->m2mf; + struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); + const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; + unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; + + nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, + src->bo, bo_flags | NOUVEAU_BO_RD); + nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT, + dst->bo, bo_flags | NOUVEAU_BO_WR); + + while (h) { + int count = (h > 2047) ? 2047 : h; + + MARK_RING(chan, 9, 2); + + BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src->bo, src_offset, + bo_flags | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->bo, dst_offset, + bo_flags | NOUVEAU_BO_WR); + OUT_RING (chan, src->pitch); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, w * src->cpp); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->pitch * count; + dst_offset += dst->pitch * count; + } + + nouveau_bo_context_reset(bctx); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +void +nv04_surface_copy(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + /* Setup transfer to swizzle the texture to vram if needed */ + if (src->layout != SWIZZLED && + dst->layout == SWIZZLED && + dst->width > 2 && dst->height > 1) { + nv04_surface_copy_swizzle(ctx, dst, src, + dx, dy, sx, sy, w, h); + return; + } + + nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h); +} + +void +nv04_surface_fill(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf2d = screen->surf2d; + struct nouveau_grobj *patt = screen->patt; + struct nouveau_grobj *rect = screen->rect; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + + MARK_RING (chan, 19, 4); + + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); + OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, surf2d_format(dst->format)); + OUT_RING (chan, (dst->pitch << 16) | dst->pitch); + OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); + + BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_COLOR_FORMAT, 1); + OUT_RING (chan, rect_format(dst->format)); + BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR1, 1); + OUT_RING (chan, mask | ~0 << (8 * dst->cpp)); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, rect_format(dst->format)); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +void +nv04_surface_takedown(struct nouveau_screen *screen) +{ + nouveau_grobj_free(&screen->swzsurf); + nouveau_grobj_free(&screen->sifm); + nouveau_grobj_free(&screen->rect); + nouveau_grobj_free(&screen->rop); + nouveau_grobj_free(&screen->patt); + nouveau_grobj_free(&screen->surf2d); + nouveau_grobj_free(&screen->m2mf); + nouveau_notifier_free(&screen->ntfy); +} + +GLboolean +nv04_surface_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + const unsigned chipset = screen->device->chipset; + unsigned handle = 0x88000000, class; + int ret; + + /* Notifier object. */ + ret = nouveau_notifier_alloc(chan, handle++, 1, &screen->ntfy); + if (ret) + goto fail; + + /* Memory to memory format. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_MEMORY_TO_MEMORY_FORMAT, + &screen->m2mf); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + /* Context surfaces 2D. */ + if (chan->device->chipset < 0x10) + class = NV04_CONTEXT_SURFACES_2D; + else + class = NV10_CONTEXT_SURFACES_2D; + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->surf2d); + if (ret) + goto fail; + + /* Raster op. */ + ret = nouveau_grobj_alloc(chan, handle++, NV03_CONTEXT_ROP, + &screen->rop); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_ROP, 1); + OUT_RING (chan, 0xca); /* DPSDxax in the GDI speech. */ + + /* Image pattern. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_IMAGE_PATTERN, + &screen->patt); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3); + OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE); + OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8); + OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO); + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, ~0); + OUT_RING (chan, ~0); + + /* GDI rectangle text. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT, + &screen->rect); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, screen->surf2d->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1); + OUT_RING (chan, screen->rop->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); + OUT_RING (chan, screen->patt->handle); + + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND); + BEGIN_RING(chan, screen->rect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + /* Swizzled surface. */ + switch (chan->device->chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->swzsurf); + if (ret) + goto fail; + + /* Scaled image from memory. */ + switch (chan->device->chipset & 0xf0) { + case 0x10: + case 0x20: + class = NV10_SCALED_IMAGE_FROM_MEMORY; + break; + case 0x30: + class = NV30_SCALED_IMAGE_FROM_MEMORY; + break; + case 0x40: + case 0x60: + class = NV40_SCALED_IMAGE_FROM_MEMORY; + break; + default: + class = NV04_SCALED_IMAGE_FROM_MEMORY; + break; + } + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->sifm); + if (ret) + goto fail; + + if (chipset >= 0x10) { + BEGIN_RING(chan, screen->sifm, + NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1); + OUT_RING(chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + } + + return GL_TRUE; + +fail: + nv04_surface_takedown(screen); + return GL_FALSE; +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c new file mode 100644 index 0000000000..d1afa87c8a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_context.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +static void +nv10_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_framebuffer *nfb = to_nouveau_framebuffer( + ctx->DrawBuffer); + + nouveau_validate_framebuffer(ctx); + + /* Clear the LMA depth buffer, if present. */ + if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask && + nfb->lma_bo) { + struct nouveau_surface *s = &to_nouveau_renderbuffer( + nfb->base._DepthBuffer->Wrapped)->surface; + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_FILL_VALUE, 1); + OUT_RING(chan, pack_zs_f(s->format, ctx->Depth.Clear, 0)); + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_CLEAR, 1); + OUT_RING(chan, 1); + } + + nouveau_clear(ctx, buffers); +} + +GLcontext * +nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nouveau_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nouveau_context); + if (!nctx) + return NULL; + + ctx = &nctx->base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureLevels = 12; + ctx->Const.MaxTextureCoordUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2; + ctx->Const.MaxTextureLodBias = 15; + ctx->Driver.Clear = nv10_clear; + + nv10_render_init(ctx); + + return ctx; +} + +void +nv10_context_destroy(GLcontext *ctx) +{ + nv10_render_destroy(ctx); + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_driver.h b/src/mesa/drivers/dri/nouveau/nv10_driver.h new file mode 100644 index 0000000000..2a1ef7b08e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_driver.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NV10_DRIVER_H__ +#define __NV10_DRIVER_H__ + +#define NV10_TEXTURE_UNITS 2 + +/* nv10_screen.c */ +GLboolean +nv10_screen_init(struct nouveau_screen *screen); + +/* nv10_context.c */ +GLcontext * +nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv10_context_destroy(GLcontext *ctx); + +/* nv10_render.c */ +void +nv10_render_init(GLcontext *ctx); + +void +nv10_render_destroy(GLcontext *ctx); + +/* nv10_state_fb.c */ +void +nv10_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv10_emit_render_mode(GLcontext *ctx, int emit); + +void +nv10_emit_scissor(GLcontext *ctx, int emit); + +void +nv10_emit_viewport(GLcontext *ctx, int emit); + +/* nv10_state_polygon.c */ +void +nv10_emit_cull_face(GLcontext *ctx, int emit); + +void +nv10_emit_front_face(GLcontext *ctx, int emit); + +void +nv10_emit_line_mode(GLcontext *ctx, int emit); + +void +nv10_emit_line_stipple(GLcontext *ctx, int emit); + +void +nv10_emit_point_mode(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_mode(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_offset(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_stipple(GLcontext *ctx, int emit); + +/* nv10_state_raster.c */ +void +nv10_emit_alpha_func(GLcontext *ctx, int emit); + +void +nv10_emit_blend_color(GLcontext *ctx, int emit); + +void +nv10_emit_blend_equation(GLcontext *ctx, int emit); + +void +nv10_emit_blend_func(GLcontext *ctx, int emit); + +void +nv10_emit_color_mask(GLcontext *ctx, int emit); + +void +nv10_emit_depth(GLcontext *ctx, int emit); + +void +nv10_emit_dither(GLcontext *ctx, int emit); + +void +nv10_emit_index_mask(GLcontext *ctx, int emit); + +void +nv10_emit_logic_opcode(GLcontext *ctx, int emit); + +void +nv10_emit_shade_model(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_func(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_mask(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_op(GLcontext *ctx, int emit); + +/* nv10_state_frag.c */ +void +nv10_emit_tex_env(GLcontext *ctx, int emit); + +void +nv10_emit_frag(GLcontext *ctx, int emit); + +/* nv10_state_tex.c */ +void +nv10_emit_tex_gen(GLcontext *ctx, int emit); + +void +nv10_emit_tex_obj(GLcontext *ctx, int emit); + +/* nv10_state_tnl.c */ +void +nv10_get_fog_coeff(GLcontext *ctx, float k[3]); + +void +nv10_get_spot_coeff(struct gl_light *l, float k[7]); + +void +nv10_get_shininess_coeff(float s, float k[6]); + +void +nv10_emit_clip_plane(GLcontext *ctx, int emit); + +void +nv10_emit_color_material(GLcontext *ctx, int emit); + +void +nv10_emit_fog(GLcontext *ctx, int emit); + +void +nv10_emit_light_enable(GLcontext *ctx, int emit); + +void +nv10_emit_light_model(GLcontext *ctx, int emit); + +void +nv10_emit_light_source(GLcontext *ctx, int emit); + +void +nv10_emit_material_ambient(GLcontext *ctx, int emit); + +void +nv10_emit_material_diffuse(GLcontext *ctx, int emit); + +void +nv10_emit_material_specular(GLcontext *ctx, int emit); + +void +nv10_emit_material_shininess(GLcontext *ctx, int emit); + +void +nv10_emit_modelview(GLcontext *ctx, int emit); + +void +nv10_emit_point_parameter(GLcontext *ctx, int emit); + +void +nv10_emit_projection(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv10_render.c b/src/mesa/drivers/dri/nouveau/nv10_render.c new file mode 100644 index 0000000000..54245ea6ba --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_render.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +#define NUM_VERTEX_ATTRS 8 + +static void +nv10_emit_material(GLcontext *ctx, struct nouveau_array_state *a, + const void *v); + +/* Vertex attribute format. */ +static struct nouveau_attr_info nv10_vertex_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .vbo_index = 0, + .imm_method = NV10TCL_VERTEX_POS_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR0] = { + .vbo_index = 1, + .imm_method = NV10TCL_VERTEX_COL_4F_R, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .vbo_index = 2, + .imm_method = NV10TCL_VERTEX_COL2_3F_R, + .imm_fields = 3, + }, + [VERT_ATTRIB_TEX0] = { + .vbo_index = 3, + .imm_method = NV10TCL_VERTEX_TX0_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX1] = { + .vbo_index = 4, + .imm_method = NV10TCL_VERTEX_TX1_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .vbo_index = 5, + .imm_method = NV10TCL_VERTEX_NOR_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_FOG] = { + .vbo_index = 7, + .imm_method = NV10TCL_VERTEX_FOG_1F, + .imm_fields = 1, + }, + [VERT_ATTRIB_GENERIC0] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC2] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC4] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC6] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC8] = { + .emit = nv10_emit_material, + }, +}; + +static int +get_hw_format(int type) +{ + switch (type) { + case GL_FLOAT: + return NV10TCL_VTXFMT_TYPE_FLOAT; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return NV10TCL_VTXFMT_TYPE_SHORT; + case GL_UNSIGNED_BYTE: + return NV10TCL_VTXFMT_TYPE_BYTE_RGBA; + default: + assert(0); + } +} + +static void +nv10_render_set_format(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int i, hw_format; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + hw_format = a->stride << 8 | + a->fields << 4 | + get_hw_format(a->type); + + if (attr == VERT_ATTRIB_POS && a->fields == 4) + hw_format |= NV10TCL_VTXFMT_POS_HOMOGENEOUS; + } else { + /* Unused attribute. */ + hw_format = NV10TCL_VTXFMT_TYPE_FLOAT; + } + + BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1); + OUT_RING(chan, hw_format); + } +} + +static void +nv10_render_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + nouveau_bo_markl(bctx, celsius, + NV10TCL_VTXBUF_ADDRESS(i), + a->bo, a->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + } + } + + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_VALIDATE, 1); + OUT_RING(chan, 0); +} + +/* Vertex array rendering defs. */ +#define RENDER_LOCALS(ctx) \ + struct nouveau_grobj *celsius = context_eng3d(ctx) + +#define BATCH_BEGIN(prim) \ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); \ + OUT_RING(chan, prim); +#define BATCH_END() \ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); \ + OUT_RING(chan, 0); + +#define MAX_PACKET 0x400 + +#define MAX_OUT_L 0x100 +#define BATCH_PACKET_L(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS, n); +#define BATCH_OUT_L(i, n) \ + OUT_RING(chan, ((n) - 1) << 24 | (i)); + +#define MAX_OUT_I16 0x2 +#define BATCH_PACKET_I16(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, n); +#define BATCH_OUT_I16(i0, i1) \ + OUT_RING(chan, (i1) << 16 | (i0)); + +#define MAX_OUT_I32 0x1 +#define BATCH_PACKET_I32(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U32, n); +#define BATCH_OUT_I32(i) \ + OUT_RING(chan, i); + +#define IMM_PACKET(m, n) \ + BEGIN_RING(chan, celsius, m, n); +#define IMM_OUT(x) \ + OUT_RINGf(chan, x); + +#define TAG(x) nv10_##x +#include "nouveau_render_t.c" diff --git a/src/mesa/drivers/dri/nouveau/nv10_screen.c b/src/mesa/drivers/dri/nouveau/nv10_screen.c new file mode 100644 index 0000000000..8665ad1410 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_screen.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" +#include "nv10_driver.h" + +static const struct nouveau_driver nv10_driver; + +static void +nv10_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *celsius = screen->eng3d; + const unsigned chipset = screen->device->chipset; + int i; + + BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1); + OUT_RING(chan, screen->ntfy->handle); + + BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 3); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, chan->gart->handle); + BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, 0x7ff << 16 | 0x800); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, 0x7ff << 16 | 0x800); + + for (i = 1; i < 8; i++) { + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING(chan, 0); + } + + BEGIN_RING(chan, celsius, 0x290, 1); + OUT_RING(chan, 0x10 << 16 | 1); + BEGIN_RING(chan, celsius, 0x3f4, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + if (chipset >= 0x17) { + BEGIN_RING(chan, celsius, NV17TCL_DMA_IN_MEMORY4, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, celsius, 0xd84, 1); + OUT_RING(chan, 0x3); + + BEGIN_RING(chan, celsius, NV17TCL_COLOR_MASK_ENABLE, 1); + OUT_RING(chan, 1); + } + + if (chipset >= 0x11) { + BEGIN_RING(chan, celsius, 0x120, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 1); + OUT_RING(chan, 2); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + } + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + /* Set state */ + BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING(chan, 0x207); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2); + OUT_RING(chan, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4); + OUT_RING(chan, 1); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0x8006); + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8); + OUT_RING(chan, 0xff); + OUT_RING(chan, 0x207); + OUT_RING(chan, 0); + OUT_RING(chan, 0xff); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1d01); + BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING(chan, 0x201); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING(chan, 8); + BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING(chan, 8); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING(chan, 0x1b02); + OUT_RING(chan, 0x1b02); + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); + OUT_RING(chan, 0x405); + OUT_RING(chan, 0x901); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8); + for (i = 0; i < 8; i++) + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_TX_MATRIX_ENABLE(0), 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RING(chan, 0x3fc00000); /* -1.50 */ + OUT_RING(chan, 0xbdb8aa0a); /* -0.09 */ + OUT_RING(chan, 0); /* 0.00 */ + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2); + OUT_RING(chan, 0x802); + OUT_RING(chan, 2); + /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when + * using texturing, except when using the texture matrix + */ + BEGIN_RING(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); + OUT_RING(chan, 6); + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING(chan, 0x01010101); + + /* Set vertex component */ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1); + OUT_RINGf(chan, 0.0); + BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1); + OUT_RING(chan, 1); + + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); + OUT_RING(chan, 0.0); + OUT_RINGf(chan, 16777216.0); + + FIRE_RING(chan); +} + +GLboolean +nv10_screen_init(struct nouveau_screen *screen) +{ + unsigned chipset = screen->device->chipset; + unsigned celsius_class; + int ret; + + screen->driver = &nv10_driver; + + /* 2D engine. */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + if (chipset >= 0x17) + celsius_class = NV17TCL; + else if (chipset >= 0x11) + celsius_class = NV11TCL; + else + celsius_class = NV10TCL; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, celsius_class, + &screen->eng3d); + if (ret) + return GL_FALSE; + + nv10_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv10_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv10_driver = { + .screen_destroy = nv10_screen_destroy, + .context_create = nv10_context_create, + .context_destroy = nv10_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv10_emit_alpha_func, + nv10_emit_blend_color, + nv10_emit_blend_equation, + nv10_emit_blend_func, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_color_mask, + nv10_emit_color_material, + nv10_emit_cull_face, + nv10_emit_front_face, + nv10_emit_depth, + nv10_emit_dither, + nv10_emit_frag, + nv10_emit_framebuffer, + nv10_emit_fog, + nv10_emit_index_mask, + nv10_emit_light_enable, + nv10_emit_light_model, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_line_stipple, + nv10_emit_line_mode, + nv10_emit_logic_opcode, + nv10_emit_material_ambient, + nouveau_emit_nothing, + nv10_emit_material_diffuse, + nouveau_emit_nothing, + nv10_emit_material_specular, + nouveau_emit_nothing, + nv10_emit_material_shininess, + nouveau_emit_nothing, + nv10_emit_modelview, + nv10_emit_point_mode, + nv10_emit_point_parameter, + nv10_emit_polygon_mode, + nv10_emit_polygon_offset, + nv10_emit_polygon_stipple, + nv10_emit_projection, + nv10_emit_render_mode, + nv10_emit_scissor, + nv10_emit_shade_model, + nv10_emit_stencil_func, + nv10_emit_stencil_mask, + nv10_emit_stencil_op, + nv10_emit_tex_env, + nv10_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_tex_obj, + nv10_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_viewport + }, + .num_emit = NUM_NOUVEAU_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_fb.c b/src/mesa/drivers/dri/nouveau/nv10_state_fb.c new file mode 100644 index 0000000000..05c36b4f8f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_fb.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + case MESA_FORMAT_Z16: + return 0x10; + case MESA_FORMAT_Z24_S8: + return 0x0; + default: + assert(0); + } +} + +static void +setup_lma_buffer(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, LMA_DEPTH); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb); + unsigned pitch = align(fb->Width, 128), + height = align(fb->Height, 2), + size = pitch * height; + + if (!nfb->lma_bo || nfb->lma_bo->size != size) { + nouveau_bo_ref(NULL, &nfb->lma_bo); + nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_VRAM, 0, size, + &nfb->lma_bo); + } + + nouveau_bo_markl(bctx, celsius, NV17TCL_LMA_DEPTH_BUFFER_OFFSET, + nfb->lma_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_WINDOW_X, 4); + OUT_RINGf(chan, - 1792); + OUT_RINGf(chan, - 2304 + fb->Height); + OUT_RINGf(chan, fb->_DepthMaxF / 2); + OUT_RINGf(chan, 0); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING(chan, pitch); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_ENABLE, 1); + OUT_RING(chan, 1); +} + +void +nv10_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + unsigned rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; + unsigned rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* At least nv11 seems to get sad if we don't do this before + * swapping RTs.*/ + if (context_chipset(ctx) < 0x17) { + int i; + + for (i = 0; i < 6; i++) { + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + } + } + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, celsius, NV10TCL_COLOR_OFFSET, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, celsius, NV10TCL_ZETA_OFFSET, + s->bo, 0, bo_flags); + + if (context_chipset(ctx) >= 0x17) + setup_lma_buffer(ctx); + } + + BEGIN_RING(chan, celsius, NV10TCL_RT_FORMAT, 2); + OUT_RING(chan, rt_format); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + context_dirty(ctx, VIEWPORT); + context_dirty(ctx, SCISSOR); +} + +void +nv10_emit_render_mode(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_scissor(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int x, y, w, h; + + get_scissors(ctx->DrawBuffer, &x, &y, &w, &h); + + BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING(chan, w << 16 | x); + OUT_RING(chan, h << 16 | y); +} + +void +nv10_emit_viewport(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + float a[4] = {}; + int i; + + get_viewport_translate(ctx, a); + a[0] -= 2048; + a[1] -= 2048; + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4); + for (i = 0; i < 4; i++) + OUT_RINGf(chan, a[i]); + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, (fb->Width - 1) << 16 | 0x08000800); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, (fb->Height - 1) << 16 | 0x08000800); + + context_dirty(ctx, PROJECTION); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_frag.c b/src/mesa/drivers/dri/nouveau/nv10_state_frag.c new file mode 100644 index 0000000000..c1df26ecce --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_frag.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +#define RC_IN_SHIFT_A 24 +#define RC_IN_SHIFT_B 16 +#define RC_IN_SHIFT_C 8 +#define RC_IN_SHIFT_D 0 +#define RC_IN_SHIFT_E 56 +#define RC_IN_SHIFT_F 48 +#define RC_IN_SHIFT_G 40 + +#define RC_IN_SOURCE(source) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_INPUT_##source) +#define RC_IN_USAGE(usage) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_COMPONENT_USAGE_##usage) +#define RC_IN_MAPPING(mapping) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_MAPPING_##mapping) + +#define RC_OUT_BIAS NV10TCL_RC_OUT_RGB_BIAS_BIAS_BY_NEGATIVE_ONE_HALF +#define RC_OUT_SCALE_1 NV10TCL_RC_OUT_RGB_SCALE_NONE +#define RC_OUT_SCALE_2 NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_TWO +#define RC_OUT_SCALE_4 NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_FOUR + +/* Make the combiner do: spare0_i = A_i * B_i */ +#define RC_OUT_AB NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0 +/* spare0_i = dot3(A, B) */ +#define RC_OUT_DOT_AB (NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0 | \ + NV10TCL_RC_OUT_RGB_AB_DOT_PRODUCT) +/* spare0_i = A_i * B_i + C_i * D_i */ +#define RC_OUT_SUM NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SPARE0 + +struct combiner_state { + GLcontext *ctx; + int unit; + + /* GL state */ + GLenum mode; + GLenum *source; + GLenum *operand; + GLuint logscale; + + /* Derived HW state */ + uint64_t in; + uint32_t out; +}; + +/* Initialize a combiner_state struct from the texture unit + * context. */ +#define INIT_COMBINER(chan, ctx, rc, i) do { \ + struct gl_tex_env_combine_state *c = \ + ctx->Texture.Unit[i]._CurrentCombine; \ + (rc)->ctx = ctx; \ + (rc)->unit = i; \ + (rc)->mode = c->Mode##chan; \ + (rc)->source = c->Source##chan; \ + (rc)->operand = c->Operand##chan; \ + (rc)->logscale = c->ScaleShift##chan; \ + (rc)->in = (rc)->out = 0; \ + } while (0) + +/* Get the RC input source for the specified EXT_texture_env_combine + * argument. */ +static uint32_t +get_input_source(struct combiner_state *rc, int arg) +{ + switch (rc->source[arg]) { + case GL_TEXTURE: + return RC_IN_SOURCE(TEXTURE0) + rc->unit; + + case GL_TEXTURE0: + return RC_IN_SOURCE(TEXTURE0); + + case GL_TEXTURE1: + return RC_IN_SOURCE(TEXTURE1); + + case GL_TEXTURE2: + return RC_IN_SOURCE(TEXTURE2); + + case GL_TEXTURE3: + return RC_IN_SOURCE(TEXTURE3); + + case GL_CONSTANT: + return context_chipset(rc->ctx) >= 0x20 ? + RC_IN_SOURCE(CONSTANT_COLOR0) : + RC_IN_SOURCE(CONSTANT_COLOR0) + rc->unit; + + case GL_PRIMARY_COLOR: + return RC_IN_SOURCE(PRIMARY_COLOR); + + case GL_PREVIOUS: + return rc->unit ? RC_IN_SOURCE(SPARE0) + : RC_IN_SOURCE(PRIMARY_COLOR); + + default: + assert(0); + } +} + +/* Get the RC input mapping for the specified argument, possibly + * inverted or biased. */ +#define INVERT 0x1 +#define HALF_BIAS 0x2 + +static uint32_t +get_input_mapping(struct combiner_state *rc, int arg, int flags) +{ + int map = 0; + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + map |= RC_IN_USAGE(RGB); + break; + + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + map |= RC_IN_USAGE(ALPHA); + break; + } + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + map |= (flags & INVERT ? RC_IN_MAPPING(UNSIGNED_INVERT) : + flags & HALF_BIAS ? RC_IN_MAPPING(HALF_BIAS_NORMAL) : + RC_IN_MAPPING(UNSIGNED_IDENTITY)); + break; + + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + map |= (flags & INVERT ? RC_IN_MAPPING(UNSIGNED_IDENTITY) : + flags & HALF_BIAS ? RC_IN_MAPPING(HALF_BIAS_NEGATE) : + RC_IN_MAPPING(UNSIGNED_INVERT)); + break; + } + + return map; +} + +/* Bind the RC input variable <var> to the EXT_texture_env_combine + * argument <arg>, possibly inverted or biased. */ +#define INPUT_ARG(rc, var, arg, flags) \ + (rc)->in |= (get_input_mapping(rc, arg, flags) | \ + get_input_source(rc, arg)) << RC_IN_SHIFT_##var + +/* Bind the RC input variable <var> to the RC source <src>. */ +#define INPUT_SRC(rc, var, src, chan) \ + (rc)->in |= (RC_IN_SOURCE(src) | \ + RC_IN_USAGE(chan)) << RC_IN_SHIFT_##var + +/* Bind the RC input variable <var> to a constant +/-1 */ +#define INPUT_ONE(rc, var, flags) \ + (rc)->in |= (RC_IN_SOURCE(ZERO) | \ + (flags & INVERT ? RC_IN_MAPPING(EXPAND_NORMAL) : \ + RC_IN_MAPPING(UNSIGNED_INVERT))) << RC_IN_SHIFT_##var + +static void +setup_combiner(struct combiner_state *rc) +{ + switch (rc->mode) { + case GL_REPLACE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + + rc->out = RC_OUT_AB; + break; + + case GL_MODULATE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ARG(rc, B, 1, 0); + + rc->out = RC_OUT_AB; + break; + + case GL_ADD: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, 0); + + rc->out = RC_OUT_SUM; + break; + + case GL_ADD_SIGNED: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, 0); + + rc->out = RC_OUT_SUM | RC_OUT_BIAS; + break; + + case GL_INTERPOLATE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ARG(rc, B, 2, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ARG(rc, D, 2, INVERT); + + rc->out = RC_OUT_SUM; + break; + + case GL_SUBTRACT: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, INVERT); + + rc->out = RC_OUT_SUM; + break; + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + INPUT_ARG(rc, A, 0, HALF_BIAS); + INPUT_ARG(rc, B, 1, HALF_BIAS); + + rc->out = RC_OUT_DOT_AB | RC_OUT_SCALE_4; + + assert(!rc->logscale); + break; + + default: + assert(0); + } + + switch (rc->logscale) { + case 0: + rc->out |= RC_OUT_SCALE_1; + break; + case 1: + rc->out |= RC_OUT_SCALE_2; + break; + case 2: + rc->out |= RC_OUT_SCALE_4; + break; + default: + assert(0); + } +} + +/* Write the register combiner state out to the hardware. */ +static void +nv10_load_combiner(GLcontext *ctx, int i, struct combiner_state *rc_a, + struct combiner_state *rc_c, uint32_t rc_const) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + /* Enable the combiners we're going to need. */ + if (i == 1) { + if (rc_c->out || rc_a->out) + rc_c->out |= 0x5 << 27; + else + rc_c->out |= 0x3 << 27; + } + + BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(i), 1); + OUT_RING(chan, rc_a->in); + BEGIN_RING(chan, celsius, NV10TCL_RC_IN_RGB(i), 1); + OUT_RING(chan, rc_c->in); + BEGIN_RING(chan, celsius, NV10TCL_RC_COLOR(i), 1); + OUT_RING(chan, rc_const); + BEGIN_RING(chan, celsius, NV10TCL_RC_OUT_ALPHA(i), 1); + OUT_RING(chan, rc_a->out); + BEGIN_RING(chan, celsius, NV10TCL_RC_OUT_RGB(i), 1); + OUT_RING(chan, rc_c->out); +} + +static void +nv10_load_final(GLcontext *ctx, struct combiner_state *rc, int n) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_RC_FINAL0, 2); + OUT_RING(chan, rc->in); + OUT_RING(chan, rc->in >> 32); +} + +static void +nv20_load_combiner(GLcontext *ctx, int i, struct combiner_state *rc_a, + struct combiner_state *rc_c, uint32_t rc_const) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(i), 1); + OUT_RING(chan, rc_a->in); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_ALPHA(i), 1); + OUT_RING(chan, rc_a->out); + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_RGB(i), 1); + OUT_RING(chan, rc_c->in); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_RGB(i), 1); + OUT_RING(chan, rc_c->out); + BEGIN_RING(chan, kelvin, NV20TCL_RC_CONSTANT_COLOR0(i), 1); + OUT_RING(chan, rc_const); +} + +static void +nv20_load_final(GLcontext *ctx, struct combiner_state *rc, int n) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_FINAL0, 2); + OUT_RING(chan, rc->in); + OUT_RING(chan, rc->in >> 32); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_ENABLE, 1); + OUT_RING(chan, n); +} + +void +nv10_emit_tex_env(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_ENV0; + struct combiner_state rc_a, rc_c; + uint32_t rc_const; + + /* Compute the new combiner state. */ + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INIT_COMBINER(RGB, ctx, &rc_c, i); + + if (rc_c.mode == GL_DOT3_RGBA) + rc_a = rc_c; + else + INIT_COMBINER(A, ctx, &rc_a, i); + + setup_combiner(&rc_c); + setup_combiner(&rc_a); + + rc_const = pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Texture.Unit[i].EnvColor); + + } else { + rc_a.in = rc_a.out = rc_c.in = rc_c.out = rc_const = 0; + } + + if (context_chipset(ctx) >= 0x20) + nv20_load_combiner(ctx, i, &rc_a, &rc_c, rc_const); + else + nv10_load_combiner(ctx, i, &rc_a, &rc_c, rc_const); + + context_dirty(ctx, FRAG); +} + +void +nv10_emit_frag(GLcontext *ctx, int emit) +{ + struct combiner_state rc = {}; + int n = log2i(ctx->Texture._EnabledUnits) + 1; + + /* + * The final fragment value equation is something like: + * x_i = A_i * B_i + (1 - A_i) * C_i + D_i + * x_alpha = G_alpha + * where D_i = E_i * F_i, i one of {red, green, blue}. + */ + if (ctx->Fog.ColorSumEnabled || ctx->Light.Enabled) { + INPUT_SRC(&rc, D, E_TIMES_F, RGB); + INPUT_SRC(&rc, F, SECONDARY_COLOR, RGB); + } + + if (ctx->Fog.Enabled) { + INPUT_SRC(&rc, A, FOG, ALPHA); + INPUT_SRC(&rc, C, FOG, RGB); + INPUT_SRC(&rc, E, FOG, ALPHA); + } else { + INPUT_ONE(&rc, A, 0); + INPUT_ONE(&rc, C, 0); + INPUT_ONE(&rc, E, 0); + } + + if (ctx->Texture._EnabledUnits) { + INPUT_SRC(&rc, B, SPARE0, RGB); + INPUT_SRC(&rc, G, SPARE0, ALPHA); + } else { + INPUT_SRC(&rc, B, PRIMARY_COLOR, RGB); + INPUT_SRC(&rc, G, PRIMARY_COLOR, ALPHA); + } + + if (context_chipset(ctx) >= 0x20) + nv20_load_final(ctx, &rc, n); + else + nv10_load_final(ctx, &rc, n); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c b/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c new file mode 100644 index 0000000000..deddca1011 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_cull_face(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLenum mode = ctx->Polygon.CullFaceMode; + + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING(chan, ctx->Polygon.CullFlag ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 1); + OUT_RING(chan, (mode == GL_FRONT ? NV10TCL_CULL_FACE_FRONT : + mode == GL_BACK ? NV10TCL_CULL_FACE_BACK : + NV10TCL_CULL_FACE_FRONT_AND_BACK)); +} + +void +nv10_emit_front_face(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_FRONT_FACE, 1); + OUT_RING(chan, ctx->Polygon.FrontFace == GL_CW ? + NV10TCL_FRONT_FACE_CW : NV10TCL_FRONT_FACE_CCW); +} + +void +nv10_emit_line_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLboolean smooth = ctx->Line.SmoothFlag && + ctx->Hint.LineSmooth == GL_NICEST; + + BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING(chan, MAX2(smooth ? 0 : 1, + ctx->Line.Width) * 8); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, smooth ? 1 : 0); +} + +void +nv10_emit_line_stipple(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_point_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING(chan, (uint32_t)(ctx->Point.Size * 8)); + + BEGIN_RING(chan, celsius, NV10TCL_POINT_SMOOTH_ENABLE, 1); + OUT_RING(chan, ctx->Point.SmoothFlag ? 1 : 0); +} + +void +nv10_emit_polygon_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.FrontMode)); + OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.BackMode)); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(chan, ctx->Polygon.SmoothFlag ? 1 : 0); +} + +void +nv10_emit_polygon_offset(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING(chan, ctx->Polygon.OffsetPoint ? 1 : 0); + OUT_RING(chan, ctx->Polygon.OffsetLine ? 1 : 0); + OUT_RING(chan, ctx->Polygon.OffsetFill ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RINGf(chan, ctx->Polygon.OffsetFactor); + OUT_RINGf(chan, ctx->Polygon.OffsetUnits); +} + +void +nv10_emit_polygon_stipple(GLcontext *ctx, int emit) +{ +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_raster.c b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c new file mode 100644 index 0000000000..68882ef05f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_alpha_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING(chan, ctx->Color.AlphaEnabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING(chan, nvgl_comparison_op(ctx->Color.AlphaFunc)); + OUT_RING(chan, FLOAT_TO_UBYTE(ctx->Color.AlphaRef)); +} + +void +nv10_emit_blend_color(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1); + OUT_RING(chan, FLOAT_TO_UBYTE(ctx->Color.BlendColor[3]) << 24 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[0]) << 16 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[1]) << 8 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[2]) << 0); +} + +void +nv10_emit_blend_equation(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING(chan, ctx->Color.BlendEnabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_EQUATION, 1); + OUT_RING(chan, nvgl_blend_eqn(ctx->Color.BlendEquationRGB)); +} + +void +nv10_emit_blend_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 2); + OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendSrcRGB)); + OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendDstRGB)); +} + +void +nv10_emit_color_mask(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING(chan, ((ctx->Color.ColorMask[0][3] ? 1 << 24 : 0) | + (ctx->Color.ColorMask[0][0] ? 1 << 16 : 0) | + (ctx->Color.ColorMask[0][1] ? 1 << 8 : 0) | + (ctx->Color.ColorMask[0][2] ? 1 << 0 : 0))); +} + +void +nv10_emit_depth(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING(chan, ctx->Depth.Test ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING(chan, ctx->Depth.Mask ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING(chan, nvgl_comparison_op(ctx->Depth.Func)); +} + +void +nv10_emit_dither(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1); + OUT_RING(chan, ctx->Color.DitherFlag ? 1 : 0); +} + +void +nv10_emit_index_mask(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_logic_opcode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + assert(!ctx->Color.ColorLogicOpEnabled + || context_chipset(ctx) >= 0x11); + + BEGIN_RING(chan, celsius, NV11TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING(chan, ctx->Color.ColorLogicOpEnabled ? 1 : 0); + OUT_RING(chan, nvgl_logicop_func(ctx->Color.LogicOp)); +} + +void +nv10_emit_shade_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 1); + OUT_RING(chan, ctx->Light.ShadeModel == GL_SMOOTH ? + NV10TCL_SHADE_MODEL_SMOOTH : NV10TCL_SHADE_MODEL_FLAT); +} + +void +nv10_emit_stencil_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1); + OUT_RING(chan, ctx->Stencil.Enabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_FUNC_FUNC, 3); + OUT_RING(chan, nvgl_comparison_op(ctx->Stencil.Function[0])); + OUT_RING(chan, ctx->Stencil.Ref[0]); + OUT_RING(chan, ctx->Stencil.ValueMask[0]); +} + +void +nv10_emit_stencil_mask(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 1); + OUT_RING(chan, ctx->Stencil.WriteMask[0]); +} + +void +nv10_emit_stencil_op(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_OP_FAIL, 3); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.FailFunc[0])); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.ZFailFunc[0])); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.ZPassFunc[0])); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c new file mode 100644 index 0000000000..e5d4f3d18d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_texture.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" + +void +nv10_emit_tex_gen(GLcontext *ctx, int emit) +{ +} + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8; + + case MESA_FORMAT_ARGB1555: + return NV10TCL_TX_FORMAT_FORMAT_A1R5G5B5; + + case MESA_FORMAT_ARGB4444: + return NV10TCL_TX_FORMAT_FORMAT_A4R4G4B4; + + case MESA_FORMAT_RGB565: + return NV10TCL_TX_FORMAT_FORMAT_R5G6B5; + + case MESA_FORMAT_A8: + return NV10TCL_TX_FORMAT_FORMAT_A8; + + case MESA_FORMAT_L8: + return NV10TCL_TX_FORMAT_FORMAT_L8; + + case MESA_FORMAT_CI8: + return NV10TCL_TX_FORMAT_FORMAT_INDEX8; + + default: + assert(0); + } +} + +void +nv10_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct gl_texture_object *t; + struct nouveau_surface *s; + struct gl_texture_image *ti; + uint32_t tx_format, tx_filter, tx_enable; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) { + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(i), 1); + OUT_RING(chan, 0); + return; + } + + t = ctx->Texture.Unit[i]._Current; + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + ti = t->Image[0][t->BaseLevel]; + + nouveau_texture_validate(ctx, t); + + /* Recompute the texturing registers. */ + tx_format = nvgl_wrap_mode(t->WrapT) << 28 + | nvgl_wrap_mode(t->WrapS) << 24 + | ti->HeightLog2 << 20 + | ti->WidthLog2 << 16 + | get_tex_format(ti) + | 5 << 4 | 1 << 12; + + tx_filter = nvgl_filter_mode(t->MagFilter) << 28 + | nvgl_filter_mode(t->MinFilter) << 24; + + tx_enable = NV10TCL_TX_ENABLE_ENABLE + | log2i(t->MaxAnisotropy) << 4; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + int lod_min = t->MinLod; + int lod_max = MIN2(t->MaxLod, t->_MaxLambda); + int lod_bias = t->LodBias + + ctx->Texture.Unit[i].LodBias; + + lod_max = CLAMP(lod_max, 0, 15); + lod_min = CLAMP(lod_min, 0, 15); + lod_bias = CLAMP(lod_bias, 0, 15); + + tx_format |= NV10TCL_TX_FORMAT_MIPMAP; + tx_filter |= lod_bias << 8; + tx_enable |= lod_min << 26 + | lod_max << 14; + } + + /* Write it to the hardware. */ + nouveau_bo_mark(bctx, celsius, NV10TCL_TX_FORMAT(i), + s->bo, tx_format, 0, + NV10TCL_TX_FORMAT_DMA0, + NV10TCL_TX_FORMAT_DMA1, + bo_flags | NOUVEAU_BO_OR); + + nouveau_bo_markl(bctx, celsius, NV10TCL_TX_OFFSET(i), + s->bo, 0, bo_flags); + + BEGIN_RING(chan, celsius, NV10TCL_TX_FILTER(i), 1); + OUT_RING(chan, tx_filter); + + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(i), 1); + OUT_RING(chan, tx_enable); +} + diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c new file mode 100644 index 0000000000..6db14d83b8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c @@ -0,0 +1,514 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_clip_plane(GLcontext *ctx, int emit) +{ +} + +static inline unsigned +get_material_bitmask(unsigned m) +{ + unsigned ret = 0; + + if (m & MAT_BIT_FRONT_EMISSION) + ret |= NV10TCL_COLOR_MATERIAL_EMISSION; + if (m & MAT_BIT_FRONT_AMBIENT) + ret |= NV10TCL_COLOR_MATERIAL_AMBIENT; + if (m & MAT_BIT_FRONT_DIFFUSE) + ret |= NV10TCL_COLOR_MATERIAL_DIFFUSE; + if (m & MAT_BIT_FRONT_SPECULAR) + ret |= NV10TCL_COLOR_MATERIAL_SPECULAR; + + return ret; +} + +void +nv10_emit_color_material(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask); + + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MATERIAL, 1); + OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0); +} + +static unsigned +get_fog_mode(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV10TCL_FOG_MODE_LINEAR; + case GL_EXP: + return NV10TCL_FOG_MODE_EXP; + case GL_EXP2: + return NV10TCL_FOG_MODE_EXP2; + default: + assert(0); + } +} + +static unsigned +get_fog_source(unsigned source) +{ + switch (source) { + case GL_FOG_COORDINATE_EXT: + return NV10TCL_FOG_COORD_FOG; + case GL_FRAGMENT_DEPTH_EXT: + return NV10TCL_FOG_COORD_DIST_ORTHOGONAL_ABS; + default: + assert(0); + } +} + +void +nv10_get_fog_coeff(GLcontext *ctx, float k[3]) +{ + struct gl_fog_attrib *f = &ctx->Fog; + + switch (f->Mode) { + case GL_LINEAR: + k[0] = 2 + f->Start / (f->End - f->Start); + k[1] = -1 / (f->End - f->Start); + break; + + case GL_EXP: + k[0] = 1.5; + k[1] = -0.09 * f->Density; + break; + + case GL_EXP2: + k[0] = 1.5; + k[1] = -0.21 * f->Density; + break; + + default: + assert(0); + } + + k[2] = 0; +} + +void +nv10_emit_fog(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_fog_attrib *f = &ctx->Fog; + unsigned source = nctx->fallback == HWTNL ? + f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; + float k[3]; + + nv10_get_fog_coeff(ctx, k); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 4); + OUT_RING(chan, get_fog_mode(f->Mode)); + OUT_RING(chan, get_fog_source(source)); + OUT_RING(chan, f->Enabled ? 1 : 0); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + + context_dirty(ctx, FRAG); +} + +static inline unsigned +get_light_mode(struct gl_light *l) +{ + if (l->Enabled) { + if (l->_Flags & LIGHT_SPOT) + return NV10TCL_ENABLED_LIGHTS_0_DIRECTIONAL; + else if (l->_Flags & LIGHT_POSITIONAL) + return NV10TCL_ENABLED_LIGHTS_0_POSITIONAL; + else + return NV10TCL_ENABLED_LIGHTS_0_NONPOSITIONAL; + } else { + return NV10TCL_ENABLED_LIGHTS_0_DISABLED; + } +} + +void +nv10_emit_light_enable(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + uint32_t en_lights = 0; + int i; + + if (nctx->fallback != HWTNL) { + BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1); + OUT_RING(chan, 0); + return; + } + + for (i = 0; i < MAX_LIGHTS; i++) + en_lights |= get_light_mode(&ctx->Light.Light[i]) << 2 * i; + + BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING(chan, en_lights); + BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1); + OUT_RING(chan, ctx->Light.Enabled ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING(chan, ctx->Transform.Normalize ? 1 : 0); +} + +void +nv10_emit_light_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_lightmodel *m = &ctx->Light.Model; + + BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING(chan, ((m->LocalViewer ? + NV10TCL_LIGHT_MODEL_LOCAL_VIEWER : 0) | + (m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? + NV10TCL_LIGHT_MODEL_SEPARATE_SPECULAR : 0))); +} + +static float +get_shine(const float p[], float x) +{ + const int n = 15; + const float *y = &p[1]; + float f = (n - 1) * (1 - 1 / (1 + p[0] * x)) + / (1 - 1 / (1 + p[0] * 1024)); + int i = f; + + /* Linear interpolation in f-space (Faster and somewhat more + * accurate than x-space). */ + if (x == 0) + return y[0]; + else if (i > n - 2) + return y[n - 1]; + else + return y[i] + (y[i + 1] - y[i]) * (f - i); +} + +static const float nv10_spot_params[2][16] = { + { 0.02, -3.80e-05, -1.77, -2.41, -2.71, -2.88, -2.98, -3.06, + -3.11, -3.17, -3.23, -3.28, -3.37, -3.47, -3.83, -5.11 }, + { 0.02, -0.01, 1.77, 2.39, 2.70, 2.87, 2.98, 3.06, + 3.10, 3.16, 3.23, 3.27, 3.37, 3.47, 3.83, 5.11 }, +}; + +void +nv10_get_spot_coeff(struct gl_light *l, float k[7]) +{ + float e = l->SpotExponent; + float a0, b0, a1, a2, b2, a3; + + if (e > 0) + a0 = -1 - 5.36e-3 / sqrt(e); + else + a0 = -1; + b0 = 1 / (1 + 0.273 * e); + + a1 = get_shine(nv10_spot_params[0], e); + + a2 = get_shine(nv10_spot_params[1], e); + b2 = 1 / (1 + 0.273 * e); + + a3 = 0.9 + 0.278 * e; + + if (l->SpotCutoff > 0) { + float cutoff = MAX2(a3, 1 / (1 - l->_CosCutoff)); + + k[0] = MAX2(0, a0 + b0 * cutoff); + k[1] = a1; + k[2] = a2 + b2 * cutoff; + k[3] = - cutoff * l->_NormSpotDirection[0]; + k[4] = - cutoff * l->_NormSpotDirection[1]; + k[5] = - cutoff * l->_NormSpotDirection[2]; + k[6] = 1 - cutoff; + + } else { + k[0] = b0; + k[1] = a1; + k[2] = a2 + b2; + k[3] = - l->_NormSpotDirection[0]; + k[4] = - l->_NormSpotDirection[1]; + k[5] = - l->_NormSpotDirection[2]; + k[6] = -1; + } +} + +void +nv10_emit_light_source(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_light *l = &ctx->Light.Light[i]; + + if (l->_Flags & LIGHT_POSITIONAL) { + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_POSITION_X(i), 3); + OUT_RINGf(chan, l->_Position[0]); + OUT_RINGf(chan, l->_Position[1]); + OUT_RINGf(chan, l->_Position[2]); + + BEGIN_RING(chan, celsius, + NV10TCL_LIGHT_ATTENUATION_CONSTANT(i), 3); + OUT_RINGf(chan, l->ConstantAttenuation); + OUT_RINGf(chan, l->LinearAttenuation); + OUT_RINGf(chan, l->QuadraticAttenuation); + + } else { + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIRECTION_X(i), 3); + OUT_RINGf(chan, l->_VP_inf_norm[0]); + OUT_RINGf(chan, l->_VP_inf_norm[1]); + OUT_RINGf(chan, l->_VP_inf_norm[2]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_HALF_VECTOR_X(i), 3); + OUT_RINGf(chan, l->_h_inf_norm[0]); + OUT_RINGf(chan, l->_h_inf_norm[1]); + OUT_RINGf(chan, l->_h_inf_norm[2]); + } + + if (l->_Flags & LIGHT_SPOT) { + float k[7]; + + nv10_get_spot_coeff(l, k); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPOT_CUTOFF_A(i), 7); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); + OUT_RINGf(chan, k[6]); + } +} + +#define USE_COLOR_MATERIAL(attr) \ + (ctx->Light.ColorMaterialEnabled && \ + ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_FRONT_##attr)) + +void +nv10_emit_material_ambient(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + float c_scene[3], c_factor[3]; + struct gl_light *l; + + if (USE_COLOR_MATERIAL(AMBIENT)) { + COPY_3V(c_scene, ctx->Light.Model.Ambient); + COPY_3V(c_factor, mat[MAT_ATTRIB_FRONT_EMISSION]); + + } else if (USE_COLOR_MATERIAL(EMISSION)) { + SCALE_3V(c_scene, mat[MAT_ATTRIB_FRONT_AMBIENT], + ctx->Light.Model.Ambient); + ZERO_3V(c_factor); + + } else { + COPY_3V(c_scene, ctx->Light._BaseColor[0]); + ZERO_3V(c_factor); + } + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL_AMBIENT_R, 3); + OUT_RINGf(chan, c_scene[0]); + OUT_RINGf(chan, c_scene[1]); + OUT_RINGf(chan, c_scene[2]); + + if (ctx->Light.ColorMaterialEnabled) { + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_R, 3); + OUT_RINGf(chan, c_factor[0]); + OUT_RINGf(chan, c_factor[1]); + OUT_RINGf(chan, c_factor[2]); + } + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ? + l->Ambient : + l->_MatAmbient[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_AMBIENT_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv10_emit_material_diffuse(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + struct gl_light *l; + + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_A, 1); + OUT_RINGf(chan, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]); + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ? + l->Diffuse : + l->_MatDiffuse[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIFFUSE_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv10_emit_material_specular(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_light *l; + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ? + l->Specular : + l->_MatSpecular[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPECULAR_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +static const float nv10_shininess_param[6][16] = { + { 0.70, 0.00, 0.06, 0.06, 0.05, 0.04, 0.02, 0.00, + -0.06, -0.13, -0.24, -0.36, -0.51, -0.66, -0.82, -1.00 }, + { 0.01, 1.00, -2.29, -2.77, -2.96, -3.06, -3.12, -3.18, + -3.24, -3.29, -3.36, -3.43, -3.51, -3.75, -4.33, -5.11 }, + { 0.02, 0.00, 2.28, 2.75, 2.94, 3.04, 3.1, 3.15, + 3.18, 3.22, 3.27, 3.32, 3.39, 3.48, 3.84, 5.11 }, + { 0.70, 0.00, 0.05, 0.06, 0.06, 0.06, 0.05, 0.04, + 0.02, 0.01, -0.03, -0.12, -0.25, -0.43, -0.68, -0.99 }, + { 0.01, 1.00, -1.61, -2.35, -2.67, -2.84, -2.96, -3.05, + -3.08, -3.14, -3.2, -3.26, -3.32, -3.42, -3.54, -4.21 }, + { 0.01, 0.00, 2.25, 2.73, 2.92, 3.03, 3.09, 3.15, + 3.16, 3.21, 3.25, 3.29, 3.35, 3.43, 3.56, 4.22 }, +}; + +void +nv10_get_shininess_coeff(float s, float k[6]) +{ + int i; + + for (i = 0; i < 6; i++) + k[i] = get_shine(nv10_shininess_param[i], s); +} + +void +nv10_emit_material_shininess(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + float k[6]; + + nv10_get_shininess_coeff( + CLAMP(mat[MAT_ATTRIB_FRONT_SHININESS][0], 0, 1024), + k); + + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_SHININESS(0), 6); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); +} + +void +nv10_emit_modelview(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLmatrix *m = ctx->ModelviewMatrixStack.Top; + + if (nctx->fallback != HWTNL) + return; + + if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) { + BEGIN_RING(chan, celsius, NV10TCL_MODELVIEW0_MATRIX(0), 16); + OUT_RINGm(chan, m->m); + } + + if (ctx->Light.Enabled) { + int i, j; + + BEGIN_RING(chan, celsius, + NV10TCL_INVERSE_MODELVIEW0_MATRIX(0), 12); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m->inv[4*i + j]); + } +} + +void +nv10_emit_point_parameter(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_projection(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLmatrix m; + + _math_matrix_ctr(&m); + get_viewport_scale(ctx, m.m); + + if (nctx->fallback == HWTNL) + _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); + + BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGm(chan, m.m); + + _math_matrix_dtr(&m); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c new file mode 100644 index 0000000000..698b83431b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_context.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nv20_driver.h" + +GLcontext * +nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nouveau_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nouveau_context); + if (!nctx) + return NULL; + + ctx = &nctx->base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureCoordUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 8; + ctx->Const.MaxTextureLodBias = 15; + + nv20_render_init(ctx); + + return ctx; +} + +void +nv20_context_destroy(GLcontext *ctx) +{ + nv20_render_destroy(ctx); + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_driver.h b/src/mesa/drivers/dri/nouveau/nv20_driver.h new file mode 100644 index 0000000000..2de18ee4af --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_driver.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 __NV20_DRIVER_H__ +#define __NV20_DRIVER_H__ + +enum { + NOUVEAU_STATE_TEX_SHADER = NUM_NOUVEAU_STATE, + NUM_NV20_STATE +}; + +#define NV20_TEXTURE_UNITS 4 + +/* nv20_screen.c */ +GLboolean +nv20_screen_init(struct nouveau_screen *screen); + +/* nv20_context.c */ +GLcontext * +nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv20_context_destroy(GLcontext *ctx); + +/* nv20_render.c */ +void +nv20_render_init(GLcontext *ctx); + +void +nv20_render_destroy(GLcontext *ctx); + +/* nv20_state_fb.c */ +void +nv20_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv20_emit_viewport(GLcontext *ctx, int emit); + +/* nv20_state_polygon.c */ +void +nv20_emit_point_mode(GLcontext *ctx, int emit); + +/* nv20_state_raster.c */ +void +nv20_emit_logic_opcode(GLcontext *ctx, int emit); + +/* nv20_state_tex.c */ +void +nv20_emit_tex_obj(GLcontext *ctx, int emit); + +void +nv20_emit_tex_shader(GLcontext *ctx, int emit); + +/* nv20_state_tnl.c */ +void +nv20_emit_clip_plane(GLcontext *ctx, int emit); + +void +nv20_emit_color_material(GLcontext *ctx, int emit); + +void +nv20_emit_fog(GLcontext *ctx, int emit); + +void +nv20_emit_light_model(GLcontext *ctx, int emit); + +void +nv20_emit_light_source(GLcontext *ctx, int emit); + +void +nv20_emit_material_ambient(GLcontext *ctx, int emit); + +void +nv20_emit_material_diffuse(GLcontext *ctx, int emit); + +void +nv20_emit_material_specular(GLcontext *ctx, int emit); + +void +nv20_emit_material_shininess(GLcontext *ctx, int emit); + +void +nv20_emit_modelview(GLcontext *ctx, int emit); + +void +nv20_emit_projection(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv20_render.c b/src/mesa/drivers/dri/nouveau/nv20_render.c new file mode 100644 index 0000000000..a696ac107f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_render.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +#define NUM_VERTEX_ATTRS 16 + +static void +nv20_emit_material(GLcontext *ctx, struct nouveau_array_state *a, + const void *v); + +/* Vertex attribute format. */ +static struct nouveau_attr_info nv20_vertex_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .vbo_index = 0, + .imm_method = NV20TCL_VERTEX_POS_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .vbo_index = 2, + .imm_method = NV20TCL_VERTEX_NOR_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_COLOR0] = { + .vbo_index = 3, + .imm_method = NV20TCL_VERTEX_COL_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .vbo_index = 4, + .imm_method = NV20TCL_VERTEX_COL2_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_FOG] = { + .vbo_index = 5, + .imm_method = NV20TCL_VERTEX_FOG_1F, + .imm_fields = 1, + }, + [VERT_ATTRIB_TEX0] = { + .vbo_index = 9, + .imm_method = NV20TCL_VERTEX_TX0_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX1] = { + .vbo_index = 10, + .imm_method = NV20TCL_VERTEX_TX1_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX2] = { + .vbo_index = 11, + .imm_method = NV20TCL_VERTEX_TX2_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX3] = { + .vbo_index = 12, + .imm_method = NV20TCL_VERTEX_TX3_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_GENERIC0] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC1] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC2] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC3] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC4] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC5] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC6] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC7] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC8] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC9] = { + .emit = nv20_emit_material, + }, +}; + +static int +get_hw_format(int type) +{ + switch (type) { + case GL_FLOAT: + return NV20TCL_VTXFMT_TYPE_FLOAT; + case GL_UNSIGNED_SHORT: + return NV20TCL_VTXFMT_TYPE_USHORT; + case GL_UNSIGNED_BYTE: + return NV20TCL_VTXFMT_TYPE_UBYTE; + default: + assert(0); + } +} + +static void +nv20_render_set_format(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + int i, hw_format; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + hw_format = a->stride << 8 | + a->fields << 4 | + get_hw_format(a->type); + + } else { + /* Unused attribute. */ + hw_format = NV10TCL_VTXFMT_TYPE_FLOAT; + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i), 1); + OUT_RING(chan, hw_format); + } +} + +static void +nv20_render_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + nouveau_bo_mark(bctx, kelvin, + NV20TCL_VTXBUF_ADDRESS(i), + a->bo, a->offset, 0, + 0, NV20TCL_VTXBUF_ADDRESS_DMA1, + NOUVEAU_BO_LOW | NOUVEAU_BO_OR | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + } + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTX_CACHE_INVALIDATE, 1); + OUT_RING(chan, 0); +} + +/* Vertex array rendering defs. */ +#define RENDER_LOCALS(ctx) \ + struct nouveau_grobj *kelvin = context_eng3d(ctx) + +#define BATCH_BEGIN(prim) \ + BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); \ + OUT_RING(chan, prim); +#define BATCH_END() \ + BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); \ + OUT_RING(chan, 0); + +#define MAX_PACKET 0x400 + +#define MAX_OUT_L 0x100 +#define BATCH_PACKET_L(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_VERTEX_BATCH, n); +#define BATCH_OUT_L(i, n) \ + OUT_RING(chan, ((n) - 1) << 24 | (i)); + +#define MAX_OUT_I16 0x2 +#define BATCH_PACKET_I16(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_ELEMENT_U16, n); +#define BATCH_OUT_I16(i0, i1) \ + OUT_RING(chan, (i1) << 16 | (i0)); + +#define MAX_OUT_I32 0x1 +#define BATCH_PACKET_I32(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_ELEMENT_U32, n); +#define BATCH_OUT_I32(i) \ + OUT_RING(chan, i); + +#define IMM_PACKET(m, n) \ + BEGIN_RING(chan, kelvin, m, n); +#define IMM_OUT(x) \ + OUT_RINGf(chan, x); + +#define TAG(x) nv20_##x +#include "nouveau_render_t.c" diff --git a/src/mesa/drivers/dri/nouveau/nv20_screen.c b/src/mesa/drivers/dri/nouveau/nv20_screen.c new file mode 100644 index 0000000000..1d29fc9976 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_screen.c @@ -0,0 +1,483 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +static const struct nouveau_driver nv20_driver; + +static void +nv20_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *kelvin = screen->eng3d; + const unsigned chipset = screen->device->chipset; + int i; + + BEGIN_RING(chan, kelvin, NV20TCL_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + BEGIN_RING(chan, kelvin, NV20TCL_DMA_TEXTURE0, 2); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->gart->handle); + BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 2); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + + BEGIN_RING(chan, kelvin, NV20TCL_DMA_QUERY, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING (chan, 0xfff << 16 | 0x0); + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING (chan, 0xfff << 16 | 0x0); + + for (i = 1; i < NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE; i++) { + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_MODE, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, 0x17e0, 3); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 1.0); + + if (chipset >= 0x25) { + BEGIN_RING(chan, kelvin, NV20TCL_TX_RCOMP, 1); + OUT_RING (chan, NV20TCL_TX_RCOMP_LEQUAL | 0xdb0); + } else { + BEGIN_RING(chan, kelvin, 0x1e68, 1); + OUT_RING (chan, 0x4b800000); /* 16777216.000000 */ + BEGIN_RING(chan, kelvin, NV20TCL_TX_RCOMP, 1); + OUT_RING (chan, NV20TCL_TX_RCOMP_LEQUAL); + } + + BEGIN_RING(chan, kelvin, 0x290, 1); + OUT_RING (chan, 0x10 << 16 | 1); + BEGIN_RING(chan, kelvin, 0x9fc, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, 0x1d80, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, kelvin, 0x9f8, 1); + OUT_RING (chan, 4); + BEGIN_RING(chan, kelvin, 0x17ec, 3); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 1.0); + OUT_RINGf (chan, 0.0); + + if (chipset >= 0x25) { + BEGIN_RING(chan, kelvin, 0x1d88, 1); + OUT_RING (chan, 3); + + BEGIN_RING(chan, kelvin, NV25TCL_DMA_IN_MEMORY9, 1); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, kelvin, NV25TCL_DMA_IN_MEMORY8, 1); + OUT_RING (chan, chan->vram->handle); + } + + BEGIN_RING(chan, kelvin, NV20TCL_DMA_FENCE, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, 0x1e98, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_NOTIFY, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, 0x120, 3); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 2); + + if (chipset >= 0x25) { + BEGIN_RING(chan, kelvin, 0x022c, 2); + OUT_RING (chan, 0x280); + OUT_RING (chan, 0x07d28000); + + BEGIN_RING(chan, kelvin, 0x1da4, 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2); + OUT_RING (chan, 0 << 16 | 0); + OUT_RING (chan, 0 << 16 | 0); + + BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING (chan, NV20TCL_ALPHA_FUNC_FUNC_ALWAYS); + OUT_RING (chan, 0); + + for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; i++) { + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_CULL_MODE, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(0), 4); + OUT_RING (chan, 0x30d410d0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_RGB(0), 4); + OUT_RING (chan, 0x00000c00); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_ENABLE, 1); + OUT_RING (chan, 0x00011101); + BEGIN_RING(chan, kelvin, NV20TCL_RC_FINAL0, 2); + OUT_RING (chan, 0x130e0300); + OUT_RING (chan, 0x0c091c80); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_ALPHA(0), 4); + OUT_RING (chan, 0x00000c00); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_RGB(0), 4); + OUT_RING (chan, 0x20c400c0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_COLOR0, 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_CONSTANT_COLOR0(0), 4); + OUT_RING (chan, 0x035125a0); + OUT_RING (chan, 0); + OUT_RING (chan, 0x40002000); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_MULTISAMPLE_CONTROL, 1); + OUT_RING (chan, 0xffff0000); + BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 4); + OUT_RING (chan, NV20TCL_BLEND_FUNC_SRC_ONE); + OUT_RING (chan, NV20TCL_BLEND_FUNC_DST_ZERO); + OUT_RING (chan, 0); + OUT_RING (chan, NV20TCL_BLEND_EQUATION_FUNC_ADD); + BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7); + OUT_RING (chan, 0xff); + OUT_RING (chan, NV20TCL_STENCIL_FUNC_FUNC_ALWAYS); + OUT_RING (chan, 0); + OUT_RING (chan, 0xff); + OUT_RING (chan, NV20TCL_STENCIL_OP_FAIL_KEEP); + OUT_RING (chan, NV20TCL_STENCIL_OP_ZFAIL_KEEP); + OUT_RING (chan, NV20TCL_STENCIL_OP_ZPASS_KEEP); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING (chan, 0); + OUT_RING (chan, NV20TCL_COLOR_LOGIC_OP_OP_COPY); + BEGIN_RING(chan, kelvin, 0x17cc, 1); + OUT_RING (chan, 0); + if (chipset >= 0x25) { + BEGIN_RING(chan, kelvin, 0x1d84, 1); + OUT_RING (chan, 1); + } + BEGIN_RING(chan, kelvin, NV20TCL_LIGHTING_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL, 1); + OUT_RING (chan, NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL); + BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_ENABLED_LIGHTS, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_NORMALIZE_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_PATTERN(0), + NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE); + for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; i++) { + OUT_RING(chan, 0xffffffff); + } + + BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1); + OUT_RING (chan, NV20TCL_DEPTH_FUNC_LESS); + BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); + BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1); + OUT_RING (chan, 1); + if (chipset < 0x25) { + BEGIN_RING(chan, kelvin, 0x1d84, 1); + OUT_RING (chan, 3); + } + BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); + if (chipset >= 0x25) + OUT_RINGf (chan, 1.0); + else + OUT_RING (chan, 8); + + if (chipset >= 0x25) { + BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, 0x0a1c, 1); + OUT_RING (chan, 0x800); + } else { + BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, kelvin, NV20TCL_LINE_WIDTH, 1); + OUT_RING (chan, 8); + BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (chan, NV20TCL_POLYGON_MODE_FRONT_FILL); + OUT_RING (chan, NV20TCL_POLYGON_MODE_BACK_FILL); + BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2); + OUT_RING (chan, NV20TCL_CULL_FACE_BACK); + OUT_RING (chan, NV20TCL_FRONT_FACE_CCW); + BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 1); + OUT_RING (chan, NV20TCL_SHADE_MODEL_SMOOTH); + BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0), + 4 * NV20TCL_TX_GEN_S__SIZE); + for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; i++) + OUT_RING(chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf (chan, 1.5); + OUT_RINGf (chan, -0.090168); + OUT_RINGf (chan, 0.0); + BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 2); + OUT_RING (chan, NV20TCL_FOG_MODE_EXP_SIGNED); + OUT_RING (chan, NV20TCL_FOG_COORD_FOG); + BEGIN_RING(chan, kelvin, NV20TCL_FOG_ENABLE, 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_ENGINE, 1); + OUT_RING (chan, NV20TCL_ENGINE_FIXED); + + for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; i++) { + BEGIN_RING(chan, kelvin, NV20TCL_TX_MATRIX_ENABLE(i), 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + for (i = 0; i < 12; i++) { + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + } + + BEGIN_RING(chan, kelvin, NV20TCL_EDGEFLAG_ENABLE, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1); + OUT_RING (chan, 0x00010101); + BEGIN_RING(chan, kelvin, NV20TCL_CLEAR_VALUE, 1); + OUT_RING (chan, 0); + + BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_RANGE_NEAR, 2); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 16777216.0); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 16777215.0); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_SCALE_X, 4); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 16777215.0 * 0.5); + OUT_RINGf (chan, 65535.0); + + FIRE_RING(chan); +} + +GLboolean +nv20_screen_init(struct nouveau_screen *screen) +{ + unsigned chipset = screen->device->chipset; + unsigned kelvin_class; + int ret; + + screen->driver = &nv20_driver; + + /* 2D engine */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + if (chipset >= 0x25) + kelvin_class = NV25TCL; + else + kelvin_class = NV20TCL; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, kelvin_class, + &screen->eng3d); + if (ret) + return GL_FALSE; + + nv20_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv20_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv20_driver = { + .screen_destroy = nv20_screen_destroy, + .context_create = nv20_context_create, + .context_destroy = nv20_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv10_emit_alpha_func, + nv10_emit_blend_color, + nv10_emit_blend_equation, + nv10_emit_blend_func, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv10_emit_color_mask, + nv20_emit_color_material, + nv10_emit_cull_face, + nv10_emit_front_face, + nv10_emit_depth, + nv10_emit_dither, + nv10_emit_frag, + nv20_emit_framebuffer, + nv20_emit_fog, + nv10_emit_index_mask, + nv10_emit_light_enable, + nv20_emit_light_model, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv10_emit_line_stipple, + nv10_emit_line_mode, + nv20_emit_logic_opcode, + nv20_emit_material_ambient, + nv20_emit_material_ambient, + nv20_emit_material_diffuse, + nv20_emit_material_diffuse, + nv20_emit_material_specular, + nv20_emit_material_specular, + nv20_emit_material_shininess, + nv20_emit_material_shininess, + nv20_emit_modelview, + nv20_emit_point_mode, + nv10_emit_point_parameter, + nv10_emit_polygon_mode, + nv10_emit_polygon_offset, + nv10_emit_polygon_stipple, + nv20_emit_projection, + nv10_emit_render_mode, + nv10_emit_scissor, + nv10_emit_shade_model, + nv10_emit_stencil_func, + nv10_emit_stencil_mask, + nv10_emit_stencil_op, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_viewport, + nv20_emit_tex_shader + }, + .num_emit = NUM_NV20_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_fb.c b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c new file mode 100644 index 0000000000..869acd6e31 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + case MESA_FORMAT_Z16: + return 0x10; + case MESA_FORMAT_Z24_S8: + return 0x20; + default: + assert(0); + } +} + +void +nv20_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + unsigned rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR; + unsigned rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, kelvin, NV20TCL_COLOR_OFFSET, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, kelvin, NV20TCL_ZETA_OFFSET, + s->bo, 0, bo_flags); + } + + BEGIN_RING(chan, kelvin, NV20TCL_RT_FORMAT, 2); + OUT_RING(chan, rt_format); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + /* Recompute the viewport/scissor state. */ + context_dirty(ctx, VIEWPORT); + context_dirty(ctx, SCISSOR); +} + +void +nv20_emit_viewport(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + float a[4] = {}; + int i; + + get_viewport_translate(ctx, a); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); + for (i = 0; i < 4; i++) + OUT_RINGf(chan, a[i]); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, (fb->Width - 1) << 16); + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, (fb->Height - 1) << 16); + + context_dirty(ctx, PROJECTION); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c b/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c new file mode 100644 index 0000000000..3a320e2dac --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +void +nv20_emit_point_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); + if (context_chipset(ctx) >= 0x25) + OUT_RINGf(chan, ctx->Point.Size); + else + OUT_RING(chan, (uint32_t)(ctx->Point.Size * 8)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_raster.c b/src/mesa/drivers/dri/nouveau/nv20_state_raster.c new file mode 100644 index 0000000000..b43b29bb23 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_raster.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +void +nv20_emit_logic_opcode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING(chan, ctx->Color.ColorLogicOpEnabled ? 1 : 0); + OUT_RING(chan, nvgl_logicop_func(ctx->Color.LogicOp)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c new file mode 100644 index 0000000000..d01e91f8ee --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_texture.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv20_driver.h" + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return NV20TCL_TX_FORMAT_FORMAT_A8R8G8B8; + + case MESA_FORMAT_ARGB1555: + return NV20TCL_TX_FORMAT_FORMAT_A1R5G5B5; + + case MESA_FORMAT_ARGB4444: + return NV20TCL_TX_FORMAT_FORMAT_A4R4G4B4; + + case MESA_FORMAT_RGB565: + return NV20TCL_TX_FORMAT_FORMAT_R5G6B5; + + case MESA_FORMAT_A8: + return NV20TCL_TX_FORMAT_FORMAT_A8; + + case MESA_FORMAT_L8: + return NV20TCL_TX_FORMAT_FORMAT_L8; + + case MESA_FORMAT_CI8: + return NV20TCL_TX_FORMAT_FORMAT_INDEX8; + + default: + assert(0); + } +} + +void +nv20_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct gl_texture_object *t; + struct nouveau_surface *s; + struct gl_texture_image *ti; + uint32_t tx_format, tx_filter, tx_wrap, tx_enable; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) { + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING(chan, 0); + + context_dirty(ctx, TEX_SHADER); + return; + } + + t = ctx->Texture.Unit[i]._Current; + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + ti = t->Image[0][t->BaseLevel]; + + nouveau_texture_validate(ctx, t); + + /* Recompute the texturing registers. */ + tx_format = ti->DepthLog2 << 28 + | ti->HeightLog2 << 24 + | ti->WidthLog2 << 20 + | get_tex_format(ti) + | NV20TCL_TX_FORMAT_DIMS_2D + | NV20TCL_TX_FORMAT_NO_BORDER + | 1 << 16; + + tx_wrap = nvgl_wrap_mode(t->WrapR) << 16 + | nvgl_wrap_mode(t->WrapT) << 8 + | nvgl_wrap_mode(t->WrapS) << 0; + + tx_filter = nvgl_filter_mode(t->MagFilter) << 24 + | nvgl_filter_mode(t->MinFilter) << 16; + + tx_enable = NV20TCL_TX_ENABLE_ENABLE + | log2i(t->MaxAnisotropy) << 4; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + int lod_min = t->MinLod; + int lod_max = MIN2(t->MaxLod, t->_MaxLambda); + int lod_bias = t->LodBias + + ctx->Texture.Unit[i].LodBias; + + lod_max = CLAMP(lod_max, 0, 15); + lod_min = CLAMP(lod_min, 0, 15); + lod_bias = CLAMP(lod_bias, 0, 15); + + tx_format |= NV20TCL_TX_FORMAT_MIPMAP; + tx_filter |= lod_bias << 8; + tx_enable |= lod_min << 26 + | lod_max << 14; + } + + /* Write it to the hardware. */ + nouveau_bo_mark(bctx, kelvin, NV20TCL_TX_FORMAT(i), + s->bo, tx_format, 0, + NV20TCL_TX_FORMAT_DMA0, + NV20TCL_TX_FORMAT_DMA1, + bo_flags | NOUVEAU_BO_OR); + + nouveau_bo_markl(bctx, kelvin, NV20TCL_TX_OFFSET(i), + s->bo, 0, bo_flags); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_WRAP(i), 1); + OUT_RING(chan, tx_wrap); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_FILTER(i), 1); + OUT_RING(chan, tx_filter); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING(chan, tx_enable); + + context_dirty(ctx, TEX_SHADER); +} + +void +nv20_emit_tex_shader(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + uint32_t tx_shader_op = 0; + int i; + + for (i = 0; i < NV20_TEXTURE_UNITS; i++) { + if (!ctx->Texture.Unit[i]._ReallyEnabled) + continue; + + tx_shader_op |= NV20TCL_TX_SHADER_OP_TX0_TEXTURE_2D << 5 * i; + } + + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1); + OUT_RING(chan, tx_shader_op); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c new file mode 100644 index 0000000000..0d566064f6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, 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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +void +nv20_emit_clip_plane(GLcontext *ctx, int emit) +{ +} + +static inline unsigned +get_material_bitmask(unsigned m) +{ + unsigned ret = 0; + + if (m & MAT_BIT_FRONT_EMISSION) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_EMISSION_COL1; + if (m & MAT_BIT_FRONT_AMBIENT) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_AMBIENT_COL1; + if (m & MAT_BIT_FRONT_DIFFUSE) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_DIFFUSE_COL1; + if (m & MAT_BIT_FRONT_SPECULAR) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_SPECULAR_COL1; + + if (m & MAT_BIT_BACK_EMISSION) + ret |= NV20TCL_COLOR_MATERIAL_BACK_EMISSION_COL1; + if (m & MAT_BIT_BACK_AMBIENT) + ret |= NV20TCL_COLOR_MATERIAL_BACK_AMBIENT_COL1; + if (m & MAT_BIT_BACK_DIFFUSE) + ret |= NV20TCL_COLOR_MATERIAL_BACK_DIFFUSE_COL1; + if (m & MAT_BIT_BACK_SPECULAR) + ret |= NV20TCL_COLOR_MATERIAL_BACK_SPECULAR_COL1; + + return ret; +} + +void +nv20_emit_color_material(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MATERIAL, 1); + OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0); +} + +static unsigned +get_fog_mode_signed(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV20TCL_FOG_MODE_LINEAR_SIGNED; + case GL_EXP: + return NV20TCL_FOG_MODE_EXP_SIGNED; + case GL_EXP2: + return NV20TCL_FOG_MODE_EXP2_SIGNED; + default: + assert(0); + } +} + +static unsigned +get_fog_mode_unsigned(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV20TCL_FOG_MODE_LINEAR_UNSIGNED; + case GL_EXP: + return NV20TCL_FOG_MODE_EXP_UNSIGNED; + case GL_EXP2: + return NV20TCL_FOG_MODE_EXP2_UNSIGNED; + default: + assert(0); + } +} + +static unsigned +get_fog_source(unsigned source) +{ + switch (source) { + case GL_FOG_COORDINATE_EXT: + return NV20TCL_FOG_COORD_FOG; + case GL_FRAGMENT_DEPTH_EXT: + return NV20TCL_FOG_COORD_DIST_ORTHOGONAL_ABS; + default: + assert(0); + } +} + +void +nv20_emit_fog(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_fog_attrib *f = &ctx->Fog; + unsigned source = nctx->fallback == HWTNL ? + f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; + float k[3]; + + nv10_get_fog_coeff(ctx, k); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 4); + OUT_RING(chan, (source == GL_FOG_COORDINATE_EXT ? + get_fog_mode_signed(f->Mode) : + get_fog_mode_unsigned(f->Mode))); + OUT_RING(chan, get_fog_source(source)); + OUT_RING(chan, f->Enabled ? 1 : 0); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); +} + +void +nv20_emit_light_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_lightmodel *m = &ctx->Light.Model; + + BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL, 1); + OUT_RING(chan, ((m->LocalViewer ? + NV20TCL_LIGHT_MODEL_VIEWER_LOCAL : + NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL) | + (m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? + NV20TCL_LIGHT_MODEL_SEPARATE_SPECULAR : + 0))); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1); + OUT_RING(chan, ctx->Light.Model.TwoSide ? 1 : 0); +} + +void +nv20_emit_light_source(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_light *l = &ctx->Light.Light[i]; + + if (l->_Flags & LIGHT_POSITIONAL) { + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_POSITION_X(i), 3); + OUT_RINGf(chan, l->_Position[0]); + OUT_RINGf(chan, l->_Position[1]); + OUT_RINGf(chan, l->_Position[2]); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_ATTENUATION_CONSTANT(i), 3); + OUT_RINGf(chan, l->ConstantAttenuation); + OUT_RINGf(chan, l->LinearAttenuation); + OUT_RINGf(chan, l->QuadraticAttenuation); + + } else { + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_DIRECTION_X(i), 3); + OUT_RINGf(chan, l->_VP_inf_norm[0]); + OUT_RINGf(chan, l->_VP_inf_norm[1]); + OUT_RINGf(chan, l->_VP_inf_norm[2]); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_HALF_VECTOR_X(i), 3); + OUT_RINGf(chan, l->_h_inf_norm[0]); + OUT_RINGf(chan, l->_h_inf_norm[1]); + OUT_RINGf(chan, l->_h_inf_norm[2]); + } + + if (l->_Flags & LIGHT_SPOT) { + float k[7]; + + nv10_get_spot_coeff(l, k); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_SPOT_CUTOFF_A(i), 7); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); + OUT_RINGf(chan, k[6]); + } +} + +#define USE_COLOR_MATERIAL(attr, side) \ + (ctx->Light.ColorMaterialEnabled && \ + ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_##attr(side))) + +void +nv20_emit_material_ambient(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t m_scene[] = { NV20TCL_LIGHT_MODEL_FRONT_AMBIENT_R, + NV20TCL_LIGHT_MODEL_BACK_AMBIENT_R }; + uint32_t m_factor[] = { NV20TCL_MATERIAL_FACTOR_FRONT_R, + NV20TCL_MATERIAL_FACTOR_BACK_R }; + float c_scene[3], c_factor[3]; + struct gl_light *l; + + if (USE_COLOR_MATERIAL(AMBIENT, side)) { + COPY_3V(c_scene, mat[MAT_ATTRIB_EMISSION(side)]); + COPY_3V(c_factor, ctx->Light.Model.Ambient); + + } else if (USE_COLOR_MATERIAL(EMISSION, side)) { + SCALE_3V(c_scene, mat[MAT_ATTRIB_AMBIENT(side)], + ctx->Light.Model.Ambient); + ASSIGN_3V(c_factor, 1, 1, 1); + + } else { + COPY_3V(c_scene, ctx->Light._BaseColor[side]); + ZERO_3V(c_factor); + } + + BEGIN_RING(chan, kelvin, m_scene[side], 3); + OUT_RINGf(chan, c_scene[0]); + OUT_RINGf(chan, c_scene[1]); + OUT_RINGf(chan, c_scene[2]); + + if (ctx->Light.ColorMaterialEnabled) { + BEGIN_RING(chan, kelvin, m_factor[side], 3); + OUT_RINGf(chan, c_factor[0]); + OUT_RINGf(chan, c_factor[1]); + OUT_RINGf(chan, c_factor[2]); + } + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_AMBIENT_R(i), + NV20TCL_LIGHT_BACK_AMBIENT_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(AMBIENT, side) ? + l->Ambient : + l->_MatAmbient[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_diffuse(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t m_factor[] = { NV20TCL_MATERIAL_FACTOR_FRONT_A, + NV20TCL_MATERIAL_FACTOR_BACK_A }; + struct gl_light *l; + + BEGIN_RING(chan, kelvin, m_factor[side], 1); + OUT_RINGf(chan, mat[MAT_ATTRIB_DIFFUSE(side)][3]); + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_DIFFUSE_R(i), + NV20TCL_LIGHT_BACK_DIFFUSE_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(DIFFUSE, side) ? + l->Diffuse : + l->_MatDiffuse[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_specular(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_light *l; + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_SPECULAR_R(i), + NV20TCL_LIGHT_BACK_SPECULAR_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(SPECULAR, side) ? + l->Specular : + l->_MatSpecular[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_shininess(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SHININESS; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t mthd[] = { NV20TCL_FRONT_MATERIAL_SHININESS(0), + NV20TCL_BACK_MATERIAL_SHININESS(0) }; + float k[6]; + + nv10_get_shininess_coeff( + CLAMP(mat[MAT_ATTRIB_SHININESS(side)][0], 0, 1024), + k); + + BEGIN_RING(chan, kelvin, mthd[side], 6); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); +} + +void +nv20_emit_modelview(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLmatrix *m = ctx->ModelviewMatrixStack.Top; + + if (nctx->fallback != HWTNL) + return; + + if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) { + BEGIN_RING(chan, kelvin, NV20TCL_MODELVIEW0_MATRIX(0), 16); + OUT_RINGm(chan, m->m); + } + + if (ctx->Light.Enabled) { + int i, j; + + BEGIN_RING(chan, kelvin, + NV20TCL_INVERSE_MODELVIEW0_MATRIX(0), 12); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m->inv[4*i + j]); + } +} + +void +nv20_emit_projection(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLmatrix m; + + _math_matrix_ctr(&m); + get_viewport_scale(ctx, m.m); + + if (nctx->fallback == HWTNL) + _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); + + BEGIN_RING(chan, kelvin, NV20TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGm(chan, m.m); + + _math_matrix_dtr(&m); +} diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index e389e1c87b..67e9240505 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/r128/r128_dd.c b/src/mesa/drivers/dri/r128/r128_dd.c index dfe47f2dd6..64dec70cdd 100644 --- a/src/mesa/drivers/dri/r128/r128_dd.c +++ b/src/mesa/drivers/dri/r128/r128_dd.c @@ -34,12 +34,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_ioctl.h" -#include "r128_state.h" #include "r128_dd.h" -#include "swrast/swrast.h" #include "main/context.h" -#include "main/framebuffer.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/r128/r128_lock.c b/src/mesa/drivers/dri/r128/r128_lock.c index 9bc3515b5a..c1fa068d1f 100644 --- a/src/mesa/drivers/dri/r128/r128_lock.c +++ b/src/mesa/drivers/dri/r128/r128_lock.c @@ -33,8 +33,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_lock.h" -#include "r128_tex.h" -#include "r128_state.h" #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c index 80b265811e..ef6b5a35c4 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.c +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -37,7 +37,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_ioctl.h" #include "r128_span.h" -#include "r128_tris.h" #include "main/context.h" #include "main/imports.h" diff --git a/src/mesa/drivers/dri/r128/r128_span.c b/src/mesa/drivers/dri/r128/r128_span.c index 0413e5b4f1..2fbe93c590 100644 --- a/src/mesa/drivers/dri/r128/r128_span.c +++ b/src/mesa/drivers/dri/r128/r128_span.c @@ -35,9 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_ioctl.h" -#include "r128_state.h" #include "r128_span.h" -#include "r128_tex.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c index 2254a7a4ff..42f6dd7388 100644 --- a/src/mesa/drivers/dri/r128/r128_state.c +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -47,8 +47,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" - #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/r128/r128_tex.c b/src/mesa/drivers/dri/r128/r128_tex.c index f1be7cc1c4..24fbf8f519 100644 --- a/src/mesa/drivers/dri/r128/r128_tex.c +++ b/src/mesa/drivers/dri/r128/r128_tex.c @@ -33,21 +33,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r128_context.h" -#include "r128_state.h" #include "r128_ioctl.h" -#include "r128_tris.h" #include "r128_tex.h" #include "r128_texobj.h" -#include "main/context.h" -#include "main/macros.h" #include "main/simple_list.h" #include "main/enums.h" #include "main/texstore.h" #include "main/teximage.h" #include "main/texobj.h" #include "main/imports.h" -#include "main/colormac.h" #include "main/texobj.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/r128/r128_texmem.c b/src/mesa/drivers/dri/r128/r128_texmem.c index 4ddcb86bcd..5eec8c08cd 100644 --- a/src/mesa/drivers/dri/r128/r128_texmem.c +++ b/src/mesa/drivers/dri/r128/r128_texmem.c @@ -33,12 +33,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r128_context.h" -#include "r128_state.h" #include "r128_ioctl.h" -#include "r128_tris.h" #include "r128_tex.h" -#include "main/context.h" #include "main/macros.h" #include "main/simple_list.h" #include "main/imports.h" diff --git a/src/mesa/drivers/dri/r128/r128_texstate.c b/src/mesa/drivers/dri/r128/r128_texstate.c index cb2b5f9536..2505b5cd65 100644 --- a/src/mesa/drivers/dri/r128/r128_texstate.c +++ b/src/mesa/drivers/dri/r128/r128_texstate.c @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "r128_context.h" -#include "r128_state.h" #include "r128_ioctl.h" #include "r128_tris.h" #include "r128_tex.h" diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 8212dc1203..14eb96c1ba 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -9,10 +9,6 @@ LIBNAME = r200_dri.so MINIGLX_SOURCES = server/radeon_dri.c -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif @@ -29,8 +25,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_queryobj.c \ radeon_span.c \ - radeon_texture.c - + radeon_texture.c \ + radeon_tex_copy.c DRIVER_SOURCES = r200_context.c \ r200_ioctl.c \ @@ -46,6 +42,7 @@ DRIVER_SOURCES = r200_context.c \ r200_sanity.c \ r200_fragshader.c \ r200_vertprog.c \ + r200_blit.c \ radeon_screen.c \ $(EGL_SOURCES) \ $(RADEON_COMMON_SOURCES) \ @@ -55,7 +52,7 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) X86_SOURCES = -DRIVER_DEFINES = -DRADEON_R200 -Wall +DRIVER_DEFINES = -DRADEON_R200 DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r200/r200_blit.c b/src/mesa/drivers/dri/r200/r200_blit.c new file mode 100644 index 0000000000..e446d532cf --- /dev/null +++ b/src/mesa/drivers/dri/r200/r200_blit.c @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * 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, 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 COPYRIGHT OWNER(S) 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 "radeon_common.h" +#include "r200_context.h" +#include "r200_blit.h" + +static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, + int reg, int count) +{ + if (count) + return CP_PACKET0(reg, count - 1); + return CP_PACKET2; +} + +/* common formats supported as both textures and render targets */ +static unsigned is_blit_supported(gl_format mesa_format) +{ + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_A8: + break; + default: + return 0; + } + + /* ??? */ + if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + +static inline void emit_vtx_state(struct r200_context *r200) +{ + BATCH_LOCALS(&r200->radeon); + + BEGIN_BATCH(14); + if (r200->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, 0); + } else { + OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS); + } + OUT_BATCH_REGVAL(R200_SE_VAP_CNTL, (R200_VAP_FORCE_W_TO_ONE | + (9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT))); + OUT_BATCH_REGVAL(R200_SE_VTX_STATE_CNTL, 0); + OUT_BATCH_REGVAL(R200_SE_VTE_CNTL, 0); + OUT_BATCH_REGVAL(R200_SE_VTX_FMT_0, R200_VTX_XY); + OUT_BATCH_REGVAL(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT)); + OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX)); + END_BATCH(); +} + +static void inline emit_tx_setup(struct r200_context *r200, + gl_format mesa_format, + struct radeon_bo *bo, + intptr_t offset, + unsigned width, + unsigned height, + unsigned pitch) +{ + uint32_t txformat = R200_TXFORMAT_NON_POWER2; + BATCH_LOCALS(&r200->radeon); + + assert(width <= 2047); + assert(height <= 2047); + assert(offset % 32 == 0); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + txformat |= R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_XRGB8888: + txformat |= R200_TXFORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + txformat |= R200_TXFORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + txformat |= R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_ARGB1555: + txformat |= R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_A8: + txformat |= R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + default: + break; + } + + BEGIN_BATCH(28); + OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); + OUT_BATCH_REGVAL(R200_PP_CNTL_X, 0); + OUT_BATCH_REGVAL(R200_PP_TXMULTI_CTL_0, 0); + OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_OP_MADD)); + OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0); + OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD)); + OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0); + OUT_BATCH_REGVAL(R200_PP_TXFILTER_0, (R200_CLAMP_S_CLAMP_LAST | + R200_CLAMP_T_CLAMP_LAST | + R200_MAG_FILTER_NEAREST | + R200_MIN_FILTER_NEAREST)); + OUT_BATCH_REGVAL(R200_PP_TXFORMAT_0, txformat); + OUT_BATCH_REGVAL(R200_PP_TXFORMAT_X_0, 0); + OUT_BATCH_REGVAL(R200_PP_TXSIZE_0, ((width - 1) | + ((height - 1) << RADEON_TEX_VSIZE_SHIFT))); + OUT_BATCH_REGVAL(R200_PP_TXPITCH_0, pitch * _mesa_get_format_bytes(mesa_format) - 32); + + OUT_BATCH_REGSEQ(R200_PP_TXOFFSET_0, 1); + OUT_BATCH_RELOC(0, bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + + END_BATCH(); +} + +static inline void emit_cb_setup(struct r200_context *r200, + struct radeon_bo *bo, + intptr_t offset, + gl_format mesa_format, + unsigned pitch, + unsigned width, + unsigned height) +{ + uint32_t dst_pitch = pitch; + uint32_t dst_format = 0; + BATCH_LOCALS(&r200->radeon); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + dst_format = RADEON_COLOR_FORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + dst_format = RADEON_COLOR_FORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + dst_format = RADEON_COLOR_FORMAT_ARGB4444; + break; + case MESA_FORMAT_ARGB1555: + dst_format = RADEON_COLOR_FORMAT_ARGB1555; + break; + case MESA_FORMAT_A8: + dst_format = RADEON_COLOR_FORMAT_RGB8; + break; + default: + break; + } + + BEGIN_BATCH_NO_AUTOSTATE(22); + OUT_BATCH_REGVAL(R200_RE_AUX_SCISSOR_CNTL, 0); + OUT_BATCH_REGVAL(R200_RE_CNTL, 0); + OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0); + OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, ((width << RADEON_RE_WIDTH_SHIFT) | + (height << RADEON_RE_HEIGHT_SHIFT))); + OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff); + OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); + OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format); + + OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1); + OUT_BATCH_RELOC(0, bo, 0, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1); + OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + + END_BATCH(); +} + +static GLboolean validate_buffers(struct r200_context *r200, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(r200->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(r200->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs, + first_elem(&r200->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Calculate texcoords for given image region. + * Output values are [minx, maxx, miny, maxy] + */ +static inline void calc_tex_coords(float img_width, float img_height, + float x, float y, + float reg_width, float reg_height, + unsigned flip_y, float *buf) +{ + buf[0] = x / img_width; + buf[1] = buf[0] + reg_width / img_width; + buf[2] = y / img_height; + buf[3] = buf[2] + reg_height / img_height; + if (flip_y) + { + buf[2] = 1.0 - buf[2]; + buf[3] = 1.0 - buf[3]; + } +} + +static inline void emit_draw_packet(struct r200_context *r200, + unsigned src_width, unsigned src_height, + unsigned src_x_offset, unsigned src_y_offset, + unsigned dst_x_offset, unsigned dst_y_offset, + unsigned reg_width, unsigned reg_height, + unsigned flip_y) +{ + float texcoords[4]; + float verts[12]; + BATCH_LOCALS(&r200->radeon); + + calc_tex_coords(src_width, src_height, + src_x_offset, src_y_offset, + reg_width, reg_height, + flip_y, texcoords); + + verts[0] = dst_x_offset; + verts[1] = dst_y_offset + reg_height; + verts[2] = texcoords[0]; + verts[3] = texcoords[3]; + + verts[4] = dst_x_offset + reg_width; + verts[5] = dst_y_offset + reg_height; + verts[6] = texcoords[1]; + verts[7] = texcoords[3]; + + verts[8] = dst_x_offset + reg_width; + verts[9] = dst_y_offset; + verts[10] = texcoords[1]; + verts[11] = texcoords[2]; + + BEGIN_BATCH(14); + OUT_BATCH(R200_CP_CMD_3D_DRAW_IMMD_2 | (12 << 16)); + OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING | + RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | + (3 << 16)); + OUT_BATCH_TABLE(verts, 12); + END_BATCH(); +} + +/** + * Copy a region of [@a width x @a height] pixels from source buffer + * to destination buffer. + * @param[in] r200 r200 context + * @param[in] src_bo source radeon buffer object + * @param[in] src_offset offset of the source image in the @a src_bo + * @param[in] src_mesaformat source image format + * @param[in] src_pitch aligned source image width + * @param[in] src_width source image width + * @param[in] src_height source image height + * @param[in] src_x_offset x offset in the source image + * @param[in] src_y_offset y offset in the source image + * @param[in] dst_bo destination radeon buffer object + * @param[in] dst_offset offset of the destination image in the @a dst_bo + * @param[in] dst_mesaformat destination image format + * @param[in] dst_pitch aligned destination image width + * @param[in] dst_width destination image width + * @param[in] dst_height destination image height + * @param[in] dst_x_offset x offset in the destination image + * @param[in] dst_y_offset y offset in the destination image + * @param[in] width region width + * @param[in] height region height + * @param[in] flip_y set if y coords of the source image need to be flipped + */ +unsigned r200_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) +{ + struct r200_context *r200 = R200_CONTEXT(ctx); + + if (!is_blit_supported(dst_mesaformat)) + return GL_FALSE; + + /* Make sure that colorbuffer has even width - hw limitation */ + if (dst_pitch % 2 > 0) + ++dst_pitch; + + /* Rendering to small buffer doesn't work. + * Looks like a hw limitation. + */ + if (dst_pitch < 32) + return GL_FALSE; + + /* Need to clamp the region size to make sure + * we don't read outside of the source buffer + * or write outside of the destination buffer. + */ + if (reg_width + src_x_offset > src_width) + reg_width = src_width - src_x_offset; + if (reg_height + src_y_offset > src_height) + reg_height = src_height - src_y_offset; + if (reg_width + dst_x_offset > dst_width) + reg_width = dst_width - dst_x_offset; + if (reg_height + dst_y_offset > dst_height) + reg_height = dst_height - dst_y_offset; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (src_offset % 32 || dst_offset % 32) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: size [%d x %d], pitch %d, " + "offset [%d x %d], format %s, bo %p\n", + src_width, src_height, src_pitch, + src_x_offset, src_y_offset, + _mesa_get_format_name(src_mesaformat), + src_bo); + fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n", + dst_pitch, dst_x_offset, dst_y_offset, + _mesa_get_format_name(dst_mesaformat), dst_bo); + fprintf(stderr, "region: %d x %d\n", reg_width, reg_height); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(r200->radeon.glCtx); + + rcommonEnsureCmdBufSpace(&r200->radeon, 78, __FUNCTION__); + + if (!validate_buffers(r200, src_bo, dst_bo)) + return GL_FALSE; + + /* 14 */ + emit_vtx_state(r200); + /* 28 */ + emit_tx_setup(r200, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch); + /* 22 */ + emit_cb_setup(r200, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height); + /* 14 */ + emit_draw_packet(r200, src_width, src_height, + src_x_offset, src_y_offset, + dst_x_offset, dst_y_offset, + reg_width, reg_height, + flip_y); + + radeonFlush(ctx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/r200/r200_blit.h b/src/mesa/drivers/dri/r200/r200_blit.h new file mode 100644 index 0000000000..38487266ae --- /dev/null +++ b/src/mesa/drivers/dri/r200/r200_blit.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * 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, 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 COPYRIGHT OWNER(S) 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 R200_BLIT_H +#define R200_BLIT_H + +void r200_blit_init(struct r200_context *r200); + +unsigned r200_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned width, + unsigned height, + unsigned flip_y); + +#endif // R200_BLIT_H diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index 1d1bea6f5f..2f2b8d94dc 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -35,15 +35,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/macros.h" #include "main/context.h" -#include "swrast/swrast.h" #include "main/simple_list.h" #include "radeon_common.h" #include "r200_context.h" -#include "r200_state.h" #include "r200_ioctl.h" -#include "r200_tcl.h" -#include "r200_sanity.h" #include "radeon_reg.h" /* The state atoms will be emitted in the order they appear in the atom list, @@ -92,6 +88,7 @@ void r200SetUpAtomList( r200ContextPtr rmesa ) insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] ); insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] ); insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] ); + insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.stp ); for (i = 0; i < 8; ++i) insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] ); for (i = 0; i < 3 + mtu; ++i) diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index f34e319222..8986191c39 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -37,10 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/framebuffer.h" -#include "main/state.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -58,9 +55,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tex.h" #include "r200_swtcl.h" #include "r200_tcl.h" -#include "r200_maos.h" #include "r200_vertprog.h" #include "radeon_queryobj.h" +#include "r200_blit.h" #include "radeon_span.h" @@ -79,7 +76,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRIVER_DATE "20060602" -#include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -268,6 +264,7 @@ static void r200_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = r200Fallback; radeon->vtbl.update_scissor = r200_vtbl_update_scissor; radeon->vtbl.emit_query_finish = r200_emit_query_finish; + radeon->vtbl.blit = r200_blit; } @@ -294,6 +291,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, if ( !rmesa ) return GL_FALSE; + rmesa->radeon.radeonScreen = screen; r200_init_vtbl(&rmesa->radeon); /* init exp fog table data */ r200InitStaticFogData(); @@ -326,7 +324,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, r200InitDriverFuncs(&functions); r200InitIoctlFuncs(&functions); r200InitStateFuncs(&functions); - r200InitTextureFuncs(&functions); + r200InitTextureFuncs(&rmesa->radeon, &functions); r200InitShaderFuncs(&functions); radeonInitQueryObjFunctions(&functions); @@ -352,6 +350,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits; + i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); /* FIXME: When no memory manager is available we should set this diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 17e4d8962e..a9dce310ae 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -645,6 +645,8 @@ extern GLboolean r200MakeCurrent( __DRIcontext *driContextPriv, __DRIdrawable *driReadPriv ); extern GLboolean r200UnbindContext( __DRIcontext *driContextPriv ); +extern void r200_init_texcopy_functions(struct dd_function_table *table); + /* ================================================================ * Debugging: */ diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 66c5d3655a..a1b505707e 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -46,13 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_common.h" #include "radeon_lock.h" #include "r200_context.h" -#include "r200_state.h" #include "r200_ioctl.h" -#include "r200_tcl.h" -#include "r200_sanity.h" #include "radeon_reg.h" -#include "drirenderbuffer.h" #include "vblank.h" #define R200_TIMEOUT 512 diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 249c0bbc11..aecba7f894 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -74,7 +74,7 @@ static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, GLvoid *data, int stride, int count) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - uint32_t *out; + GLfloat *out; int i; int size = 1; @@ -91,7 +91,7 @@ static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, aos->count = count; radeon_bo_map(aos->bo, 1); - out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + out = (GLfloat*)((char*)aos->bo->ptr + aos->offset); for (i = 0; i < count; i++) { out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); out++; diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h index 526a624b69..59115212ce 100644 --- a/src/mesa/drivers/dri/r200/r200_reg.h +++ b/src/mesa/drivers/dri/r200/r200_reg.h @@ -938,7 +938,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_CLAMP_Q_CLAMP_GL (6 << 9) #define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9) #define R200_CLAMP_Q_MASK (7 << 9) -#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) +#define R200_MIN_MIP_LEVEL_MASK (0x0f << 12) #define R200_MIN_MIP_LEVEL_SHIFT 12 #define R200_TEXCOORD_NONPROJ (0 << 16) #define R200_TEXCOORD_CUBIC_ENV (1 << 16) @@ -950,6 +950,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_TEXCOORD_ZERO (7 << 16) #define R200_TEXCOORD_MASK (7 << 16) #define R200_LOD_BIAS_MASK (0xfff80000) +#define R200_LOD_BIAS_FIXED_ONE (0x08000000) +#define R200_LOD_BIAS_CORRECTION (0x00600000) #define R200_LOD_BIAS_SHIFT 19 #define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ #define R200_PP_TX_WIDTHMASK_SHIFT 0 diff --git a/src/mesa/drivers/dri/r200/r200_sanity.c b/src/mesa/drivers/dri/r200/r200_sanity.c index 1241a926ba..a439fd84ed 100644 --- a/src/mesa/drivers/dri/r200/r200_sanity.c +++ b/src/mesa/drivers/dri/r200/r200_sanity.c @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "r200_context.h" -#include "r200_ioctl.h" #include "r200_sanity.h" #include "radeon_reg.h" #include "r200_reg.h" diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 7fe482fe15..b9ec6f428f 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -57,8 +57,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_swtcl.h" #include "r200_vertprog.h" -#include "drirenderbuffer.h" - /* ============================================================= * Alpha blending @@ -597,6 +595,13 @@ static void r200PointSize( GLcontext *ctx, GLfloat size ) r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd; + radeon_print(RADEON_STATE, RADEON_TRACE, + "%s(%p) size: %f, fixed point result: %d.%d (%d/16)\n", + __func__, ctx, size, + ((GLuint)(ctx->Point.Size * 16.0))/16, + (((GLuint)(ctx->Point.Size * 16.0))&15)*100/16, + ((GLuint)(ctx->Point.Size * 16.0))&15); + R200_STATECHANGE( rmesa, cst ); R200_STATECHANGE( rmesa, ptp ); rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff; @@ -2466,6 +2471,12 @@ static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask ) radeon_firevertices(&r200->radeon); + radeon_print(RADEON_STATE, RADEON_TRACE, + "%s(%p) first 32 bits are %x.\n", + __func__, + ctx, + *(uint32_t*)mask); + R200_STATECHANGE(r200, stp); /* Must flip pattern upside down. diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index 6c5a0b79ee..e06437bd50 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "vbo/vbo.h" -#include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -48,9 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" #include "r200_ioctl.h" #include "r200_state.h" -#include "r200_tcl.h" -#include "r200_tex.h" -#include "r200_swtcl.h" #include "radeon_queryobj.h" #include "xmlpool.h" @@ -351,6 +347,15 @@ static int check_rrb(GLcontext *ctx, struct radeon_state_atom *atom) return atom->cmd_size; } +static int check_polygon_stipple(GLcontext *ctx, + struct radeon_state_atom *atom) +{ + r200ContextPtr r200 = R200_CONTEXT(ctx); + if (r200->hw.set.cmd[SET_RE_CNTL] & R200_STIPPLE_ENABLE) + return atom->cmd_size; + return 0; +} + static void mtl_emit(GLcontext *ctx, struct radeon_state_atom *atom) { r200ContextPtr r200 = R200_CONTEXT(ctx); @@ -698,7 +703,8 @@ static void tex_emit_mm(GLcontext *ctx, struct radeon_state_atom *atom) uint32_t dwords = atom->check(ctx, atom); int i = atom->idx; radeonTexObj *t = r200->state.texture.unit[i].texobj; - if (!r200->state.texture.unit[i].unitneeded) + + if (!r200->state.texture.unit[i].unitneeded && !(dwords <= atom->cmd_size)) dwords -= 4; BEGIN_BATCH_NO_AUTOSTATE(dwords); @@ -888,7 +894,7 @@ void r200InitState( r200ContextPtr rmesa ) } } - ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 ); + ALLOC_STATE( stp, polygon_stipple, STP_STATE_SIZE, "STP/stp", 0 ); for (i = 0; i < 6; i++) if (rmesa->radeon.radeonScreen->kernel_mm) @@ -1380,7 +1386,7 @@ void r200InitState( r200ContextPtr rmesa ) rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0; rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT_X] = (/* R200_TEXCOORD_PROJ | */ - 0x100000); /* Small default bias */ + R200_LOD_BIAS_CORRECTION); /* Small default bias */ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) { rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET_NEWDRM] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index 4596912ddc..e220e40b01 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -44,7 +44,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/s_context.h" #include "swrast/s_fog.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index e7d48a7f29..f3f558b7de 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" #include "r200_state.h" #include "r200_ioctl.h" -#include "r200_tex.h" #include "r200_tcl.h" #include "r200_swtcl.h" #include "r200_maos.h" diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c index 5b87ba6ccd..6723b12bf4 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.c +++ b/src/mesa/drivers/dri/r200/r200_tex.c @@ -44,9 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_mipmap_tree.h" #include "r200_context.h" -#include "r200_state.h" #include "r200_ioctl.h" -#include "r200_swtcl.h" #include "r200_tex.h" #include "xmlpool.h" @@ -67,6 +65,13 @@ static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenu GLboolean is_clamp_to_border = GL_FALSE; struct gl_texture_object *tObj = &t->base; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(tex %p) sw %s, tw %s, rw %s\n", + __func__, t, + _mesa_lookup_enum_by_nr(swrap), + _mesa_lookup_enum_by_nr(twrap), + _mesa_lookup_enum_by_nr(rwrap)); + t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D); switch ( swrap ) { @@ -182,6 +187,9 @@ static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenu static void r200SetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max ) { t->pp_txfilter &= ~R200_MAX_ANISO_MASK; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(tex %p) max %f.\n", + __func__, t, max); if ( max <= 1.0 ) { t->pp_txfilter |= R200_MAX_ANISO_1_TO_1; @@ -214,6 +222,13 @@ static void r200SetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK); t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(tex %p) minf %s, maxf %s, anisotropy %d.\n", + __func__, t, + _mesa_lookup_enum_by_nr(minf), + _mesa_lookup_enum_by_nr(magf), + anisotropy); + if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) { switch ( minf ) { case GL_NEAREST: @@ -286,10 +301,8 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if ( R200_DEBUG & RADEON_STATE ) { - fprintf( stderr, "%s( %s )\n", + radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_VERBOSE, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); - } /* This is incorrect: Need to maintain this data for each of * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch @@ -311,18 +324,19 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, case GL_TEXTURE_LOD_BIAS_EXT: { GLfloat bias, min; GLuint b; - const int fixed_one = 0x8000000; + const int fixed_one = R200_LOD_BIAS_FIXED_ONE; /* The R200's LOD bias is a signed 2's complement value with a * range of -16.0 <= bias < 16.0. * * NOTE: Add a small bias to the bias for conform mipsel.c test. */ - bias = *param + .01; + bias = *param; min = driQueryOptionb (&rmesa->radeon.optionCache, "no_neg_lod_bias") ? 0.0 : -16.0; bias = CLAMP( bias, min, 16.0 ); - b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK; + b = ((int)(bias * fixed_one) + + R200_LOD_BIAS_CORRECTION) & R200_LOD_BIAS_MASK; if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) { R200_STATECHANGE( rmesa, tex[unit] ); @@ -358,10 +372,11 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, { radeonTexObj* t = radeon_tex_obj(texObj); - if ( R200_DEBUG & (RADEON_STATE|RADEON_TEXTURE) ) { - fprintf( stderr, "%s( %s )\n", __FUNCTION__, + radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_VERBOSE, + "%s(%p, tex %p) target %s, pname %s\n", + __FUNCTION__, ctx, texObj, + _mesa_lookup_enum_by_nr( target ), _mesa_lookup_enum_by_nr( pname ) ); - } switch ( pname ) { case GL_TEXTURE_MIN_FILTER: @@ -399,11 +414,10 @@ static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) r200ContextPtr rmesa = R200_CONTEXT(ctx); radeonTexObj* t = radeon_tex_obj(texObj); - if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) { - fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, - (void *)texObj, - _mesa_lookup_enum_by_nr(texObj->Target)); - } + radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_NORMAL, + "%s( %p (target = %s) )\n", __FUNCTION__, + (void *)texObj, + _mesa_lookup_enum_by_nr(texObj->Target)); if (rmesa) { int i; @@ -458,10 +472,10 @@ static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx, radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); - if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) { - fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, - t, _mesa_lookup_enum_by_nr(target)); - } + radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p) target %s, new texture %p.\n", + __FUNCTION__, ctx, + _mesa_lookup_enum_by_nr(target), t); _mesa_initialize_texture_object(&t->base, name, target); t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; @@ -477,7 +491,7 @@ static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx, -void r200InitTextureFuncs( struct dd_function_table *functions ) +void r200InitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ) { /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. @@ -511,6 +525,11 @@ void r200InitTextureFuncs( struct dd_function_table *functions ) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; functions->NewTextureImage = radeonNewTextureImage; diff --git a/src/mesa/drivers/dri/r200/r200_tex.h b/src/mesa/drivers/dri/r200/r200_tex.h index e122de6e5e..1a1e7038df 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.h +++ b/src/mesa/drivers/dri/r200/r200_tex.h @@ -48,7 +48,7 @@ extern int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint extern void r200DestroyTexObj( r200ContextPtr rmesa, radeonTexObjPtr t ); -extern void r200InitTextureFuncs( struct dd_function_table *functions ); +extern void r200InitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ); extern void r200UpdateFragmentShader( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index e2f9cf0ea8..458de08522 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -1055,6 +1055,7 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx ) #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ R200_TEXCOORD_MASK | \ + R200_MIN_MIP_LEVEL_MASK | \ R200_CLAMP_Q_MASK | \ R200_VOLUME_FILTER_MASK) @@ -1410,6 +1411,7 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) { const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod]; GLint log2Width, log2Height, log2Depth, texelBytes; + uint extra_size = 0; if ( t->bo ) { return; @@ -1420,6 +1422,10 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) log2Depth = firstImage->DepthLog2; texelBytes = _mesa_get_format_bytes(firstImage->TexFormat); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n", + __func__, rmesa, t, log2Width, log2Height, + log2Depth, texelBytes, firstImage->TexFormat); if (!t->image_override) { if (VALID_FORMAT(firstImage->TexFormat)) { @@ -1432,6 +1438,8 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) t->pp_txformat |= table[ firstImage->TexFormat ].format; t->pp_txfilter |= table[ firstImage->TexFormat ].filter; + + } else { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); @@ -1440,19 +1448,34 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) } t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; - t->pp_txfilter |= (t->maxLod - t->minLod) << R200_MAX_MIP_LEVEL_SHIFT; - + t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT) + & R200_MAX_MIP_LEVEL_MASK; + + if ( t->pp_txfilter & + (R200_MIN_FILTER_NEAREST_MIP_NEAREST + | R200_MIN_FILTER_NEAREST_MIP_LINEAR + | R200_MIN_FILTER_LINEAR_MIP_NEAREST + | R200_MIN_FILTER_LINEAR_MIP_LINEAR + | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST + | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR)) + extra_size = t->minLod; + t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | R200_TXFORMAT_HEIGHT_MASK | R200_TXFORMAT_CUBIC_MAP_ENABLE | R200_TXFORMAT_F5_WIDTH_MASK | R200_TXFORMAT_F5_HEIGHT_MASK); - t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) | - (log2Height << R200_TXFORMAT_HEIGHT_SHIFT)); + t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) | + ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT)); t->tile_bits = 0; - t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK); + t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK + | R200_MIN_MIP_LEVEL_MASK); + + t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT) + & R200_MIN_MIP_LEVEL_MASK; + if (t->base.Target == GL_TEXTURE_3D) { t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); t->pp_txformat_x |= R200_TEXCOORD_VOLUME; @@ -1480,7 +1503,7 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) */ t->pp_txformat_x |= R200_TEXCOORD_PROJ; } - + /* FIXME: NPOT sizes, Is it correct realy? */ t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT) | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT)); diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 11405d7cae..12f869d96f 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -437,7 +437,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) | (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) { if (R200_DEBUG & RADEON_FALLBACKS) { - fprintf(stderr, "can't handle vert prog outputs 0x%x\n", + fprintf(stderr, "can't handle vert prog outputs 0x%llx\n", mesa_vp->Base.OutputsWritten); } return GL_FALSE; @@ -1218,7 +1218,7 @@ r200DeleteProgram(GLcontext *ctx, struct gl_program *prog) _mesa_delete_program(ctx, prog); } -static void +static GLboolean r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) { struct r200_vertex_program *vp = (void *)prog; @@ -1237,7 +1237,10 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) break; } /* need this for tcl fallbacks */ - _tnl_program_string(ctx, target, prog); + (void) _tnl_program_string(ctx, target, prog); + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } static GLboolean diff --git a/src/mesa/drivers/dri/r200/radeon_tex_copy.c b/src/mesa/drivers/dri/r200/radeon_tex_copy.c new file mode 120000 index 0000000000..dfa5ba34e6 --- /dev/null +++ b/src/mesa/drivers/dri/r200/radeon_tex_copy.c @@ -0,0 +1 @@ +../radeon/radeon_tex_copy.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r200/server/radeon_egl.c b/src/mesa/drivers/dri/r200/server/radeon_egl.c deleted file mode 120000 index d7735a7643..0000000000 --- a/src/mesa/drivers/dri/r200/server/radeon_egl.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_egl.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index be005bd164..04459c2ddf 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -9,10 +9,6 @@ LIBNAME = r300_dri.so MINIGLX_SOURCES = server/radeon_dri.c -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif @@ -39,7 +35,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_span.c \ radeon_queryobj.c \ - radeon_texture.c + radeon_texture.c \ + radeon_tex_copy.c DRIVER_SOURCES = \ radeon_screen.c \ @@ -50,7 +47,6 @@ DRIVER_SOURCES = \ r300_state.c \ r300_render.c \ r300_tex.c \ - r300_texcopy.c \ r300_texstate.c \ r300_vertprog.c \ r300_fragprog_common.c \ @@ -66,7 +62,6 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) DRIVER_DEFINES = -DRADEON_R300 # -DRADEON_BO_TRACK \ - -Wall DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c index aa69b0fc72..928c15e1e4 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c @@ -297,7 +297,7 @@ void r300FragmentProgramDump(struct rX00_fragment_program_code *c) if (flags[0] != 0) { sprintf(tmp, "o%i.%s", (code->alu.inst[i]. - rgb_addr >> R300_ALU_DSTC_SHIFT) & 31, + rgb_addr >> 29) & 3, flags); strcat(dstc, tmp); } @@ -311,7 +311,7 @@ void r300FragmentProgramDump(struct rX00_fragment_program_code *c) if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) { sprintf(tmp, "o%i.w ", (code->alu.inst[i]. - alpha_addr >> R300_ALU_DSTA_SHIFT) & 31); + alpha_addr >> 25) & 3); strcat(dsta, tmp); } if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) { diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c index 375838d98e..cc552aee17 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c @@ -176,7 +176,9 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT); } if (inst->RGB.OutputWriteMask) { - code->alu.inst[ip].rgb_addr |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT); + code->alu.inst[ip].rgb_addr |= + (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) | + R300_RGB_TARGET(inst->RGB.Target); emit->node_flags |= R300_RGBA_OUT; } @@ -187,7 +189,8 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i R300_ALU_DSTA_REG; } if (inst->Alpha.OutputWriteMask) { - code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT; + code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT | + R300_ALPHA_TARGET(inst->Alpha.Target); emit->node_flags |= R300_RGBA_OUT; } if (inst->Alpha.DepthWriteMask) { diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index 5581f25352..c2d5dc27b4 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -35,7 +35,10 @@ static void dataflow_outputs_mark_use(void * userdata, void * data, void (*callback)(void *, unsigned int, unsigned int)) { struct r300_fragment_program_compiler * c = userdata; - callback(data, c->OutputColor, RC_MASK_XYZW); + callback(data, c->OutputColor[0], RC_MASK_XYZW); + callback(data, c->OutputColor[1], RC_MASK_XYZW); + callback(data, c->OutputColor[2], RC_MASK_XYZW); + callback(data, c->OutputColor[3], RC_MASK_XYZW); callback(data, c->OutputDepth, RC_MASK_W); } 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 b1b14394b6..c2eb613b23 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -241,6 +241,9 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT; + code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target); + code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target); + if (inst->WriteALUResult) { code->inst[ip].inst3 |= R500_ALU_RGB_WMASK; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h index 731adc1af2..6bfda0574f 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h @@ -23,6 +23,8 @@ #ifndef RADEON_COMPILER_H #define RADEON_COMPILER_H +#include "../../../../main/compiler.h" + #include "memory_pool.h" #include "radeon_code.h" #include "radeon_program.h" @@ -81,8 +83,10 @@ struct r300_fragment_program_compiler { struct rX00_fragment_program_code *code; struct r300_fragment_program_external_state state; unsigned is_r500; + /* Register corresponding to the depthbuffer. */ unsigned OutputDepth; - unsigned OutputColor; + /* Registers corresponding to the four colorbuffers. */ + unsigned OutputColor[4]; void * UserData; void (*AllocateHwInputs)( diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c index 7211768272..fff5b0c217 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c @@ -203,12 +203,21 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c, /* Destination handling */ if (inst->DstReg.File == RC_FILE_OUTPUT) { - if (inst->DstReg.Index == c->OutputColor) { - pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ; - pair->Alpha.OutputWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); - } else if (inst->DstReg.Index == c->OutputDepth) { - pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); - } + if (inst->DstReg.Index == c->OutputDepth) { + pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); + } else { + for (i = 0; i < 4; i++) { + if (inst->DstReg.Index == c->OutputColor[i]) { + pair->RGB.Target = i; + pair->Alpha.Target = i; + pair->RGB.OutputWriteMask |= + inst->DstReg.WriteMask & RC_MASK_XYZ; + pair->Alpha.OutputWriteMask |= + GET_BIT(inst->DstReg.WriteMask, 3); + break; + } + } + } } else { if (needrgb) { pair->RGB.DestIndex = inst->DstReg.Index; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h index 6685ade3ea..511cc707a3 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h @@ -60,6 +60,7 @@ struct radeon_pair_instruction_rgb { unsigned int Opcode:8; unsigned int DestIndex:RC_REGISTER_INDEX_BITS; unsigned int WriteMask:3; + unsigned int Target:2; unsigned int OutputWriteMask:3; unsigned int Saturate:1; @@ -77,6 +78,7 @@ struct radeon_pair_instruction_alpha { unsigned int Opcode:8; unsigned int DestIndex:RC_REGISTER_INDEX_BITS; unsigned int WriteMask:1; + unsigned int Target:2; unsigned int OutputWriteMask:1; unsigned int DepthWriteMask:1; unsigned int Saturate:1; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c index d863b82d53..28fb9eae92 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c @@ -229,7 +229,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst (inst->RGB.WriteMask & 2) ? "y" : "", (inst->RGB.WriteMask & 4) ? "z" : ""); if (inst->RGB.OutputWriteMask) - fprintf(f, " color.%s%s%s", + fprintf(f, " color[%i].%s%s%s", inst->RGB.Target, (inst->RGB.OutputWriteMask & 1) ? "x" : "", (inst->RGB.OutputWriteMask & 2) ? "y" : "", (inst->RGB.OutputWriteMask & 4) ? "z" : ""); @@ -255,7 +255,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst if (inst->Alpha.WriteMask) fprintf(f, " temp[%i].w", inst->Alpha.DestIndex); if (inst->Alpha.OutputWriteMask) - fprintf(f, " color.w"); + fprintf(f, " color[%i].w", inst->Alpha.Target); if (inst->Alpha.DepthWriteMask) fprintf(f, " depth.w"); if (inst->WriteALUResult == RC_ALURESULT_W) diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index 2eec27e900..54ac2510e7 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -114,7 +114,7 @@ static void create_fragment_program(struct r300_context *r300) inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW; compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0); - compiler.OutputColor = FRAG_RESULT_COLOR; + compiler.OutputColor[0] = FRAG_RESULT_COLOR; compiler.OutputDepth = FRAG_RESULT_DEPTH; compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515); compiler.code = &r300->blit.fp_code; @@ -150,8 +150,8 @@ static void r300_emit_tx_setup(struct r300_context *r300, (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) | (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_R_SHIFT) | R300_TX_MIN_FILTER_MIP_NONE | - R300_TX_MIN_FILTER_LINEAR | - R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_NEAREST | + R300_TX_MAG_FILTER_NEAREST | (0 << 28)); OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0); OUT_BATCH_REGVAL(R300_TX_SIZE_0, @@ -403,9 +403,8 @@ static void calc_tex_coords(float img_width, float img_height, buf[3] = buf[2] + reg_height / img_height; if (flip_y) { - float tmp = buf[2]; - buf[2] = 1.0 - buf[3]; - buf[3] = 1.0 - tmp; + buf[2] = 1.0 - buf[2]; + buf[3] = 1.0 - buf[3]; } } @@ -424,13 +423,13 @@ static void emit_draw_packet(struct r300_context *r300, flip_y, texcoords); float verts[] = { dst_x_offset, dst_y_offset, - texcoords[0], texcoords[3], - dst_x_offset, dst_y_offset + reg_height, texcoords[0], texcoords[2], + dst_x_offset, dst_y_offset + reg_height, + texcoords[0], texcoords[3], dst_x_offset + reg_width, dst_y_offset + reg_height, - texcoords[1], texcoords[2], + texcoords[1], texcoords[3], dst_x_offset + reg_width, dst_y_offset, - texcoords[1], texcoords[3] }; + texcoords[1], texcoords[2] }; BATCH_LOCALS(&r300->radeon); @@ -495,6 +494,27 @@ static void emit_cb_setup(struct r300_context *r300, END_BATCH(); } +static unsigned is_blit_supported(gl_format dst_format) +{ + switch (dst_format) { + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_XRGB8888: + break; + default: + return 0; + } + + if (_mesa_get_format_bits(dst_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + /** * Copy a region of [@a width x @a height] pixels from source buffer * to destination buffer. @@ -519,29 +539,31 @@ static void emit_cb_setup(struct r300_context *r300, * @param[in] height region height * @param[in] flip_y set if y coords of the source image need to be flipped */ -GLboolean r300_blit(struct r300_context *r300, - struct radeon_bo *src_bo, - intptr_t src_offset, - gl_format src_mesaformat, - unsigned src_pitch, - unsigned src_width, - unsigned src_height, - unsigned src_x_offset, - unsigned src_y_offset, - struct radeon_bo *dst_bo, - intptr_t dst_offset, - gl_format dst_mesaformat, - unsigned dst_pitch, - unsigned dst_width, - unsigned dst_height, - unsigned dst_x_offset, - unsigned dst_y_offset, - unsigned reg_width, - unsigned reg_height, - unsigned flip_y) +unsigned r300_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) { - if (_mesa_get_format_bits(src_mesaformat, GL_DEPTH_BITS) > 0) - return GL_FALSE; + r300ContextPtr r300 = R300_CONTEXT(ctx); + + if (!is_blit_supported(dst_mesaformat)) + return 0; /* Make sure that colorbuffer has even width - hw limitation */ if (dst_pitch % 2 > 0) @@ -551,7 +573,7 @@ GLboolean r300_blit(struct r300_context *r300, * Looks like a hw limitation. */ if (dst_pitch < 32) - return GL_FALSE; + return 0; /* Need to clamp the region size to make sure * we don't read outside of the source buffer @@ -567,6 +589,10 @@ GLboolean r300_blit(struct r300_context *r300, reg_height = dst_height - dst_y_offset; if (src_bo == dst_bo) { + return 0; + } + + if (src_offset % 32 || dst_offset % 32) { return GL_FALSE; } @@ -587,7 +613,7 @@ GLboolean r300_blit(struct r300_context *r300, radeonFlush(r300->radeon.glCtx); if (!validate_buffers(r300, src_bo, dst_bo)) - return GL_FALSE; + return 0; rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__); @@ -618,5 +644,5 @@ GLboolean r300_blit(struct r300_context *r300, radeonFlush(r300->radeon.glCtx); - return GL_TRUE; -}
\ No newline at end of file + return 1; +} diff --git a/src/mesa/drivers/dri/r300/r300_blit.h b/src/mesa/drivers/dri/r300/r300_blit.h index dc21e88098..735acaddd7 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.h +++ b/src/mesa/drivers/dri/r300/r300_blit.h @@ -30,25 +30,25 @@ void r300_blit_init(struct r300_context *r300); -GLboolean r300_blit(struct r300_context *r300, - struct radeon_bo *src_bo, - intptr_t src_offset, - gl_format src_mesaformat, - unsigned src_pitch, - unsigned src_width, - unsigned src_height, - unsigned src_x_offset, - unsigned src_y_offset, - struct radeon_bo *dst_bo, - intptr_t dst_offset, - gl_format dst_mesaformat, - unsigned dst_pitch, - unsigned dst_width, - unsigned dst_height, - unsigned dst_x_offset, - unsigned dst_y_offset, - unsigned width, - unsigned height, - unsigned flip_y); +unsigned r300_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y); #endif // R300_BLIT_H
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index e1c33bbb2c..4787bafc66 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "main/context.h" #include "main/simple_list.h" -#include "swrast/swrast.h" #include "drm.h" #include "radeon_drm.h" @@ -50,7 +49,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_emit.h" #include "radeon_bocs_wrapper.h" #include "radeon_mipmap_tree.h" -#include "r300_state.h" #include "radeon_queryobj.h" /** # of dwords reserved for additional instructions that may need to be written diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 1f6ccf6ddc..7c21efb1de 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -40,9 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/state.h" #include "main/bufferobj.h" #include "main/texobj.h" @@ -52,13 +50,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vp_build.h" #include "drivers/common/driverfuncs.h" #include "drivers/common/meta.h" #include "r300_context.h" -#include "radeon_context.h" #include "radeon_span.h" #include "r300_blit.h" #include "r300_cmdbuf.h" @@ -70,7 +66,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_buffer_objects.h" #include "radeon_queryobj.h" -#include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -93,8 +88,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/remap_helper.h" -void r300_init_texcopy_functions(struct dd_function_table *table); - static const struct dri_extension card_extensions[] = { /* *INDENT-OFF* */ {"GL_ARB_depth_texture", NULL}, @@ -326,6 +319,8 @@ static void r300_init_vtbl(radeonContextPtr radeon) radeon->vtbl.emit_query_finish = rv530_emit_query_finish_single_z; } else radeon->vtbl.emit_query_finish = r300_emit_query_finish; + + radeon->vtbl.blit = r300_blit; } static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) @@ -338,6 +333,10 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) driQueryOptioni(&r300->radeon.optionCache, "texture_coord_units"); ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits); + ctx->Const.MaxCombinedTextureImageUnits = + ctx->Const.MaxVertexTextureImageUnits + + ctx->Const.MaxTextureImageUnits; + ctx->Const.MaxTextureMaxAnisotropy = 16.0; ctx->Const.MaxTextureLodBias = 16.0; @@ -451,6 +450,8 @@ 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) + _mesa_enable_extension(ctx, "GL_ARB_half_float_vertex"); } static void r300InitIoctlFuncs(struct dd_function_table *functions) @@ -488,15 +489,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _mesa_init_driver_functions(&functions); r300InitIoctlFuncs(&functions); r300InitStateFuncs(&functions); - r300InitTextureFuncs(&functions); + r300InitTextureFuncs(&r300->radeon, &functions); r300InitShaderFuncs(&functions); radeonInitQueryObjFunctions(&functions); radeonInitBufferObjectFuncs(&functions); - if (r300->radeon.radeonScreen->kernel_mm) { - r300_init_texcopy_functions(&functions); - } - if (!radeonInitContext(&r300->radeon, &functions, glVisual, driContextPriv, sharedContextPrivate)) { diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 546cd8ddde..78ab43a99f 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -554,8 +554,6 @@ extern void r300InitShaderFunctions(r300ContextPtr r300); extern void r300InitDraw(GLcontext *ctx); -extern void r300_init_texcopy_functions(struct dd_function_table *table); - #define r300PackFloat32 radeonPackFloat32 #define r300PackFloat24 radeonPackFloat24 diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index 3dcd986e22..4ae0d6fe48 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -29,7 +29,6 @@ #include "main/glheader.h" #include "main/context.h" #include "main/state.h" -#include "main/api_validate.h" #include "main/enums.h" #include "main/simple_list.h" @@ -47,8 +46,6 @@ #include "tnl/tnl.h" #include "tnl/t_vp_build.h" #include "vbo/vbo_context.h" -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" static int getTypeSize(GLenum type) @@ -56,6 +53,8 @@ static int getTypeSize(GLenum type) switch (type) { case GL_DOUBLE: return sizeof(GLdouble); + case GL_HALF_FLOAT: + return sizeof(GLhalfARB); case GL_FLOAT: return sizeof(GLfloat); case GL_INT: @@ -385,6 +384,18 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st r300_attr._signed = 0; r300_attr.normalize = 0; break; + case GL_HALF_FLOAT: + switch (input->Size) { + case 1: + case 2: + r300_attr.data_type = R300_DATA_TYPE_FLT16_2; + break; + case 3: + case 4: + r300_attr.data_type = R300_DATA_TYPE_FLT16_4; + break; + } + break; case GL_SHORT: r300_attr._signed = 1; r300_attr.normalize = input->Normalized; @@ -594,13 +605,23 @@ static void r300FreeData(GLcontext *ctx) } } -static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, GLuint nr_prims) +static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, + GLuint nr_prims, const struct _mesa_prim *prim) { struct r300_context *r300 = R300_CONTEXT(ctx); struct r300_vertex_buffer *vbuf = &r300->vbuf; GLboolean flushed; GLuint dwords; GLuint state_size; + int i; + GLuint extra_prims = 0; + + /* Check for primitive splitting. */ + for (i = 0; i < nr_prims; ++i) { + const GLuint num_verts = r300NumVerts(r300, prim[i].count, prim[i].mode); + extra_prims += num_verts/(65535 - 32); + } + nr_prims += extra_prims; dwords = 2*CACHE_FLUSH_BUFSZ; dwords += PRE_EMIT_STATE_BUFSZ; @@ -656,7 +677,7 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, /* ensure we have the cmd buf space in advance to cover * the state + DMA AOS pointers */ - GLuint emit_end = r300PredictTryDrawPrimsSize(ctx, nr_prims) + GLuint emit_end = r300PredictTryDrawPrimsSize(ctx, nr_prims, prim) + r300->radeon.cmdbuf.cs->cdw; r300SetupIndexBuffer(ctx, ib); diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index 15aeaf0514..a24d431611 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -39,18 +39,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "main/imports.h" #include "main/macros.h" -#include "main/image.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "r300_context.h" -#include "r300_state.h" #include "r300_emit.h" -#include "r300_render.h" -#include "r300_swtcl.h" + GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead) { diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c index 2933d31136..a0e2dd3c09 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -38,14 +38,12 @@ #include "r300_fragprog_common.h" -#include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "compiler/radeon_compiler.h" #include "radeon_mesa_to_rc.h" -#include "r300_state.h" static GLuint build_dtm(GLuint depthmode) @@ -223,7 +221,8 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog compiler.state = fp->state; compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE; compiler.OutputDepth = FRAG_RESULT_DEPTH; - compiler.OutputColor = FRAG_RESULT_COLOR; + memset(compiler.OutputColor, 0, 4 * sizeof(unsigned)); + compiler.OutputColor[0] = FRAG_RESULT_COLOR; compiler.AllocateHwInputs = &allocate_hw_inputs; if (compiler.Base.Debug) { diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index ea684e7df1..d18ebab8ff 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -230,6 +230,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_DATA_TYPE_SHORT_4 7 # define R300_DATA_TYPE_VECTOR_3_TTT 8 # define R300_DATA_TYPE_VECTOR_3_EET 9 +# define R300_DATA_TYPE_FLT16_2 11 +# define R300_DATA_TYPE_FLT16_4 12 + # define R300_SKIP_DWORDS_SHIFT 4 # define R300_DST_VEC_LOC_SHIFT 8 # define R300_LAST_VEC (1 << 13) diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 02c94250a8..e3e6285784 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -53,7 +53,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_render.h" #include "main/glheader.h" -#include "main/state.h" #include "main/imports.h" #include "main/enums.h" #include "main/macros.h" @@ -65,14 +64,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "vbo/vbo.h" #include "vbo/vbo_split.h" -#include "tnl/tnl.h" -#include "tnl/t_vp_build.h" #include "r300_context.h" #include "r300_state.h" #include "r300_reg.h" -#include "r300_tex.h" #include "r300_emit.h" -#include "r300_fragprog_common.h" #include "r300_swtcl.h" /** diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index a4f9db13ec..3638010e48 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -98,7 +98,7 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog) _mesa_delete_program(ctx, prog); } -static void +static GLboolean r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog; @@ -116,7 +116,10 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) } /* need this for tcl fallbacks */ - _tnl_program_string(ctx, target, prog); + (void) _tnl_program_string(ctx, target, prog); + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } static GLboolean diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c51285aad9..017d45a503 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -58,13 +58,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_reg.h" #include "r300_emit.h" -#include "r300_tex.h" #include "r300_fragprog_common.h" #include "r300_render.h" #include "r300_vertprog.h" -#include "drirenderbuffer.h" - static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4]) { r300ContextPtr rmesa = R300_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 963f648cb1..8dd8507395 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -41,18 +41,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/mipmap.h" #include "main/simple_list.h" #include "main/texstore.h" -#include "main/teximage.h" #include "main/texobj.h" #include "texmem.h" #include "r300_context.h" -#include "r300_state.h" #include "radeon_mipmap_tree.h" #include "r300_tex.h" -#include "xmlpool.h" - static unsigned int translate_wrap_mode(GLenum wrapmode) { @@ -312,7 +308,7 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, return &t->base; } -void r300InitTextureFuncs(struct dd_function_table *functions) +void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. @@ -340,6 +336,11 @@ void r300InitTextureFuncs(struct dd_function_table *functions) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; driInitTextureFormats(); diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index 6ede0fe25c..9694e703b8 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -49,7 +49,7 @@ extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, extern GLboolean r300ValidateBuffers(GLcontext * ctx); -extern void r300InitTextureFuncs(struct dd_function_table *functions); +extern void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions); int32_t r300TranslateTexFormat(gl_format mesaFormat); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 78ff54574f..09e046859a 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "r300_context.h" -#include "r300_state.h" #include "radeon_mipmap_tree.h" #include "r300_tex.h" #include "r300_reg.h" diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index aa98a049aa..e6fa57d439 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -34,7 +34,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "shader/program.h" #include "shader/programopt.h" #include "shader/prog_instruction.h" -#include "shader/prog_optimize.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "shader/prog_statevars.h" diff --git a/src/mesa/drivers/dri/r300/radeon_tex_copy.c b/src/mesa/drivers/dri/r300/radeon_tex_copy.c new file mode 120000 index 0000000000..dfa5ba34e6 --- /dev/null +++ b/src/mesa/drivers/dri/r300/radeon_tex_copy.c @@ -0,0 +1 @@ +../radeon/radeon_tex_copy.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/server/radeon_egl.c b/src/mesa/drivers/dri/r300/server/radeon_egl.c deleted file mode 120000 index d7735a7643..0000000000 --- a/src/mesa/drivers/dri/r300/server/radeon_egl.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_egl.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile index 26f47b7268..5d50941539 100644 --- a/src/mesa/drivers/dri/r600/Makefile +++ b/src/mesa/drivers/dri/r600/Makefile @@ -9,10 +9,6 @@ LIBNAME = r600_dri.so MINIGLX_SOURCES = server/radeon_dri.c -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif @@ -39,7 +35,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_span.c \ radeon_texture.c \ - radeon_queryobj.c + radeon_queryobj.c \ + radeon_tex_copy.c DRIVER_SOURCES = \ radeon_screen.c \ @@ -59,6 +56,7 @@ DRIVER_SOURCES = \ r700_render.c \ r600_tex.c \ r600_texstate.c \ + r600_blit.c \ r700_debug.c \ $(RADEON_COMMON_SOURCES) \ $(EGL_SOURCES) \ @@ -66,9 +64,8 @@ DRIVER_SOURCES = \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -DRIVER_DEFINES = -DRADEON_R600 \ +DRIVER_DEFINES = -DRADEON_R600 # -DRADEON_BO_TRACK \ - -Wall DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r600/r600_blit.c b/src/mesa/drivers/dri/r600/r600_blit.c new file mode 100644 index 0000000000..4bb77a398f --- /dev/null +++ b/src/mesa/drivers/dri/r600/r600_blit.c @@ -0,0 +1,1661 @@ +/* + * Copyright (C) 2009 Advanced Micro Devices, 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, 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 COPYRIGHT OWNER(S) 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 "radeon_common.h" +#include "r600_context.h" + +#include "r600_blit.h" +#include "r600_blit_shaders.h" +#include "r600_cmdbuf.h" + +/* common formats supported as both textures and render targets */ +static unsigned is_blit_supported(gl_format mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_SIGNED_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_SIGNED_RGBA8888_REV: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_XRGB8888_REV: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_A8: + case MESA_FORMAT_I8: + case MESA_FORMAT_CI8: + case MESA_FORMAT_L8: + case MESA_FORMAT_RGBA_FLOAT32: + case MESA_FORMAT_RGBA_FLOAT16: + case MESA_FORMAT_ALPHA_FLOAT32: + case MESA_FORMAT_ALPHA_FLOAT16: + case MESA_FORMAT_LUMINANCE_FLOAT32: + case MESA_FORMAT_LUMINANCE_FLOAT16: + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */ + case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */ + case MESA_FORMAT_X8_Z24: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z16: + case MESA_FORMAT_Z32: + case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SLA8: + case MESA_FORMAT_SL8: + break; + default: + return 0; + } + + /* ??? */ + /* not sure blit to depth works or not yet */ + if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + +static inline void +set_render_target(context_t *context, struct radeon_bo *bo, gl_format mesa_format, + int nPitchInPixel, int w, int h, intptr_t dst_offset) +{ + uint32_t cb_color0_base, cb_color0_size = 0, cb_color0_info = 0, cb_color0_view = 0; + int id = 0; + uint32_t comp_swap, format; + BATCH_LOCALS(&context->radeon); + + cb_color0_base = dst_offset / 256; + + SETfield(cb_color0_size, (nPitchInPixel / 8) - 1, + PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask); + SETfield(cb_color0_size, ((nPitchInPixel * h) / 64) - 1, + SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask); + + SETfield(cb_color0_info, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask); + SETfield(cb_color0_info, ARRAY_LINEAR_GENERAL, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + + SETbit(cb_color0_info, BLEND_BYPASS_bit); + + switch(mesa_format) { + case MESA_FORMAT_RGBA8888: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SIGNED_RGBA8888: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGBA8888_REV: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SIGNED_RGBA8888_REV: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + format = COLOR_8_8_8_8; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_XRGB8888_REV: + format = COLOR_8_8_8_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGB565: + format = COLOR_5_6_5; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGB565_REV: + format = COLOR_5_6_5; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB4444: + format = COLOR_4_4_4_4; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB4444_REV: + format = COLOR_4_4_4_4; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB1555: + format = COLOR_1_5_5_5; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB1555_REV: + format = COLOR_1_5_5_5; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_AL88: + format = COLOR_8_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_AL88_REV: + format = COLOR_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGB332: + format = COLOR_3_3_2; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_A8: + format = COLOR_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_I8: + case MESA_FORMAT_CI8: + format = COLOR_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_L8: + format = COLOR_8; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGBA_FLOAT32: + format = COLOR_32_32_32_32_FLOAT; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGBA_FLOAT16: + format = COLOR_16_16_16_16_FLOAT; + comp_swap = SWAP_STD_REV; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ALPHA_FLOAT32: + format = COLOR_32_FLOAT; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ALPHA_FLOAT16: + format = COLOR_16_FLOAT; + comp_swap = SWAP_ALT_REV; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT32: + format = COLOR_32_FLOAT; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT16: + format = COLOR_16_FLOAT; + comp_swap = SWAP_ALT; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + format = COLOR_32_32_FLOAT; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + format = COLOR_16_16_FLOAT; + comp_swap = SWAP_ALT_REV; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */ + format = COLOR_32_FLOAT; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */ + format = COLOR_16_FLOAT; + comp_swap = SWAP_STD; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_X8_Z24: + case MESA_FORMAT_S8_Z24: + format = COLOR_8_24; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_Z24_S8: + format = COLOR_24_8; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_Z16: + format = COLOR_16; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_Z32: + format = COLOR_32; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SRGBA8: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SLA8: + format = COLOR_8_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SL8: + format = COLOR_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + default: + fprintf(stderr,"Invalid format for copy %s\n",_mesa_get_format_name(mesa_format)); + assert("Invalid format for US output\n"); + return; + } + + SETfield(cb_color0_info, format, CB_COLOR0_INFO__FORMAT_shift, + CB_COLOR0_INFO__FORMAT_mask); + SETfield(cb_color0_info, comp_swap, COMP_SWAP_shift, COMP_SWAP_mask); + + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_BASE + (4 * id), 1); + R600_OUT_BATCH(cb_color0_base); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + + if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) && + (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)) { + BEGIN_BATCH_NO_AUTOSTATE(2); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); + R600_OUT_BATCH((2 << id)); + END_BATCH(); + } + + /* Set CMASK & TILE buffer to the offset of color buffer as + * we don't use those this shouldn't cause any issue and we + * then have a valid cmd stream + */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_TILE + (4 * id), 1); + R600_OUT_BATCH(cb_color0_base); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_FRAG + (4 * id), 1); + R600_OUT_BATCH(cb_color0_base); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(12); + 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(); + + COMMIT_BATCH(); + +} + +static inline void load_shaders(GLcontext * ctx) +{ + + radeonContextPtr radeonctx = RADEON_CONTEXT(ctx); + context_t *context = R700_CONTEXT(ctx); + int i, size; + uint32_t *shader; + + if (context->blit_bo_loaded == 1) + return; + + size = 4096; + context->blit_bo = radeon_bo_open(radeonctx->radeonScreen->bom, 0, + size, 256, RADEON_GEM_DOMAIN_GTT, 0); + radeon_bo_map(context->blit_bo, 1); + shader = context->blit_bo->ptr; + + for(i=0; i<sizeof(r6xx_vs)/4; i++) { + shader[128+i] = r6xx_vs[i]; + } + for(i=0; i<sizeof(r6xx_ps)/4; i++) { + shader[256+i] = r6xx_ps[i]; + } + + radeon_bo_unmap(context->blit_bo); + context->blit_bo_loaded = 1; + +} + +static inline void +set_shaders(context_t *context) +{ + struct radeon_bo * pbo = context->blit_bo; + BATCH_LOCALS(&context->radeon); + + uint32_t sq_pgm_start_fs = (512 >> 8); + uint32_t sq_pgm_resources_fs = 0; + uint32_t sq_pgm_cf_offset_fs = 0; + + uint32_t sq_pgm_start_vs = (512 >> 8); + uint32_t sq_pgm_resources_vs = (1 << NUM_GPRS_shift); + uint32_t sq_pgm_cf_offset_vs = 0; + + uint32_t sq_pgm_start_ps = (1024 >> 8); + uint32_t sq_pgm_resources_ps = (1 << NUM_GPRS_shift); + uint32_t sq_pgm_cf_offset_ps = 0; + uint32_t sq_pgm_exports_ps = (1 << 1); + + r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit); + + /* FS */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(SQ_PGM_START_FS, 1); + R600_OUT_BATCH(sq_pgm_start_fs); + R600_OUT_BATCH_RELOC(sq_pgm_start_fs, + pbo, + sq_pgm_start_fs, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(6); + R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_FS, sq_pgm_resources_fs); + R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_FS, sq_pgm_cf_offset_fs); + END_BATCH(); + + /* VS */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1); + R600_OUT_BATCH(sq_pgm_start_vs); + R600_OUT_BATCH_RELOC(sq_pgm_start_vs, + pbo, + sq_pgm_start_vs, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(6); + R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_VS, sq_pgm_resources_vs); + R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_VS, sq_pgm_cf_offset_vs); + END_BATCH(); + + /* PS */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1); + R600_OUT_BATCH(sq_pgm_start_ps); + R600_OUT_BATCH_RELOC(sq_pgm_start_ps, + pbo, + sq_pgm_start_ps, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(9); + R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_PS, sq_pgm_resources_ps); + R600_OUT_BATCH_REGVAL(SQ_PGM_EXPORTS_PS, sq_pgm_exports_ps); + R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_PS, sq_pgm_cf_offset_ps); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(18); + R600_OUT_BATCH_REGVAL(SPI_VS_OUT_CONFIG, 0); //EXPORT_COUNT is - 1 + R600_OUT_BATCH_REGVAL(SPI_VS_OUT_ID_0, 0); + R600_OUT_BATCH_REGVAL(SPI_PS_INPUT_CNTL_0, SEL_CENTROID_bit); + R600_OUT_BATCH_REGVAL(SPI_PS_IN_CONTROL_0, (1 << NUM_INTERP_shift)); + R600_OUT_BATCH_REGVAL(SPI_PS_IN_CONTROL_1, 0); + R600_OUT_BATCH_REGVAL(SPI_INTERP_CONTROL_0, 0); + END_BATCH(); + + COMMIT_BATCH(); + +} + +static inline void +set_vtx_resource(context_t *context) +{ + struct radeon_bo *bo = context->blit_bo; + BATCH_LOCALS(&context->radeon); + + 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(); + + if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710)) + r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit); + else + r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit); + + BEGIN_BATCH_NO_AUTOSTATE(9 + 2); + + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + R600_OUT_BATCH(SQ_FETCH_RESOURCE_VS_OFFSET * FETCH_RESOURCE_STRIDE); + R600_OUT_BATCH(0); + R600_OUT_BATCH(48 - 1); + R600_OUT_BATCH(16 << SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift); + R600_OUT_BATCH(1 << MEM_REQUEST_SIZE_shift); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(SQ_TEX_VTX_VALID_BUFFER << SQ_TEX_RESOURCE_WORD6_0__TYPE_shift); + R600_OUT_BATCH_RELOC(SQ_VTX_CONSTANT_WORD0_0, + bo, + SQ_VTX_CONSTANT_WORD0_0, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + COMMIT_BATCH(); + +} + +static inline void +set_tex_resource(context_t * context, + gl_format mesa_format, struct radeon_bo *bo, int w, int h, + int TexelPitch, intptr_t src_offset) +{ + uint32_t sq_tex_resource0, sq_tex_resource1, sq_tex_resource2, sq_tex_resource4, sq_tex_resource6; + + sq_tex_resource0 = sq_tex_resource1 = sq_tex_resource2 = sq_tex_resource4 = sq_tex_resource6 = 0; + BATCH_LOCALS(&context->radeon); + + SETfield(sq_tex_resource0, SQ_TEX_DIM_2D, DIM_shift, DIM_mask); + SETfield(sq_tex_resource0, ARRAY_LINEAR_GENERAL, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + + switch (mesa_format) { + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_SIGNED_RGBA8888: + 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); + 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); + 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); + if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888) { + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_X_shift, FORMAT_COMP_X_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_W_shift, FORMAT_COMP_W_mask); + } + break; + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_SIGNED_RGBA8888_REV: + 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_X, + 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_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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); + if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888_REV) { + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_X_shift, FORMAT_COMP_X_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_W_shift, FORMAT_COMP_W_mask); + } + break; + case MESA_FORMAT_ARGB8888: + 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_Z, + 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_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); + break; + case MESA_FORMAT_XRGB8888: + 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_Z, + 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_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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB8888_REV: + 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_Y, + 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); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_XRGB8888_REV: + 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_1, + 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); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_RGB565: + SETfield(sq_tex_resource1, FMT_5_6_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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_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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGB565_REV: + SETfield(sq_tex_resource1, FMT_5_6_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB4444: + SETfield(sq_tex_resource1, FMT_4_4_4_4, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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_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); + break; + case MESA_FORMAT_ARGB4444_REV: + SETfield(sq_tex_resource1, FMT_4_4_4_4, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Y, + 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); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_ARGB1555: + SETfield(sq_tex_resource1, FMT_1_5_5_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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_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); + break; + case MESA_FORMAT_ARGB1555_REV: + SETfield(sq_tex_resource1, FMT_1_5_5_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Y, + 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); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_AL88: + case MESA_FORMAT_AL88_REV: /* TODO : Check this. */ + SETfield(sq_tex_resource1, FMT_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGB332: + SETfield(sq_tex_resource1, FMT_3_3_2, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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_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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_A8: /* ZERO, ZERO, ZERO, X */ + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_L8: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_I8: /* X, X, X, X */ + case MESA_FORMAT_CI8: + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGBA_FLOAT32: + SETfield(sq_tex_resource1, FMT_32_32_32_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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); + break; + case MESA_FORMAT_RGBA_FLOAT16: + SETfield(sq_tex_resource1, FMT_16_16_16_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + 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); + break; + case MESA_FORMAT_ALPHA_FLOAT32: /* ZERO, ZERO, ZERO, X */ + SETfield(sq_tex_resource1, FMT_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_ALPHA_FLOAT16: /* ZERO, ZERO, ZERO, X */ + SETfield(sq_tex_resource1, FMT_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + 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_LUMINANCE_FLOAT32: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT16: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + SETfield(sq_tex_resource1, FMT_32_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + SETfield(sq_tex_resource1, FMT_16_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */ + SETfield(sq_tex_resource1, FMT_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */ + SETfield(sq_tex_resource1, FMT_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_Z16: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_16, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_X8_Z24: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_8_24, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_S8_Z24: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_8_24, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_Z24_S8: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_24_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_Z32: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_32, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_S8: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_SRGBA8: + 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); + 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); + 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); + SETbit(sq_tex_resource4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); + break; + case MESA_FORMAT_SLA8: + SETfield(sq_tex_resource1, FMT_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_Y, + 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; + case MESA_FORMAT_SL8: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + 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_1, + 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; + default: + fprintf(stderr,"Invalid format for copy %s\n",_mesa_get_format_name(mesa_format)); + assert("Invalid format for US output\n"); + return; + }; + + SETfield(sq_tex_resource0, (TexelPitch/8)-1, PITCH_shift, PITCH_mask); + SETfield(sq_tex_resource0, w - 1, TEX_WIDTH_shift, TEX_WIDTH_mask); + SETfield(sq_tex_resource1, h - 1, TEX_HEIGHT_shift, TEX_HEIGHT_mask); + + sq_tex_resource2 = src_offset / 256; + + SETfield(sq_tex_resource6, SQ_TEX_VTX_VALID_TEXTURE, + SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, + SQ_TEX_RESOURCE_WORD6_0__TYPE_mask); + + r700SyncSurf(context, bo, + RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, + 0, TC_ACTION_ENA_bit); + + BEGIN_BATCH_NO_AUTOSTATE(9 + 4); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + R600_OUT_BATCH(0 * 7); + + R600_OUT_BATCH(sq_tex_resource0); + R600_OUT_BATCH(sq_tex_resource1); + R600_OUT_BATCH(sq_tex_resource2); + R600_OUT_BATCH(0); //SQ_TEX_RESOURCE3 + R600_OUT_BATCH(sq_tex_resource4); + R600_OUT_BATCH(0); //SQ_TEX_RESOURCE5 + R600_OUT_BATCH(sq_tex_resource6); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + END_BATCH(); + COMMIT_BATCH(); +} + +static inline void +set_tex_sampler(context_t * context) +{ + uint32_t sq_tex_sampler_word0 = 0, sq_tex_sampler_word1 = 0, sq_tex_sampler_word2 = 0; + int i = 0; + + SETbit(sq_tex_sampler_word2, SQ_TEX_SAMPLER_WORD2_0__TYPE_bit); + + BATCH_LOCALS(&context->radeon); + + BEGIN_BATCH_NO_AUTOSTATE(5); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3)); + R600_OUT_BATCH(i * 3); + R600_OUT_BATCH(sq_tex_sampler_word0); + R600_OUT_BATCH(sq_tex_sampler_word1); + R600_OUT_BATCH(sq_tex_sampler_word2); + END_BATCH(); + +} + +static inline void +set_scissors(context_t *context, int x1, int y1, int x2, int y2) +{ + BATCH_LOCALS(&context->radeon); + + BEGIN_BATCH_NO_AUTOSTATE(17); + R600_OUT_BATCH_REGSEQ(PA_SC_SCREEN_SCISSOR_TL, 2); + R600_OUT_BATCH((x1 << 0) | (y1 << 16)); + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + + R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 3); + R600_OUT_BATCH(0); //PA_SC_WINDOW_OFFSET + R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); //PA_SC_WINDOW_SCISSOR_TL + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + + R600_OUT_BATCH_REGSEQ(PA_SC_GENERIC_SCISSOR_TL, 2); + R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + + /* XXX 16 of these PA_SC_VPORT_SCISSOR_0_TL_num ... */ + R600_OUT_BATCH_REGSEQ(PA_SC_VPORT_SCISSOR_0_TL, 2 ); + R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + END_BATCH(); + + COMMIT_BATCH(); + +} + +static inline void +set_vb_data(context_t * context, int src_x, int src_y, int dst_x, int dst_y, + int w, int h, int src_h, unsigned flip_y) +{ + float *vb; + radeon_bo_map(context->blit_bo, 1); + vb = context->blit_bo->ptr; + + vb[0] = (float)(dst_x); + vb[1] = (float)(dst_y); + vb[2] = (float)(src_x); + vb[3] = (flip_y) ? (float)(src_h - src_y) : (float)src_y; + + vb[4] = (float)(dst_x); + vb[5] = (float)(dst_y + h); + vb[6] = (float)(src_x); + vb[7] = (flip_y) ? (float)(src_h - (src_y + h)) : (float)(src_y + h); + + vb[8] = (float)(dst_x + w); + vb[9] = (float)(dst_y + h); + vb[10] = (float)(src_x + w); + vb[11] = (flip_y) ? (float)(src_h - (src_y + h)) : (float)(src_y + h); + + radeon_bo_unmap(context->blit_bo); + +} + +static inline void +draw_auto(context_t *context) +{ + BATCH_LOCALS(&context->radeon); + uint32_t vgt_primitive_type = 0, vgt_index_type = 0, vgt_draw_initiator = 0, vgt_num_indices; + + SETfield(vgt_primitive_type, DI_PT_RECTLIST, + VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, + VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask); + SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, + INDEX_TYPE_mask); + SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, + MAJOR_MODE_mask); + SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, + SOURCE_SELECT_mask); + + vgt_num_indices = 3; + + BEGIN_BATCH_NO_AUTOSTATE(10); + // prim + R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1); + R600_OUT_BATCH(vgt_primitive_type); + // index type + R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); + R600_OUT_BATCH(vgt_index_type); + // num instances + R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); + R600_OUT_BATCH(1); + // + R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); + R600_OUT_BATCH(vgt_num_indices); + R600_OUT_BATCH(vgt_draw_initiator); + + END_BATCH(); + COMMIT_BATCH(); +} + +static inline void +set_default_state(context_t *context) +{ + int ps_prio = 0; + int vs_prio = 1; + int gs_prio = 2; + int es_prio = 3; + int num_ps_gprs; + int num_vs_gprs; + int num_gs_gprs; + int num_es_gprs; + int num_temp_gprs; + int num_ps_threads; + int num_vs_threads; + int num_gs_threads; + int num_es_threads; + int num_ps_stack_entries; + int num_vs_stack_entries; + int num_gs_stack_entries; + int num_es_stack_entries; + uint32_t sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; + uint32_t sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; + uint32_t ta_cntl_aux, db_watermarks, sq_dyn_gpr_cntl_ps_flush_req, db_debug; + BATCH_LOCALS(&context->radeon); + + switch (context->radeon.radeonScreen->chip_family) { + case CHIP_FAMILY_R600: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_FAMILY_RV630: + case CHIP_FAMILY_RV635: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 40; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_FAMILY_RV610: + case CHIP_FAMILY_RV620: + case CHIP_FAMILY_RS780: + case CHIP_FAMILY_RS880: + default: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_FAMILY_RV670: + num_ps_gprs = 144; + num_vs_gprs = 40; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_FAMILY_RV770: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 256; + num_vs_stack_entries = 256; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_FAMILY_RV730: + case CHIP_FAMILY_RV740: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_FAMILY_RV710: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 48; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + } + + sq_config = 0; + if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710)) + CLEARbit(sq_config, VC_ENABLE_bit); + else + SETbit(sq_config, VC_ENABLE_bit); + SETbit(sq_config, DX9_CONSTS_bit); + SETbit(sq_config, ALU_INST_PREFER_VECTOR_bit); + SETfield(sq_config, ps_prio, PS_PRIO_shift, PS_PRIO_mask); + SETfield(sq_config, vs_prio, VS_PRIO_shift, VS_PRIO_mask); + SETfield(sq_config, gs_prio, GS_PRIO_shift, GS_PRIO_mask); + SETfield(sq_config, es_prio, ES_PRIO_shift, ES_PRIO_mask); + + sq_gpr_resource_mgmt_1 = 0; + SETfield(sq_gpr_resource_mgmt_1, num_ps_gprs, NUM_PS_GPRS_shift, NUM_PS_GPRS_mask); + SETfield(sq_gpr_resource_mgmt_1, num_vs_gprs, NUM_VS_GPRS_shift, NUM_VS_GPRS_mask); + SETfield(sq_gpr_resource_mgmt_1, num_temp_gprs, + NUM_CLAUSE_TEMP_GPRS_shift, NUM_CLAUSE_TEMP_GPRS_mask); + + sq_gpr_resource_mgmt_2 = 0; + SETfield(sq_gpr_resource_mgmt_2, num_gs_gprs, NUM_GS_GPRS_shift, NUM_GS_GPRS_mask); + SETfield(sq_gpr_resource_mgmt_2, num_es_gprs, NUM_ES_GPRS_shift, NUM_ES_GPRS_mask); + + sq_thread_resource_mgmt = 0; + SETfield(sq_thread_resource_mgmt, num_ps_threads, + NUM_PS_THREADS_shift, NUM_PS_THREADS_mask); + SETfield(sq_thread_resource_mgmt, num_vs_threads, + NUM_VS_THREADS_shift, NUM_VS_THREADS_mask); + SETfield(sq_thread_resource_mgmt, num_gs_threads, + NUM_GS_THREADS_shift, NUM_GS_THREADS_mask); + SETfield(sq_thread_resource_mgmt, num_es_threads, + NUM_ES_THREADS_shift, NUM_ES_THREADS_mask); + + sq_stack_resource_mgmt_1 = 0; + SETfield(sq_stack_resource_mgmt_1, num_ps_stack_entries, + NUM_PS_STACK_ENTRIES_shift, NUM_PS_STACK_ENTRIES_mask); + SETfield(sq_stack_resource_mgmt_1, num_vs_stack_entries, + NUM_VS_STACK_ENTRIES_shift, NUM_VS_STACK_ENTRIES_mask); + + sq_stack_resource_mgmt_2 = 0; + SETfield(sq_stack_resource_mgmt_2, num_gs_stack_entries, + NUM_GS_STACK_ENTRIES_shift, NUM_GS_STACK_ENTRIES_mask); + SETfield(sq_stack_resource_mgmt_2, num_es_stack_entries, + NUM_ES_STACK_ENTRIES_shift, NUM_ES_STACK_ENTRIES_mask); + + ta_cntl_aux = 0; + SETfield(ta_cntl_aux, 28, TD_FIFO_CREDIT_shift, TD_FIFO_CREDIT_mask); + db_watermarks = 0; + SETfield(db_watermarks, 4, DEPTH_FREE_shift, DEPTH_FREE_mask); + SETfield(db_watermarks, 16, DEPTH_FLUSH_shift, DEPTH_FLUSH_mask); + SETfield(db_watermarks, 0, FORCE_SUMMARIZE_shift, FORCE_SUMMARIZE_mask); + SETfield(db_watermarks, 4, DEPTH_PENDING_FREE_shift, DEPTH_PENDING_FREE_mask); + sq_dyn_gpr_cntl_ps_flush_req = 0; + db_debug = 0; + if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) { + SETfield(ta_cntl_aux, 3, GRADIENT_CREDIT_shift, GRADIENT_CREDIT_mask); + db_debug = 0x82000000; + SETfield(db_watermarks, 16, DEPTH_CACHELINE_FREE_shift, DEPTH_CACHELINE_FREE_mask); + } else { + SETfield(ta_cntl_aux, 2, GRADIENT_CREDIT_shift, GRADIENT_CREDIT_mask); + SETfield(db_watermarks, 4, DEPTH_CACHELINE_FREE_shift, DEPTH_CACHELINE_FREE_mask); + SETbit(sq_dyn_gpr_cntl_ps_flush_req, VS_PC_LIMIT_ENABLE_bit); + } + + BEGIN_BATCH_NO_AUTOSTATE(117); + R600_OUT_BATCH_REGSEQ(SQ_CONFIG, 6); + R600_OUT_BATCH(sq_config); + R600_OUT_BATCH(sq_gpr_resource_mgmt_1); + R600_OUT_BATCH(sq_gpr_resource_mgmt_2); + R600_OUT_BATCH(sq_thread_resource_mgmt); + R600_OUT_BATCH(sq_stack_resource_mgmt_1); + R600_OUT_BATCH(sq_stack_resource_mgmt_2); + + R600_OUT_BATCH_REGVAL(TA_CNTL_AUX, ta_cntl_aux); + R600_OUT_BATCH_REGVAL(VC_ENHANCE, 0); + R600_OUT_BATCH_REGVAL(R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, sq_dyn_gpr_cntl_ps_flush_req); + R600_OUT_BATCH_REGVAL(DB_DEBUG, db_debug); + R600_OUT_BATCH_REGVAL(DB_WATERMARKS, db_watermarks); + + R600_OUT_BATCH_REGSEQ(SQ_ESGS_RING_ITEMSIZE, 9); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGVAL(CB_CLRCMP_CONTROL, + (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)); + R600_OUT_BATCH_REGVAL(R7xx_CB_SHADER_CONTROL, (RT0_ENABLE_bit)); + R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, (0xcc << ROP3_shift)); + + R600_OUT_BATCH_REGVAL(PA_CL_VTE_CNTL, VTX_XY_FMT_bit); + R600_OUT_BATCH_REGVAL(PA_CL_VS_OUT_CNTL, 0); + R600_OUT_BATCH_REGVAL(PA_CL_CLIP_CNTL, CLIP_DISABLE_bit); + R600_OUT_BATCH_REGVAL(PA_SU_SC_MODE_CNTL, (FACE_bit) | + (POLYMODE_PTYPE__TRIANGLES << POLYMODE_FRONT_PTYPE_shift) | + (POLYMODE_PTYPE__TRIANGLES << POLYMODE_BACK_PTYPE_shift)); + R600_OUT_BATCH_REGVAL(PA_SU_VTX_CNTL, (PIX_CENTER_bit) | + (X_ROUND_TO_EVEN << PA_SU_VTX_CNTL__ROUND_MODE_shift) | + (X_1_256TH << QUANT_MODE_shift)); + + R600_OUT_BATCH_REGSEQ(VGT_MAX_VTX_INDX, 4); + R600_OUT_BATCH(2048); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGSEQ(VGT_OUTPUT_PATH_CNTL, 13); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGVAL(VGT_PRIMITIVEID_EN, 0); + R600_OUT_BATCH_REGVAL(VGT_MULTI_PRIM_IB_RESET_EN, 0); + R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_0, 0); + R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_1, 0); + + R600_OUT_BATCH_REGSEQ(VGT_STRMOUT_EN, 3); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGVAL(VGT_STRMOUT_BUFFER_EN, 0); + + END_BATCH(); + COMMIT_BATCH(); +} + +static GLboolean validate_buffers(context_t *rmesa, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rmesa->blit_bo, RADEON_GEM_DOMAIN_GTT, 0); + + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, + rmesa->blit_bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, + first_elem(&rmesa->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +unsigned r600_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x, + unsigned src_y, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x, + unsigned dst_y, + unsigned w, + unsigned h, + unsigned flip_y) +{ + context_t *context = R700_CONTEXT(ctx); + int id = 0; + + if (!is_blit_supported(dst_mesaformat)) + return GL_FALSE; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (src_offset % 256 || dst_offset % 256) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: width %d, height %d, pitch %d vs %d, format %s\n", + src_width, src_height, src_pitch, + _mesa_format_row_stride(src_mesaformat, src_width), + _mesa_get_format_name(src_mesaformat)); + fprintf(stderr, "dst: width %d, height %d, pitch %d, format %s\n", + dst_width, dst_height, + _mesa_format_row_stride(dst_mesaformat, dst_width), + _mesa_get_format_name(dst_mesaformat)); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(ctx); + + rcommonEnsureCmdBufSpace(&context->radeon, 304, __FUNCTION__); + + /* load shaders */ + load_shaders(context->radeon.glCtx); + + if (!validate_buffers(context, src_bo, dst_bo)) + return GL_FALSE; + + /* set clear state */ + /* 117 */ + set_default_state(context); + + /* shaders */ + /* 72 */ + set_shaders(context); + + /* src */ + /* 20 */ + set_tex_resource(context, src_mesaformat, src_bo, + src_width, src_height, src_pitch, src_offset); + + /* 5 */ + set_tex_sampler(context); + + /* dst */ + /* 27 */ + set_render_target(context, dst_bo, dst_mesaformat, + dst_pitch, dst_width, dst_height, dst_offset); + /* scissors */ + /* 17 */ + set_scissors(context, dst_x, dst_y, dst_x + dst_width, dst_y + dst_height); + + set_vb_data(context, src_x, src_y, dst_x, dst_y, w, h, src_height, flip_y); + /* Vertex buffer setup */ + /* 24 */ + set_vtx_resource(context); + + /* draw */ + /* 10 */ + draw_auto(context); + + /* 7 */ + r700SyncSurf(context, dst_bo, 0, + RADEON_GEM_DOMAIN_VRAM|RADEON_GEM_DOMAIN_GTT, + CB_ACTION_ENA_bit | (1 << (id + 6))); + + /* 5 */ + /* XXX drm should handle this in fence submit */ + r700WaitForIdleClean(context); + + radeonFlush(ctx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/r600/r600_blit.h b/src/mesa/drivers/dri/r600/r600_blit.h new file mode 100644 index 0000000000..f280e23489 --- /dev/null +++ b/src/mesa/drivers/dri/r600/r600_blit.h @@ -0,0 +1,21 @@ +unsigned r600_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned w, + unsigned h, + unsigned flip_y); + diff --git a/src/mesa/drivers/dri/r600/r600_blit_shaders.h b/src/mesa/drivers/dri/r600/r600_blit_shaders.h new file mode 100644 index 0000000000..492dde9636 --- /dev/null +++ b/src/mesa/drivers/dri/r600/r600_blit_shaders.h @@ -0,0 +1,28 @@ +const uint32_t r6xx_vs[] = +{ + 0x00000004, // CF_DWORD0(ADDR(4)) + 0x81000000, // SQ_CF_INST_VTX COUNT(1) + 0x0000203c, // CF_EXP_IMP CF_POS0 SQ_EXPORT_POS RW_GPR(0) ELEM_SIZE(0) + 0x94000b08, // SQ_CF_INST_EXPORT_DONE SWZ XY01 BARRIER(1) + 0x00004000, // CF_EXP_IMP 0 SQ_EXPORT_PARAM RW_GPR(0) ELEM_SIZE(0) + 0x14200b1a, // SQ_CF_INST_EXPORT_DONE SWZ ZW01 EOP(1) BARRIER(0) + 0x00000000, + 0x00000000, + 0x3c000000, // SQ_VTX_INST_FETCH BUFFER_ID(0) MEGA_FETCH_COUNT(16) + 0x68cd1000, // DST_GPR(0) DST_SWZ: XYZW DATA_FORMAT(35) SQ_NUM_FORMAT_SCALED SQ_FORMAT_COMP_SIGNED + 0x00080000, // ENDIAN_SWAP(SQ_ENDIAN_NONE) MEGA_FETCH(1) + 0x00000000, // VTX_DWORD_PAD +}; + +const uint32_t r6xx_ps[] = +{ + 0x00000002, // CF_DWORD0 AADR(2) + 0x80800000, // SQ_CF_INST_TEX COUNT(1) + 0x00000000, // CF_ALLOC_IMP_EXP0 SQ_EXPORT_PIXEL RW_GPR(0) ELEM_SIZE(0) + 0x94200688, // SQ_CF_INST_EXPORT_DONE EOP(1) BARRIER(1) SWZ: XYZW + 0x00000010, // SQ_TEX_INST_SAMPLE SRC_GPR(0) RESOURCE_ID(0) + 0x000d1000, // DST_GPR(0) SWZ: XYZW TEX_UNNORMALIZED + 0xb0800000, // SAMPLER_ID(0) SRC_SWZ XYZW + 0x00000000, // TEX_DWORD_PAD +}; + diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.c b/src/mesa/drivers/dri/r600/r600_cmdbuf.c index 370bb04f93..afe2d55dc7 100644 --- a/src/mesa/drivers/dri/r600/r600_cmdbuf.c +++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "main/context.h" #include "main/simple_list.h" -#include "swrast/swrast.h" #include "drm.h" #include "radeon_drm.h" @@ -49,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r600_cmdbuf.h" #include "r600_emit.h" #include "radeon_bocs_wrapper.h" -#include "radeon_mipmap_tree.h" #include "radeon_reg.h" #ifdef HAVE_LIBDRM_RADEON diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index cb549497f5..5b7d7c28ec 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -40,9 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/state.h" #include "main/bufferobj.h" #include "main/texobj.h" @@ -52,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vp_build.h" #include "drivers/common/driverfuncs.h" @@ -65,14 +62,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r600_emit.h" #include "radeon_bocs_wrapper.h" #include "radeon_queryobj.h" +#include "r600_blit.h" #include "r700_state.h" #include "r700_ioctl.h" -#include "vblank.h" #include "utils.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ #define R600_ENABLE_GLSL_TEST 1 @@ -240,19 +236,23 @@ static void r600_init_vtbl(radeonContextPtr radeon) radeon->vtbl.pre_emit_atoms = r600_vtbl_pre_emit_atoms; radeon->vtbl.fallback = r600_fallback; radeon->vtbl.emit_query_finish = r600_emit_query_finish; + radeon->vtbl.blit = r600_blit; } static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen) { - context_t *r600 = R700_CONTEXT(ctx); - - ctx->Const.MaxTextureImageUnits = - driQueryOptioni(&r600->radeon.optionCache, "texture_image_units"); - ctx->Const.MaxTextureCoordUnits = - driQueryOptioni(&r600->radeon.optionCache, "texture_coord_units"); + ctx->Const.MaxTextureImageUnits = 16; + /* 8 per clause on r6xx, 16 on r7xx + * but I think mesa only supports 8 at the moment + */ + ctx->Const.MaxTextureCoordUnits = 8; ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits); + ctx->Const.MaxCombinedTextureImageUnits = + ctx->Const.MaxVertexTextureImageUnits + + ctx->Const.MaxTextureImageUnits; + ctx->Const.MaxTextureMaxAnisotropy = 16.0; ctx->Const.MaxTextureLodBias = 16.0; @@ -284,9 +284,8 @@ static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen) ctx->Const.FragmentProgram.MaxNativeAttribs = 32; ctx->Const.FragmentProgram.MaxNativeParameters = 256; ctx->Const.FragmentProgram.MaxNativeAluInstructions = 8192; - /* 8 per clause on r6xx, 16 on rv670/r7xx */ - if ((screen->chip_family == CHIP_FAMILY_RV670) || - (screen->chip_family >= CHIP_FAMILY_RV770)) + /* 8 per clause on r6xx, 16 on r7xx */ + if (screen->chip_family >= CHIP_FAMILY_RV770) ctx->Const.FragmentProgram.MaxNativeTexInstructions = 16; else ctx->Const.FragmentProgram.MaxNativeTexInstructions = 8; @@ -378,7 +377,7 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual, _mesa_init_driver_functions(&functions); r700InitStateFuncs(&functions); - r600InitTextureFuncs(&functions); + r600InitTextureFuncs(&r600->radeon, &functions); r700InitShaderFuncs(&functions); radeonInitQueryObjFunctions(&functions); r700InitIoctlFuncs(&functions); diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h index a1b4af715e..72c8c869b7 100644 --- a/src/mesa/drivers/dri/r600/r600_context.h +++ b/src/mesa/drivers/dri/r600/r600_context.h @@ -148,6 +148,8 @@ struct r600_context { GLint nNumActiveAos; StreamDesc stream_desc[VERT_ATTRIB_MAX]; struct r700_index_buffer ind_buf; + struct radeon_bo *blit_bo; + GLboolean blit_bo_loaded; }; #define R700_CONTEXT(ctx) ((context_t *)(ctx->DriverCtx)) @@ -178,6 +180,8 @@ extern GLboolean r700SyncSurf(context_t *context, uint32_t write_domain, uint32_t sync_type); +extern void r700WaitForIdleClean(context_t *context); + extern void r700Start3D(context_t *context); extern void r600InitAtoms(context_t *context); extern void r700InitDraw(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/r600/r600_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c index 5c250c2418..1eb89a5305 100644 --- a/src/mesa/drivers/dri/r600/r600_emit.c +++ b/src/mesa/drivers/dri/r600/r600_emit.c @@ -37,10 +37,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "main/imports.h" #include "main/macros.h" -#include "main/image.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" diff --git a/src/mesa/drivers/dri/r600/r600_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c index f745fe3e8a..36a6e6e0a1 100644 --- a/src/mesa/drivers/dri/r600/r600_tex.c +++ b/src/mesa/drivers/dri/r600/r600_tex.c @@ -41,18 +41,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/mipmap.h" #include "main/simple_list.h" #include "main/texstore.h" -#include "main/teximage.h" #include "main/texobj.h" #include "texmem.h" #include "r600_context.h" -#include "r700_state.h" #include "radeon_mipmap_tree.h" #include "r600_tex.h" -#include "xmlpool.h" - static unsigned int translate_wrap_mode(GLenum wrapmode) { @@ -396,7 +392,7 @@ static struct gl_texture_object *r600NewTextureObject(GLcontext * ctx, return &t->base; } -void r600InitTextureFuncs(struct dd_function_table *functions) +void r600InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. @@ -424,6 +420,11 @@ void r600InitTextureFuncs(struct dd_function_table *functions) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; driInitTextureFormats(); diff --git a/src/mesa/drivers/dri/r600/r600_tex.h b/src/mesa/drivers/dri/r600/r600_tex.h index fb0e1a023e..1d75a2ecd6 100644 --- a/src/mesa/drivers/dri/r600/r600_tex.h +++ b/src/mesa/drivers/dri/r600/r600_tex.h @@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Texel pitch is 8 alignment. */ #define R700_TEXEL_PITCH_ALIGNMENT_MASK 0x7 -#define R700_MAX_TEXTURE_UNITS 8 /* TODO : should be 16, lets make it work, review later */ +#define R700_MAX_TEXTURE_UNITS 16 extern void r600SetDepthTexMode(struct gl_texture_object *tObj); @@ -58,6 +58,6 @@ extern void r600SetTexOffset(__DRIcontext *pDRICtx, GLint texname, extern GLboolean r600ValidateBuffers(GLcontext * ctx); -extern void r600InitTextureFuncs(struct dd_function_table *functions); +extern void r600InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions); #endif /* __r600_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c index b8466bdd75..8228cd67c8 100644 --- a/src/mesa/drivers/dri/r600/r600_texstate.c +++ b/src/mesa/drivers/dri/r600/r600_texstate.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "r600_context.h" -#include "r700_state.h" #include "radeon_mipmap_tree.h" #include "r600_tex.h" #include "r700_fragprog.h" @@ -85,6 +84,7 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED, FORMAT_COMP_X_shift, FORMAT_COMP_X_mask); @@ -95,6 +95,11 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED, FORMAT_COMP_W_shift, FORMAT_COMP_W_mask); + CLEARbit(t->SQ_TEX_RESOURCE0, TILE_TYPE_bit); + SETfield(t->SQ_TEX_RESOURCE0, ARRAY_LINEAR_GENERAL, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + switch (mesa_format) /* This is mesa format. */ { case MESA_FORMAT_RGBA8888: @@ -158,6 +163,32 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa 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); break; + case MESA_FORMAT_XRGB8888: + 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_Z, + 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_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_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_XRGB8888_REV: + 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_1, + 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); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W, + 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_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; case MESA_FORMAT_ARGB8888_REV: 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); @@ -515,6 +546,10 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa case MESA_FORMAT_Z24_S8: case MESA_FORMAT_Z32: case MESA_FORMAT_S8: + SETbit(t->SQ_TEX_RESOURCE0, TILE_TYPE_bit); + SETfield(t->SQ_TEX_RESOURCE0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); switch (mesa_format) { case MESA_FORMAT_Z16: SETfield(t->SQ_TEX_RESOURCE1, FMT_16, @@ -651,6 +686,12 @@ static GLuint r600_translate_shadow_func(GLenum func) } } +static INLINE uint32_t +S_FIXED(float value, uint32_t frac_bits) +{ + return value * (1 << frac_bits); +} + void r600SetDepthTexMode(struct gl_texture_object *tObj) { radeonTexObjPtr t; @@ -670,8 +711,9 @@ void r600SetDepthTexMode(struct gl_texture_object *tObj) * \param rmesa Context pointer * \param t the r300 texture object */ -static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *texObj) +static void setup_hardware_state(GLcontext * ctx, struct gl_texture_object *texObj, int unit) { + context_t *rmesa = R700_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); const struct gl_texture_image *firstImage; GLuint uTexelPitch, row_align; @@ -733,11 +775,21 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex t->SQ_TEX_RESOURCE2 = get_base_teximage_offset(t) / 256; - if ((t->maxLod - t->minLod) > 0) { - t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256; - SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask); - SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask); - } + t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256; + + SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask); + SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask); + + SETfield(t->SQ_TEX_SAMPLER1, + S_FIXED(CLAMP(t->base.MinLod - t->minLod, 0, 15), 6), + MIN_LOD_shift, MIN_LOD_mask); + SETfield(t->SQ_TEX_SAMPLER1, + S_FIXED(CLAMP(t->base.MaxLod - t->minLod, 0, 15), 6), + MAX_LOD_shift, MAX_LOD_mask); + SETfield(t->SQ_TEX_SAMPLER1, + S_FIXED(CLAMP(ctx->Texture.Unit[unit].LodBias + t->base.LodBias, -16, 16), 6), + SQ_TEX_SAMPLER_WORD1_0__LOD_BIAS_shift, SQ_TEX_SAMPLER_WORD1_0__LOD_BIAS_mask); + if(texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { SETfield(t->SQ_TEX_SAMPLER0, r600_translate_shadow_func(texObj->CompareFunc), DEPTH_COMPARE_FUNCTION_shift, DEPTH_COMPARE_FUNCTION_mask); @@ -754,9 +806,8 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex * * Mostly this means populating the texture object's mipmap tree. */ -static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj) +static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj, int unit) { - context_t *rmesa = R700_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); if (!radeon_validate_texture_miptree(ctx, texObj)) @@ -764,7 +815,7 @@ static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object /* Configure the hardware registers (more precisely, the cached version * of the hardware registers). */ - setup_hardware_state(rmesa, texObj); + setup_hardware_state(ctx, texObj, unit); t->validated = GL_TRUE; return GL_TRUE; @@ -805,7 +856,7 @@ GLboolean r600ValidateBuffers(GLcontext * ctx) if (!ctx->Texture.Unit[i]._ReallyEnabled) continue; - if (!r600_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) { + if (!r600_validate_texture(ctx, ctx->Texture.Unit[i]._Current, i)) { radeon_warning("failed to validate texture for unit %d.\n", i); } t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index 0ff16b4ddd..89adb77bf5 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -4469,7 +4469,7 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) } pAsm->D2.dst2.SaturateMode = 1; - pAsm->S[0].src.rtype = pAsm->D.dst.rtype; + pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; pAsm->S[0].src.reg = pAsm->D.dst.reg; noswizzle_PVSSRC(&(pAsm->S[0].src)); noneg_PVSSRC(&(pAsm->S[0].src)); @@ -4491,20 +4491,21 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) GLboolean assemble_XPD(r700_AssemblerBase *pAsm) { - BITS tmp; + BITS tmp1; + BITS tmp2 = 0; if( GL_FALSE == checkop2(pAsm) ) { return GL_FALSE; } - tmp = gethelpr(pAsm); + tmp1 = gethelpr(pAsm); pAsm->D.dst.opcode = SQ_OP2_INST_MUL; setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); pAsm->D.dst.rtype = DST_REG_TEMPORARY; - pAsm->D.dst.reg = tmp; + pAsm->D.dst.reg = tmp1; nomask_PVSDST(&(pAsm->D.dst)); if( GL_FALSE == assemble_src(pAsm, 0, -1) ) @@ -4530,11 +4531,11 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm) if(0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask) { - tmp = gethelpr(pAsm); + tmp2 = gethelpr(pAsm); setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); pAsm->D.dst.rtype = DST_REG_TEMPORARY; - pAsm->D.dst.reg = tmp; + pAsm->D.dst.reg = tmp2; nomask_PVSDST(&(pAsm->D.dst)); } @@ -4562,7 +4563,7 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm) // result1 + (neg) result0 setaddrmode_PVSSRC(&(pAsm->S[2].src),ADDR_ABSOLUTE); pAsm->S[2].src.rtype = SRC_REG_TEMPORARY; - pAsm->S[2].src.reg = tmp; + pAsm->S[2].src.reg = tmp1; neg_PVSSRC(&(pAsm->S[2].src)); noswizzle_PVSSRC(&(pAsm->S[2].src)); @@ -4585,7 +4586,7 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm) // Use tmp as source setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE); pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; - pAsm->S[0].src.reg = tmp; + pAsm->S[0].src.reg = tmp2; noneg_PVSSRC(&(pAsm->S[0].src)); noswizzle_PVSSRC(&(pAsm->S[0].src)); @@ -5090,15 +5091,15 @@ void add_return_inst(r700_AssemblerBase *pAsm) { if(GL_FALSE == add_cf_instruction(pAsm) ) { - return GL_FALSE; + return; } //pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1; pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0; - pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0; + pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0; pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE; pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0; - pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; + pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_RETURN; pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0; @@ -5302,7 +5303,7 @@ GLboolean assemble_CAL(r700_AssemblerBase *pAsm, GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue) { - GLfloat fLiteral[2] = {0.1, 0.0}; + /*GLfloat fLiteral[2] = {0.1, 0.0};*/ pAsm->D.dst.opcode = SQ_OP2_INST_MOV; pAsm->D.dst.op3 = 0; @@ -5353,7 +5354,7 @@ GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue) GLboolean testFlag(r700_AssemblerBase *pAsm) { - GLfloat fLiteral[2] = {0.1, 0.0}; + /*GLfloat fLiteral[2] = {0.1, 0.0};*/ //Test flag GLuint tmp = gethelpr(pAsm); @@ -6123,7 +6124,7 @@ GLboolean callPreSub(r700_AssemblerBase* pAsm, R700ControlFlowGenericClause* prelude_cf_ptr = NULL; - /* copy srcs to presub inputs */ + /* copy srcs to presub inputs */ pAsm->alu_x_opcode = SQ_CF_INST_ALU; for(i=0; i<uNumValidSrc; i++) { diff --git a/src/mesa/drivers/dri/r600/r700_assembler.h b/src/mesa/drivers/dri/r600/r700_assembler.h index 56baf5b0d9..0064d0814f 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.h +++ b/src/mesa/drivers/dri/r600/r700_assembler.h @@ -619,6 +619,7 @@ GLboolean assemble_RCP(r700_AssemblerBase *pAsm); GLboolean assemble_RSQ(r700_AssemblerBase *pAsm); GLboolean assemble_SCS(r700_AssemblerBase *pAsm); GLboolean assemble_SGE(r700_AssemblerBase *pAsm); +GLboolean assemble_CONT(r700_AssemblerBase *pAsm); GLboolean assemble_LOGIC(r700_AssemblerBase *pAsm, BITS opcode); GLboolean assemble_LOGIC_PRED(r700_AssemblerBase *pAsm, BITS opcode); diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index 3bc2d2ba02..e0be74935b 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -32,12 +32,10 @@ #include "r600_context.h" #include "r600_cmdbuf.h" -#include "r700_state.h" #include "r600_tex.h" #include "r700_oglprog.h" #include "r700_fragprog.h" #include "r700_vertprog.h" -#include "r700_ioctl.h" #include "radeon_mipmap_tree.h" @@ -303,14 +301,13 @@ static void r700SetRenderTarget(context_t *context, int id) R600_STATECHANGE(context, cb_target); /* color buffer */ - r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset; + r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset / 256; nPitchInPixel = rrb->pitch/rrb->cpp; SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, (nPitchInPixel/8)-1, PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask); SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1, SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask); - r700->render_target[id].CB_COLOR0_BASE.u32All = 0; SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask); SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ARRAY_LINEAR_GENERAL, CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); @@ -453,13 +450,31 @@ static void r700SendRenderTargetState(GLcontext *ctx, struct radeon_state_atom * R600_OUT_BATCH((2 << id)); END_BATCH(); } + /* Set CMASK & TILE buffer to the offset of color buffer as + * we don't use those this shouldn't cause any issue and we + * then have a valid cmd stream + */ + 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, + rrb->bo, + r700->render_target[id].CB_COLOR0_BASE.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, + rrb->bo, + r700->render_target[id].CB_COLOR0_BASE.u32All, + 0, RADEON_GEM_DOMAIN_VRAM, 0); + END_BATCH(); - BEGIN_BATCH_NO_AUTOSTATE(18); + BEGIN_BATCH_NO_AUTOSTATE(12); 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_TILE + (4 * id), r700->render_target[id].CB_COLOR0_TILE.u32All); - R600_OUT_BATCH_REGVAL(CB_COLOR0_FRAG + (4 * id), r700->render_target[id].CB_COLOR0_FRAG.u32All); R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), r700->render_target[id].CB_COLOR0_MASK.u32All); END_BATCH(); diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c index 98bfdd0937..09c48565b6 100644 --- a/src/mesa/drivers/dri/r600/r700_clear.c +++ b/src/mesa/drivers/dri/r600/r700_clear.c @@ -37,7 +37,6 @@ #include "r600_context.h" #include "r700_shaderinst.h" -#include "r600_emit.h" #include "r700_clear.h" static GLboolean r700ClearFast(context_t *context, GLbitfield mask) diff --git a/src/mesa/drivers/dri/r600/r700_ioctl.c b/src/mesa/drivers/dri/r600/r700_ioctl.c index 72a8978976..3bc422f394 100644 --- a/src/mesa/drivers/dri/r600/r700_ioctl.c +++ b/src/mesa/drivers/dri/r600/r700_ioctl.c @@ -32,10 +32,8 @@ #include "main/macros.h" #include "main/context.h" #include "main/simple_list.h" -#include "swrast/swrast.h" #include "radeon_common.h" -#include "radeon_lock.h" #include "r600_context.h" #include "r700_ioctl.h" diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c index 0d476fcd86..2a50361199 100644 --- a/src/mesa/drivers/dri/r600/r700_oglprog.c +++ b/src/mesa/drivers/dri/r600/r700_oglprog.c @@ -132,7 +132,7 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog) _mesa_delete_program(ctx, prog); } -static void +static GLboolean r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog; @@ -153,6 +153,8 @@ r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) break; } + /* XXX check if program is legal, within limits */ + return GL_TRUE; } static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index eab27cbd84..8f14af7472 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -42,7 +42,6 @@ #include "tnl/t_vp_build.h" #include "tnl/t_context.h" #include "tnl/t_vertex.h" -#include "tnl/t_pipeline.h" #include "vbo/vbo_context.h" #include "r600_context.h" @@ -116,8 +115,6 @@ void r700Start3D(context_t *context) END_BATCH(); COMMIT_BATCH(); - - r700WaitForIdleClean(context); } GLboolean r700SyncSurf(context_t *context, @@ -422,7 +419,7 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end, } /* start 3d, idle, cb/db flush */ -#define PRE_EMIT_STATE_BUFSZ 10 + 5 + 14 +#define PRE_EMIT_STATE_BUFSZ 5 + 5 + 18 static GLuint r700PredictRenderSize(GLcontext* ctx, const struct _mesa_prim *prim, @@ -935,6 +932,7 @@ static GLboolean r700TryDrawPrims(GLcontext *ctx, radeon_debug_remove_indent(); /* Flush render op cached for last several quads. */ + /* XXX drm should handle this in fence submit */ r700WaitForIdleClean(context); rrb = radeon_get_colorbuffer(&context->radeon); diff --git a/src/mesa/drivers/dri/r600/r700_shader.c b/src/mesa/drivers/dri/r600/r700_shader.c index 2eed1acc2f..67b0d40308 100644 --- a/src/mesa/drivers/dri/r600/r700_shader.c +++ b/src/mesa/drivers/dri/r600/r700_shader.c @@ -35,7 +35,6 @@ #include "main/glheader.h" #include "r600_context.h" -#include "r700_debug.h" #include "r700_shader.h" diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c index 3c8cb579f9..0240eefd5c 100644 --- a/src/mesa/drivers/dri/r600/r700_state.c +++ b/src/mesa/drivers/dri/r600/r700_state.c @@ -26,7 +26,6 @@ #include "main/glheader.h" #include "main/mtypes.h" -#include "main/state.h" #include "main/imports.h" #include "main/enums.h" #include "main/macros.h" @@ -36,11 +35,9 @@ #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vp_build.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "main/api_arrayelt.h" -#include "main/state.h" #include "main/framebuffer.h" #include "shader/prog_parameter.h" @@ -59,6 +56,7 @@ static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state); static void r700UpdatePolygonMode(GLcontext * ctx); static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state); static void r700SetStencilState(GLcontext * ctx, GLboolean state); +static void r700UpdateWindow(GLcontext * ctx, int id); void r700UpdateShaders(GLcontext * ctx) { @@ -780,6 +778,9 @@ static void r700Enable(GLcontext * ctx, GLenum cap, GLboolean state) //--------- case GL_LINE_STIPPLE: r700UpdateLineStipple(ctx); break; + case GL_DEPTH_CLAMP: + r700UpdateWindow(ctx, 0); + break; default: break; } @@ -1576,9 +1577,9 @@ static void r700InitSQConfig(GLcontext * ctx) SETbit(r700->sq_config.SQ_CONFIG.u32All, DX9_CONSTS_bit); SETbit(r700->sq_config.SQ_CONFIG.u32All, ALU_INST_PREFER_VECTOR_bit); SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, PS_PRIO_shift, PS_PRIO_mask); - SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, VS_PRIO_shift, VS_PRIO_mask); - SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, GS_PRIO_shift, GS_PRIO_mask); - SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, ES_PRIO_shift, ES_PRIO_mask); + SETfield(r700->sq_config.SQ_CONFIG.u32All, vs_prio, VS_PRIO_shift, VS_PRIO_mask); + SETfield(r700->sq_config.SQ_CONFIG.u32All, gs_prio, GS_PRIO_shift, GS_PRIO_mask); + SETfield(r700->sq_config.SQ_CONFIG.u32All, es_prio, ES_PRIO_shift, ES_PRIO_mask); r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All = 0; SETfield(r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All, num_ps_gprs, NUM_PS_GPRS_shift, NUM_PS_GPRS_mask); diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index 782f151f5a..618f7e1be1 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -647,7 +647,7 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */ /* so, use ctx->VertexProgem._Current */ struct gl_program_parameter_list *paramListOrginal = - paramListOrginal = ctx->VertexProgram._Current->Base.Parameters; + ctx->VertexProgram._Current->Base.Parameters; _mesa_load_state_parameters(ctx, paramList); diff --git a/src/mesa/drivers/dri/r600/radeon_tex_copy.c b/src/mesa/drivers/dri/r600/radeon_tex_copy.c new file mode 120000 index 0000000000..dfa5ba34e6 --- /dev/null +++ b/src/mesa/drivers/dri/r600/radeon_tex_copy.c @@ -0,0 +1 @@ +../radeon/radeon_tex_copy.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/server/radeon_egl.c b/src/mesa/drivers/dri/r600/server/radeon_egl.c deleted file mode 120000 index d7735a7643..0000000000 --- a/src/mesa/drivers/dri/r600/server/radeon_egl.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_egl.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 2b2f2c4aa7..a54ea16ec6 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -26,7 +26,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_queryobj.c \ radeon_span.c \ - radeon_texture.c + radeon_texture.c \ + radeon_tex_copy.c DRIVER_SOURCES = \ radeon_context.c \ @@ -40,6 +41,7 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_maos.c \ radeon_sanity.c \ + radeon_blit.c \ $(RADEON_COMMON_SOURCES) C_SOURCES = \ @@ -47,7 +49,7 @@ C_SOURCES = \ $(DRIVER_SOURCES) \ $(CS_SOURCES) -DRIVER_DEFINES = -DRADEON_R100 -Wall +DRIVER_DEFINES = -DRADEON_R100 DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.c b/src/mesa/drivers/dri/radeon/radeon_blit.c new file mode 100644 index 0000000000..0df4fbb33c --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_blit.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2010 Advanced Micro Devices, 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, 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 COPYRIGHT OWNER(S) 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 "radeon_common.h" +#include "radeon_context.h" +#include "radeon_blit.h" + +static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, + int reg, int count) +{ + if (count) + return CP_PACKET0(reg, count - 1); + return CP_PACKET2; +} + +/* common formats supported as both textures and render targets */ +static unsigned is_blit_supported(gl_format mesa_format) +{ + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_A8: + break; + default: + return 0; + } + + /* ??? */ + if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + +static inline void emit_vtx_state(struct r100_context *r100) +{ + BATCH_LOCALS(&r100->radeon); + + BEGIN_BATCH(8); + if (r100->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + OUT_BATCH_REGVAL(RADEON_SE_CNTL_STATUS, 0); + } else { + OUT_BATCH_REGVAL(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS); + + } + OUT_BATCH_REGVAL(RADEON_SE_COORD_FMT, (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_W0)); + OUT_BATCH_REGVAL(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0); + OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX)); + END_BATCH(); +} + +static void inline emit_tx_setup(struct r100_context *r100, + gl_format mesa_format, + struct radeon_bo *bo, + intptr_t offset, + unsigned width, + unsigned height, + unsigned pitch) +{ + uint32_t txformat = RADEON_TXFORMAT_NON_POWER2; + BATCH_LOCALS(&r100->radeon); + + assert(width <= 2047); + assert(height <= 2047); + assert(offset % 32 == 0); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + txformat |= RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_XRGB8888: + txformat |= RADEON_TXFORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + txformat |= RADEON_TXFORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + txformat |= RADEON_TXFORMAT_ARGB4444 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_ARGB1555: + txformat |= RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_A8: + txformat |= RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + default: + break; + } + + BEGIN_BATCH(18); + OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); + OUT_BATCH_REGVAL(RADEON_PP_TXCBLEND_0, (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX)); + OUT_BATCH_REGVAL(RADEON_PP_TXABLEND_0, (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX)); + OUT_BATCH_REGVAL(RADEON_PP_TXFILTER_0, (RADEON_CLAMP_S_CLAMP_LAST | + RADEON_CLAMP_T_CLAMP_LAST | + RADEON_MAG_FILTER_NEAREST | + RADEON_MIN_FILTER_NEAREST)); + OUT_BATCH_REGVAL(RADEON_PP_TXFORMAT_0, txformat); + OUT_BATCH_REGVAL(RADEON_PP_TEX_SIZE_0, ((width - 1) | + ((height - 1) << RADEON_TEX_VSIZE_SHIFT))); + OUT_BATCH_REGVAL(RADEON_PP_TEX_PITCH_0, pitch * _mesa_get_format_bytes(mesa_format) - 32); + + OUT_BATCH_REGSEQ(RADEON_PP_TXOFFSET_0, 1); + OUT_BATCH_RELOC(0, bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + + END_BATCH(); +} + +static inline void emit_cb_setup(struct r100_context *r100, + struct radeon_bo *bo, + intptr_t offset, + gl_format mesa_format, + unsigned pitch, + unsigned width, + unsigned height) +{ + uint32_t dst_pitch = pitch; + uint32_t dst_format = 0; + BATCH_LOCALS(&r100->radeon); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + dst_format = RADEON_COLOR_FORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + dst_format = RADEON_COLOR_FORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + dst_format = RADEON_COLOR_FORMAT_ARGB4444; + break; + case MESA_FORMAT_ARGB1555: + dst_format = RADEON_COLOR_FORMAT_ARGB1555; + break; + case MESA_FORMAT_A8: + dst_format = RADEON_COLOR_FORMAT_RGB8; + break; + default: + break; + } + + BEGIN_BATCH_NO_AUTOSTATE(18); + OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0); + OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, ((width << RADEON_RE_WIDTH_SHIFT) | + (height << RADEON_RE_HEIGHT_SHIFT))); + OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff); + OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); + OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format); + + OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1); + OUT_BATCH_RELOC(0, bo, 0, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1); + OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + + END_BATCH(); +} + +static GLboolean validate_buffers(struct r100_context *r100, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check_with_bo(r100->radeon.cmdbuf.cs, + first_elem(&r100->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Calculate texcoords for given image region. + * Output values are [minx, maxx, miny, maxy] + */ +static inline void calc_tex_coords(float img_width, float img_height, + float x, float y, + float reg_width, float reg_height, + unsigned flip_y, float *buf) +{ + buf[0] = x / img_width; + buf[1] = buf[0] + reg_width / img_width; + buf[2] = y / img_height; + buf[3] = buf[2] + reg_height / img_height; + if (flip_y) + { + buf[2] = 1.0 - buf[2]; + buf[3] = 1.0 - buf[3]; + } +} + +static inline void emit_draw_packet(struct r100_context *r100, + unsigned src_width, unsigned src_height, + unsigned src_x_offset, unsigned src_y_offset, + unsigned dst_x_offset, unsigned dst_y_offset, + unsigned reg_width, unsigned reg_height, + unsigned flip_y) +{ + float texcoords[4]; + float verts[12]; + BATCH_LOCALS(&r100->radeon); + + calc_tex_coords(src_width, src_height, + src_x_offset, src_y_offset, + reg_width, reg_height, + flip_y, texcoords); + + verts[0] = dst_x_offset; + verts[1] = dst_y_offset + reg_height; + verts[2] = texcoords[0]; + verts[3] = texcoords[3]; + + verts[4] = dst_x_offset + reg_width; + verts[5] = dst_y_offset + reg_height; + verts[6] = texcoords[1]; + verts[7] = texcoords[3]; + + verts[8] = dst_x_offset + reg_width; + verts[9] = dst_y_offset; + verts[10] = texcoords[1]; + verts[11] = texcoords[2]; + + BEGIN_BATCH(15); + OUT_BATCH(RADEON_CP_PACKET3_3D_DRAW_IMMD | (13 << 16)); + OUT_BATCH(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0); + OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING | + RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | + RADEON_CP_VC_CNTL_MAOS_ENABLE | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | + (3 << 16)); + OUT_BATCH_TABLE(verts, 12); + END_BATCH(); +} + +/** + * Copy a region of [@a width x @a height] pixels from source buffer + * to destination buffer. + * @param[in] r100 r100 context + * @param[in] src_bo source radeon buffer object + * @param[in] src_offset offset of the source image in the @a src_bo + * @param[in] src_mesaformat source image format + * @param[in] src_pitch aligned source image width + * @param[in] src_width source image width + * @param[in] src_height source image height + * @param[in] src_x_offset x offset in the source image + * @param[in] src_y_offset y offset in the source image + * @param[in] dst_bo destination radeon buffer object + * @param[in] dst_offset offset of the destination image in the @a dst_bo + * @param[in] dst_mesaformat destination image format + * @param[in] dst_pitch aligned destination image width + * @param[in] dst_width destination image width + * @param[in] dst_height destination image height + * @param[in] dst_x_offset x offset in the destination image + * @param[in] dst_y_offset y offset in the destination image + * @param[in] width region width + * @param[in] height region height + * @param[in] flip_y set if y coords of the source image need to be flipped + */ +unsigned r100_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) +{ + struct r100_context *r100 = R100_CONTEXT(ctx); + + if (!is_blit_supported(dst_mesaformat)) + return GL_FALSE; + + /* Make sure that colorbuffer has even width - hw limitation */ + if (dst_pitch % 2 > 0) + ++dst_pitch; + + /* Rendering to small buffer doesn't work. + * Looks like a hw limitation. + */ + if (dst_pitch < 32) + return GL_FALSE; + + /* Need to clamp the region size to make sure + * we don't read outside of the source buffer + * or write outside of the destination buffer. + */ + if (reg_width + src_x_offset > src_width) + reg_width = src_width - src_x_offset; + if (reg_height + src_y_offset > src_height) + reg_height = src_height - src_y_offset; + if (reg_width + dst_x_offset > dst_width) + reg_width = dst_width - dst_x_offset; + if (reg_height + dst_y_offset > dst_height) + reg_height = dst_height - dst_y_offset; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (src_offset % 32 || dst_offset % 32) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: size [%d x %d], pitch %d, " + "offset [%d x %d], format %s, bo %p\n", + src_width, src_height, src_pitch, + src_x_offset, src_y_offset, + _mesa_get_format_name(src_mesaformat), + src_bo); + fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n", + dst_pitch, dst_x_offset, dst_y_offset, + _mesa_get_format_name(dst_mesaformat), dst_bo); + fprintf(stderr, "region: %d x %d\n", reg_width, reg_height); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(ctx); + + rcommonEnsureCmdBufSpace(&r100->radeon, 59, __FUNCTION__); + + if (!validate_buffers(r100, src_bo, dst_bo)) + return GL_FALSE; + + /* 8 */ + emit_vtx_state(r100); + /* 18 */ + emit_tx_setup(r100, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch); + /* 18 */ + emit_cb_setup(r100, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height); + /* 15 */ + emit_draw_packet(r100, src_width, src_height, + src_x_offset, src_y_offset, + dst_x_offset, dst_y_offset, + reg_width, reg_height, + flip_y); + + radeonFlush(ctx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.h b/src/mesa/drivers/dri/radeon/radeon_blit.h new file mode 100644 index 0000000000..d36366ff79 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_blit.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Advanced Micro Devices, 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, 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 COPYRIGHT OWNER(S) 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 RADEON_BLIT_H +#define RADEON_BLIT_H + +void r100_blit_init(struct r100_context *r100); + +unsigned r100_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned width, + unsigned height, + unsigned flip_y); + +#endif // RADEON_BLIT_H diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index e0b853bc97..79f3ff7da6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -1036,10 +1036,11 @@ static INLINE void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state OUT_BATCH_TABLE(atom->cmd, dwords); END_BATCH(); } + atom->dirty = GL_FALSE; + } else { radeon_print(RADEON_STATE, RADEON_VERBOSE, " skip state %s\n", atom->name); } - atom->dirty = GL_FALSE; } diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index b9c29b937e..94f476617b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drirenderbuffer.h" #include "drivers/common/meta.h" #include "main/context.h" -#include "main/framebuffer.h" #include "main/renderbuffer.h" #include "main/state.h" #include "main/simple_list.h" @@ -47,10 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#if defined(RADEON_R600) -#include "r600_context.h" -#endif - #define DRIVER_DATE "20090101" #ifndef RADEON_DEBUG diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index ab79d2dc0f..e397ee8c22 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -518,6 +518,26 @@ struct radeon_context { void (*free_context)(GLcontext *ctx); void (*emit_query_finish)(radeonContextPtr radeon); void (*update_scissor)(GLcontext *ctx); + unsigned (*blit)(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y); } vtbl; }; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 3cd305b0a2..475e93bc05 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -39,10 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/framebuffer.h" -#include "main/state.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -61,8 +58,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_swtcl.h" #include "radeon_tcl.h" -#include "radeon_maos.h" #include "radeon_queryobj.h" +#include "radeon_blit.h" #define need_GL_ARB_occlusion_query #define need_GL_EXT_blend_minmax @@ -73,7 +70,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRIVER_DATE "20061018" -#include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -202,6 +198,7 @@ static void r100_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = radeonFallback; radeon->vtbl.free_context = r100_vtbl_free_context; radeon->vtbl.emit_query_finish = r100_emit_query_finish; + radeon->vtbl.blit = r100_blit; } /* Create the device specific context. @@ -228,6 +225,7 @@ r100CreateContext( const __GLcontextModes *glVisual, if ( !rmesa ) return GL_FALSE; + rmesa->radeon.radeonScreen = screen; r100_init_vtbl(&rmesa->radeon); /* init exp fog table data */ @@ -257,7 +255,7 @@ r100CreateContext( const __GLcontextModes *glVisual, * (the texture functions are especially important) */ _mesa_init_driver_functions( &functions ); - radeonInitTextureFuncs( &functions ); + radeonInitTextureFuncs( &rmesa->radeon, &functions ); radeonInitQueryObjFunctions(&functions); if (!radeonInitContext(&rmesa->radeon, &functions, @@ -281,6 +279,7 @@ r100CreateContext( const __GLcontextModes *glVisual, "texture_units"); ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits; i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index dfedc38bfd..d84760bf74 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -453,7 +453,6 @@ struct r100_context { extern GLboolean r100CreateContext( const __GLcontextModes *glVisual, __DRIcontext *driContextPriv, void *sharedContextPrivate); - #endif /* __RADEON_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index bf46eb8aab..cc951a12cb 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -180,7 +180,6 @@ static int cs_begin(struct radeon_cs_int *cs, if (cs->cdw + ndw > cs->ndw) { uint32_t tmp, *ptr; - int num = (ndw > 0x3FF) ? ndw : 0x3FF; tmp = (cs->cdw + ndw + 0x3ff) & (~0x3ff); ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.h b/src/mesa/drivers/dri/radeon/radeon_debug.h index 26da31c1c4..ef8b9671ac 100644 --- a/src/mesa/drivers/dri/radeon/radeon_debug.h +++ b/src/mesa/drivers/dri/radeon/radeon_debug.h @@ -47,7 +47,11 @@ typedef enum radeon_debug_levels { * errors. */ #ifndef RADEON_DEBUG_LEVEL -#define RADEON_DEBUG_LEVEL RADEON_VERBOSE +# ifdef DEBUG +# define RADEON_DEBUG_LEVEL RADEON_TRACE +# else +# define RADEON_DEBUG_LEVEL RADEON_VERBOSE +# endif #endif typedef enum radeon_debug_types { diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 7b1f84a715..e780b9eef1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -531,10 +531,9 @@ radeon_render_texture(GLcontext * ctx, att->TextureLevel); if (att->Texture->Target == GL_TEXTURE_3D) { - GLuint offsets[6]; - radeon_miptree_depth_offsets(radeon_image->mt, att->TextureLevel, - offsets); - imageOffset += offsets[att->Zoffset]; + imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride * + radeon_image->mt->levels[att->TextureLevel].height * + att->Zoffset; } /* store that offset in the region, along with the correct pitch for diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index a9d50c5d07..c7ea452156 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -38,18 +38,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <errno.h> #include "main/attrib.h" -#include "main/enable.h" -#include "main/blend.h" #include "main/bufferobj.h" -#include "main/buffers.h" -#include "main/depth.h" -#include "main/shaders.h" -#include "main/texstate.h" -#include "main/varray.h" -#include "glapi/dispatch.h" #include "swrast/swrast.h" -#include "main/stencil.h" -#include "main/matrix.h" #include "main/glheader.h" #include "main/imports.h" @@ -58,15 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_common.h" -#include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_tcl.h" -#include "radeon_sanity.h" #define STANDALONE_MMIO -#include "radeon_macros.h" /* for INREG() */ -#include "drirenderbuffer.h" #include "vblank.h" #define RADEON_TIMEOUT 512 @@ -107,6 +92,8 @@ void radeonSetUpAtomList( r100ContextPtr rmesa ) insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]); for (i = 0; i < 6; ++i) insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]); + if (rmesa->radeon.radeonScreen->kernel_mm) + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.stp); insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye); insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd); insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog); diff --git a/src/mesa/drivers/dri/radeon/radeon_lighting.c b/src/mesa/drivers/dri/radeon/radeon_lighting.c deleted file mode 100644 index ba444f2b10..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_lighting.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. - * - * 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 SYSTEMS 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. - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keith@tungstengraphics.com> - */ - -#include "main/glheader.h" -#include "main/imports.h" -#include "api_arrayelt.h" -/* #include "mmath.h" */ -#include "main/enums.h" -#include "colormac.h" - - -#include "radeon_context.h" -#include "radeon_ioctl.h" -#include "radeon_state.h" -#include "radeon_tcl.h" -#include "radeon_tex.h" -#include "radeon_vtxfmt.h" - - - -/* ============================================================= - * Materials - */ - - -/* Update on colormaterial, material emmissive/ambient, - * lightmodel.globalambient - */ -void update_global_ambient( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - float *fcmd = (float *)RADEON_DB_STATE( glt ); - - /* Need to do more if both emmissive & ambient are PREMULT: - */ - if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] & - ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | - (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0) - { - COPY_3V( &fcmd[GLT_RED], - ctx->Light.Material[0].Emission); - ACC_SCALE_3V( &fcmd[GLT_RED], - ctx->Light.Model.Ambient, - ctx->Light.Material[0].Ambient); - } - else - { - COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); - } - - RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt); -} - -/* Update on change to - * - light[p].colors - * - light[p].enabled - * - material, - * - colormaterial enabled - * - colormaterial bitmask - */ -void update_light_colors( GLcontext *ctx, GLuint p ) -{ - struct gl_light *l = &ctx->Light.Light[p]; - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ - - if (l->Enabled) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - float *fcmd = (float *)RADEON_DB_STATE( lit[p] ); - GLuint bitmask = ctx->Light.ColorMaterialBitmask; - struct gl_material *mat = &ctx->Light.Material[0]; - - COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); - COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); - COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); - - if (!ctx->Light.ColorMaterialEnabled) - bitmask = 0; - - if ((bitmask & FRONT_AMBIENT_BIT) == 0) - SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient ); - - if ((bitmask & FRONT_DIFFUSE_BIT) == 0) - SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse ); - - if ((bitmask & FRONT_SPECULAR_BIT) == 0) - SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular ); - - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); - } -} - -/* Also fallback for asym colormaterial mode in twoside lighting... - */ -void check_twoside_fallback( GLcontext *ctx ) -{ - GLboolean fallback = GL_FALSE; - - if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { - if (memcmp( &ctx->Light.Material[0], - &ctx->Light.Material[1], - sizeof(struct gl_material)) != 0) - fallback = GL_TRUE; - else if (ctx->Light.ColorMaterialEnabled && - (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != - ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) - fallback = GL_TRUE; - } - - TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback ); -} - -void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) -{ - if (ctx->Light.ColorMaterialEnabled) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint light_model_ctl = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; - GLuint mask = ctx->Light.ColorMaterialBitmask; - - /* Default to PREMULT: - */ - light_model_ctl &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | - (3 << RADEON_AMBIENT_SOURCE_SHIFT) | - (3 << RADEON_DIFFUSE_SOURCE_SHIFT) | - (3 << RADEON_SPECULAR_SOURCE_SHIFT)); - - if (mask & FRONT_EMISSION_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_EMISSIVE_SOURCE_SHIFT); - } - - if (mask & FRONT_AMBIENT_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_AMBIENT_SOURCE_SHIFT); - } - - if (mask & FRONT_DIFFUSE_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_DIFFUSE_SOURCE_SHIFT); - } - - if (mask & FRONT_SPECULAR_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_SPECULAR_SOURCE_SHIFT); - } - - if (light_model_ctl != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) { - GLuint p; - - RADEON_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl; - - for (p = 0 ; p < MAX_LIGHTS; p++) - update_light_colors( ctx, p ); - update_global_ambient( ctx ); - } - } - - check_twoside_fallback( ctx ); -} - -void radeonUpdateMaterial( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl ); - GLuint p; - GLuint mask = ~0; - - if (ctx->Light.ColorMaterialEnabled) - mask &= ~ctx->Light.ColorMaterialBitmask; - - if (RADEON_DEBUG & RADEON_STATE) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (mask & FRONT_EMISSION_BIT) { - fcmd[MTL_EMMISSIVE_RED] = ctx->Light.Material[0].Emission[0]; - fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1]; - fcmd[MTL_EMMISSIVE_BLUE] = ctx->Light.Material[0].Emission[2]; - fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3]; - } - if (mask & FRONT_AMBIENT_BIT) { - fcmd[MTL_AMBIENT_RED] = ctx->Light.Material[0].Ambient[0]; - fcmd[MTL_AMBIENT_GREEN] = ctx->Light.Material[0].Ambient[1]; - fcmd[MTL_AMBIENT_BLUE] = ctx->Light.Material[0].Ambient[2]; - fcmd[MTL_AMBIENT_ALPHA] = ctx->Light.Material[0].Ambient[3]; - } - if (mask & FRONT_DIFFUSE_BIT) { - fcmd[MTL_DIFFUSE_RED] = ctx->Light.Material[0].Diffuse[0]; - fcmd[MTL_DIFFUSE_GREEN] = ctx->Light.Material[0].Diffuse[1]; - fcmd[MTL_DIFFUSE_BLUE] = ctx->Light.Material[0].Diffuse[2]; - fcmd[MTL_DIFFUSE_ALPHA] = ctx->Light.Material[0].Diffuse[3]; - } - if (mask & FRONT_SPECULAR_BIT) { - fcmd[MTL_SPECULAR_RED] = ctx->Light.Material[0].Specular[0]; - fcmd[MTL_SPECULAR_GREEN] = ctx->Light.Material[0].Specular[1]; - fcmd[MTL_SPECULAR_BLUE] = ctx->Light.Material[0].Specular[2]; - fcmd[MTL_SPECULAR_ALPHA] = ctx->Light.Material[0].Specular[3]; - } - if (mask & FRONT_SHININESS_BIT) { - fcmd[MTL_SHININESS] = ctx->Light.Material[0].Shininess; - } - - if (RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl )) { - for (p = 0 ; p < MAX_LIGHTS; p++) - update_light_colors( ctx, p ); - - check_twoside_fallback( ctx ); - update_global_ambient( ctx ); - } - else if (RADEON_DEBUG & (RADEON_PRIMS|DEBUG_STATE)) - fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__); -} - -/* _NEW_LIGHT - * _NEW_MODELVIEW - * _MESA_NEW_NEED_EYE_COORDS - * - * Uses derived state from mesa: - * _VP_inf_norm - * _h_inf_norm - * _Position - * _NormSpotDirection - * _ModelViewInvScale - * _NeedEyeCoords - * _EyeZDir - * - * which are calculated in light.c and are correct for the current - * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW - * and _MESA_NEW_NEED_EYE_COORDS. - */ -void radeonUpdateLighting( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - /* Have to check these, or have an automatic shortcircuit mechanism - * to remove noop statechanges. (Or just do a better job on the - * front end). - */ - { - GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; - - if (ctx->_NeedEyeCoords) - tmp &= ~RADEON_LIGHT_IN_MODELSPACE; - else - tmp |= RADEON_LIGHT_IN_MODELSPACE; - - - /* Leave this test disabled: (unexplained q3 lockup) (even with - new packets) - */ - if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) - { - RADEON_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp; - } - } - - { - GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye ); - fcmd[EYE_X] = ctx->_EyeZDir[0]; - fcmd[EYE_Y] = ctx->_EyeZDir[1]; - fcmd[EYE_Z] = - ctx->_EyeZDir[2]; - fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale; - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye ); - } - - -/* RADEON_STATECHANGE( rmesa, glt ); */ - - if (ctx->Light.Enabled) { - GLint p; - for (p = 0 ; p < MAX_LIGHTS; p++) { - if (ctx->Light.Light[p].Enabled) { - struct gl_light *l = &ctx->Light.Light[p]; - GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] ); - - if (l->EyePosition[3] == 0.0) { - COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); - COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); - fcmd[LIT_POSITION_W] = 0; - fcmd[LIT_DIRECTION_W] = 0; - } else { - COPY_4V( &fcmd[LIT_POSITION_X], l->_Position ); - fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0]; - fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1]; - fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2]; - fcmd[LIT_DIRECTION_W] = 0; - } - - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); - } - } - } -} - - -void radeonLightfv( GLcontext *ctx, GLenum light, - GLenum pname, const GLfloat *params ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLint p = light - GL_LIGHT0; - struct gl_light *l = &ctx->Light.Light[p]; - GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; - - - switch (pname) { - case GL_AMBIENT: - case GL_DIFFUSE: - case GL_SPECULAR: - update_light_colors( ctx, p ); - break; - - case GL_SPOT_DIRECTION: - /* picked up in update_light */ - break; - - case GL_POSITION: { - /* positions picked up in update_light, but can do flag here */ - GLuint flag = (p&1)? RADEON_LIGHT_1_IS_LOCAL : RADEON_LIGHT_0_IS_LOCAL; - GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; - - RADEON_STATECHANGE(rmesa, tcl); - if (l->EyePosition[3] != 0.0F) - rmesa->hw.tcl.cmd[idx] |= flag; - else - rmesa->hw.tcl.cmd[idx] &= ~flag; - break; - } - - case GL_SPOT_EXPONENT: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_SPOT_EXPONENT] = params[0]; - break; - - case GL_SPOT_CUTOFF: { - GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT; - GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; - - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff; - - RADEON_STATECHANGE(rmesa, tcl); - if (l->SpotCutoff != 180.0F) - rmesa->hw.tcl.cmd[idx] |= flag; - else - rmesa->hw.tcl.cmd[idx] &= ~flag; - break; - } - - case GL_CONSTANT_ATTENUATION: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_ATTEN_CONST] = params[0]; - break; - case GL_LINEAR_ATTENUATION: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_ATTEN_LINEAR] = params[0]; - break; - case GL_QUADRATIC_ATTENUATION: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_ATTEN_QUADRATIC] = params[0]; - break; - default: - return; - } - -} - - - - -void radeonLightModelfv( GLcontext *ctx, GLenum pname, - const GLfloat *param ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - switch (pname) { - case GL_LIGHT_MODEL_AMBIENT: - update_global_ambient( ctx ); - break; - - case GL_LIGHT_MODEL_LOCAL_VIEWER: - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.LocalViewer) - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER; - else - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER; - break; - - case GL_LIGHT_MODEL_TWO_SIDE: - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.TwoSide) - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE; - else - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE; - - check_twoside_fallback( ctx ); - -#if _HAVE_SWTNL - if (rmesa->TclFallback) { - radeonChooseRenderState( ctx ); - radeonChooseVertexState( ctx ); - } -#endif - break; - - case GL_LIGHT_MODEL_COLOR_CONTROL: - radeonUpdateSpecular(ctx); - - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= - ~RADEON_DIFFUSE_SPECULAR_COMBINE; - else - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= - RADEON_DIFFUSE_SPECULAR_COMBINE; - break; - - default: - break; - } -} - - -/* ============================================================= - * Fog - */ - - -static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - union { int i; float f; } c, d; - GLchan col[4]; - - c.i = rmesa->hw.fog.cmd[FOG_C]; - d.i = rmesa->hw.fog.cmd[FOG_D]; - - switch (pname) { - case GL_FOG_MODE: - if (!ctx->Fog.Enabled) - return; - RADEON_STATECHANGE(rmesa, tcl); - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK; - switch (ctx->Fog.Mode) { - case GL_LINEAR: - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR; - if (ctx->Fog.Start == ctx->Fog.End) { - c.f = 1.0F; - d.f = 1.0F; - } - else { - c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); - d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start); - } - break; - case GL_EXP: - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP; - c.f = 0.0; - d.f = ctx->Fog.Density; - break; - case GL_EXP2: - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2; - c.f = 0.0; - d.f = -(ctx->Fog.Density * ctx->Fog.Density); - break; - default: - return; - } - break; - case GL_FOG_DENSITY: - switch (ctx->Fog.Mode) { - case GL_EXP: - c.f = 0.0; - d.f = ctx->Fog.Density; - break; - case GL_EXP2: - c.f = 0.0; - d.f = -(ctx->Fog.Density * ctx->Fog.Density); - break; - default: - break; - } - break; - case GL_FOG_START: - case GL_FOG_END: - if (ctx->Fog.Mode == GL_LINEAR) { - if (ctx->Fog.Start == ctx->Fog.End) { - c.f = 1.0F; - d.f = 1.0F; - } else { - c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); - d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start); - } - } - break; - case GL_FOG_COLOR: - RADEON_STATECHANGE( rmesa, ctx ); - UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color ); - rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = - radeonPackColor( 4, col[0], col[1], col[2], 0 ); - break; - case GL_FOG_COORDINATE_SOURCE_EXT: - /* What to do? - */ - break; - default: - return; - } - - if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) { - RADEON_STATECHANGE( rmesa, fog ); - rmesa->hw.fog.cmd[FOG_C] = c.i; - rmesa->hw.fog.cmd[FOG_D] = d.i; - } -} - -/* Examine lighting and texture state to determine if separate specular - * should be enabled. - */ -void radeonUpdateSpecular( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; - - if (NEED_SECONDARY_COLOR(ctx)) { - p |= RADEON_SPECULAR_ENABLE; - } else { - p &= ~RADEON_SPECULAR_ENABLE; - } - - if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; - } - - /* Bizzare: have to leave lighting enabled to get fog. - */ - RADEON_STATECHANGE( rmesa, tcl ); - if ((ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } - else if (ctx->Fog.Enabled) { - if (ctx->Light.Enabled) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } else { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } - } - else if (ctx->Light.Enabled) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } else if (ctx->Fog.ColorSumEnabled ) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; - } else { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; - } - -#if _HAVE_SWTNL - /* Update vertex/render formats - */ - if (rmesa->TclFallback) { - radeonChooseRenderState( ctx ); - radeonChooseVertexState( ctx ); - } -#endif -} - - - -static void radeonLightingSpaceChange( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLboolean tmp; - RADEON_STATECHANGE( rmesa, tcl ); - - if (RADEON_DEBUG & RADEON_STATE) - fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords); - - if (ctx->_NeedEyeCoords) - tmp = ctx->Transform.RescaleNormals; - else - tmp = !ctx->Transform.RescaleNormals; - - if ( tmp ) { - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS; - } else { - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; - } -} - -void radeonInitLightStateFuncs( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - ctx->Driver.LightModelfv = radeonLightModelfv; - ctx->Driver.Lightfv = radeonLightfv; - ctx->Driver.Fogfv = radeonFogfv; - ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange; - - for (i = 0 ; i < 8; i++) { - struct gl_light *l = &ctx->Light.Light[i]; - GLenum p = GL_LIGHT0 + i; - *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX; - - ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient ); - ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse ); - ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular ); - ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 ); - ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 ); - ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent ); - ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff ); - ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION, - &l->ConstantAttenuation ); - ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION, - &l->LinearAttenuation ); - ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION, - &l->QuadraticAttenuation ); - } - - ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT, - ctx->Light.Model.Ambient ); - - ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); - ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); - ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); - ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); - ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); - ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 ); -} diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 9dee691938..7b6bd36dcf 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" #include "radeon_common.h" #include "radeon_lock.h" -#include "drirenderbuffer.h" /* Update the hardware state. This is called if another context has * grabbed the hardware lock, which includes the X server. This diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 033f26db2a..cd843d965e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -32,9 +32,9 @@ #include <unistd.h> #include "main/simple_list.h" -#include "main/texcompress.h" #include "main/teximage.h" #include "main/texobj.h" +#include "main/enums.h" #include "radeon_texture.h" static unsigned get_aligned_compressed_row_stride( @@ -42,18 +42,31 @@ static unsigned get_aligned_compressed_row_stride( unsigned width, unsigned minStride) { - const unsigned blockSize = _mesa_get_format_bytes(format); - unsigned blockWidth, blockHeight, numXBlocks; + const unsigned blockBytes = _mesa_get_format_bytes(format); + unsigned blockWidth, blockHeight; + unsigned stride; _mesa_get_format_block_size(format, &blockWidth, &blockHeight); - numXBlocks = (width + blockWidth - 1) / blockWidth; - - while (numXBlocks * blockSize < minStride) - { - ++numXBlocks; - } - return numXBlocks * blockSize; + /* Count number of blocks required to store the given width. + * And then multiple it with bytes required to store a block. + */ + stride = (width + blockWidth - 1) / blockWidth * blockBytes; + + /* Round the given minimum stride to the next full blocksize. + * (minStride + blockBytes - 1) / blockBytes * blockBytes + */ + if ( stride < minStride ) + stride = (minStride + blockBytes - 1) / blockBytes * blockBytes; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s width %u, minStride %u, block(bytes %u, width %u):" + "stride %u\n", + __func__, width, minStride, + blockBytes, blockWidth, + stride); + + return stride; } static unsigned get_compressed_image_size( @@ -68,19 +81,6 @@ static unsigned get_compressed_image_size( return rowStride * ((height + blockHeight - 1) / blockHeight); } -static int find_next_power_of_two(GLuint value) -{ - int i, tmp; - - i = 0; - tmp = value - 1; - while (tmp) { - tmp >>= 1; - i++; - } - return (1 << i); -} - /** * Compute sizes and fill in offset and blit information for the given * image (determined by \p face and \p level). @@ -95,7 +95,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree uint32_t row_align; GLuint height; - height = find_next_power_of_two(lvl->height); + height = _mesa_next_pow_two_32(lvl->height); /* Find image size in bytes */ if (_mesa_is_format_compressed(mt->mesaFormat)) { @@ -123,10 +123,11 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree lvl->faces[face].offset = *curOffset; *curOffset += lvl->size; - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, - "level %d, face %d: rs:%d %dx%d at %d\n", - level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p) level %d, face %d: rs:%d %dx%d at %d\n", + __func__, rmesa, + level, face, + lvl->rowstride, lvl->width, height, lvl->faces[face].offset); } static GLuint minify(GLuint size, GLuint levels) @@ -158,6 +159,10 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_ /* Note the required size in memory */ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, %p) total size %d\n", + __func__, rmesa, mt, mt->totalsize); } static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt) @@ -177,10 +182,20 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_ for(face = 0; face < mt->faces; face++) compute_tex_image_offset(rmesa, mt, face, level, &curOffset); + /* r600 cube levels seems to be aligned to 8 faces but + * we have separate register for 1'st level offset so add + * 2 image alignment after 1'st mip level */ + if(rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R600 && + mt->target == GL_TEXTURE_CUBE_MAP && level >= 1) + curOffset += 2 * mt->levels[level].size; } /* Note the required size in memory */ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, %p) total size %d\n", + __func__, rmesa, mt, mt->totalsize); } /** @@ -192,6 +207,10 @@ static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, { radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p) new tree is %p.\n", + __func__, rmesa, mt); + mt->mesaFormat = mesaFormat; mt->refcount = 1; mt->target = target; @@ -282,6 +301,12 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj, return; } + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p) target %s, min %d, max %d.\n", + __func__, tObj, + _mesa_lookup_enum_by_nr(tObj->Target), + minLod, maxLod); + /* save these values */ *pminLod = minLod; *pmaxLod = maxLod; @@ -328,7 +353,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g firstImage = texObj->Image[0][texObj->BaseLevel]; numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); - if (RADEON_DEBUG & RADEON_TEXTURE) { + if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target); fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat); @@ -369,8 +394,12 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) assert(!t->mt); - if (!texImg) + if (!texImg) { + radeon_warning("%s(%p) No image in given texture object(%p).\n", + __func__, rmesa, t); return; + } + numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1); @@ -380,25 +409,6 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) texImg->Depth, t->tile_bits); } -/* Although we use the image_offset[] array to store relative offsets - * to cube faces, Mesa doesn't know anything about this and expects - * each cube face to be treated as a separate image. - * - * These functions present that view to mesa: - */ -void -radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets) -{ - if (mt->target != GL_TEXTURE_3D || mt->faces == 1) { - offsets[0] = 0; - } else { - int i; - for (i = 0; i < 6; i++) { - offsets[i] = mt->levels[level].faces[i].offset; - } - } -} - GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level) @@ -425,6 +435,10 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, assert(dstlvl->height == image->base.Height); assert(dstlvl->depth == image->base.Depth); + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s miptree %p, image %p, face %d, level %d.\n", + __func__, mt, image, face, level); + radeon_bo_map(mt->bo, GL_TRUE); dest = mt->bo->ptr + dstlvl->faces[face].offset; @@ -456,6 +470,9 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, /* This condition should be removed, it's here to workaround * a segfault when mapping textures during software fallbacks. */ + radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, + "%s Trying to map texture in sowftware fallback.\n", + __func__); const uint32_t srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width); uint32_t rows = image->base.Height * image->base.Depth; @@ -562,9 +579,9 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod); - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", - __FUNCTION__, texObj ,t->minLod, t->maxLod); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", + __FUNCTION__, texObj ,t->minLod, t->maxLod); radeon_mipmap_tree *dst_miptree; dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod); @@ -573,11 +590,13 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); dst_miptree = t->mt; - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt); - } - } else if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: No matching miptree found, allocated new one %p\n", + __FUNCTION__, t->mt); + + } else { + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: Using miptree %p\n", __FUNCTION__, t->mt); } const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; @@ -588,22 +607,21 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t for (level = t->minLod; level <= t->maxLod; ++level) { img = get_radeon_texture_image(texObj->Image[face][level]); - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt); - } + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "Checking image level %d, face %d, mt %p ... ", + level, face, img->mt); if (img->mt != dst_miptree) { - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "MIGRATING\n"); - } + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "MIGRATING\n"); + struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { radeon_firevertices(rmesa); } migrate_image_to_miptree(dst_miptree, img, face, level); - } else if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "OK\n"); - } + } else + radeon_print(RADEON_TEXTURE, RADEON_TRACE, "OK\n"); } } @@ -619,4 +637,4 @@ uint32_t get_base_teximage_offset(radeonTexObj *texObj) } else { return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod); } -}
\ No newline at end of file +} diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index a10649b5ae..c911688c1a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -88,7 +88,5 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t); GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level); -void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); - uint32_t get_base_teximage_offset(radeonTexObj *texObj); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c index 98117cdfc1..d0dcf0e431 100644 --- a/src/mesa/drivers/dri/radeon/radeon_queryobj.c +++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.c @@ -65,7 +65,7 @@ static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q) } radeon_print(RADEON_STATE, RADEON_TRACE, - "%d start: %lx, end: %lx %ld\n", i, start, end, end - start); + "%d start: %llx, end: %llx %lld\n", i, start, end, end - start); } } else { for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) { diff --git a/src/mesa/drivers/dri/radeon/radeon_sanity.c b/src/mesa/drivers/dri/radeon/radeon_sanity.c index 1ab570f507..3e64be83ed 100644 --- a/src/mesa/drivers/dri/radeon/radeon_sanity.c +++ b/src/mesa/drivers/dri/radeon/radeon_sanity.c @@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "radeon_context.h" -#include "radeon_ioctl.h" #include "radeon_sanity.h" /* Set this '1' to get more verbiage. diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 3080a0fcd0..93b6399a66 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -47,7 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_macros.h" #include "radeon_screen.h" #include "radeon_common.h" -#include "radeon_span.h" #if defined(RADEON_R100) #include "radeon_context.h" #include "radeon_tex.h" @@ -66,7 +65,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" #include "vblank.h" -#include "drirenderbuffer.h" #include "radeon_bocs_wrapper.h" @@ -1481,7 +1479,7 @@ radeonCreateBuffer( __DRIscreen *driScrnPriv, if (!rfb) return GL_FALSE; - _mesa_initialize_framebuffer(&rfb->base, mesaVis); + _mesa_initialize_window_framebuffer(&rfb->base, mesaVis); if (mesaVis->redBits == 5) rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV; diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 1c9ec36dae..7db745a180 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -37,7 +37,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/api_arrayelt.h" #include "main/enums.h" #include "main/light.h" -#include "main/state.h" #include "main/context.h" #include "main/framebuffer.h" #include "main/simple_list.h" @@ -54,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "drirenderbuffer.h" static void radeonUpdateSpecular( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index dd82888254..91718a4777 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -33,7 +33,6 @@ #include "swrast/swrast.h" #include "vbo/vbo.h" -#include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -41,9 +40,6 @@ #include "radeon_mipmap_tree.h" #include "radeon_ioctl.h" #include "radeon_state.h" -#include "radeon_tcl.h" -#include "radeon_tex.h" -#include "radeon_swtcl.h" #include "radeon_queryobj.h" #include "../r200/r200_reg.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index 8bf1bfbc57..5a71b510fa 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -41,7 +41,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index cd02bfbcf5..ea796e1a45 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_tex.h" #include "radeon_tcl.h" #include "radeon_swtcl.h" #include "radeon_maos.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c index 14163f13af..c66e5d17b1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex.c @@ -44,9 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_mipmap_tree.h" -#include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_swtcl.h" #include "radeon_tex.h" #include "xmlpool.h" @@ -434,7 +432,7 @@ radeonNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) -void radeonInitTextureFuncs( struct dd_function_table *functions ) +void radeonInitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ) { functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; functions->TexImage1D = radeonTexImage1D; @@ -455,6 +453,11 @@ void radeonInitTextureFuncs( struct dd_function_table *functions ) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; functions->NewTextureImage = radeonNewTextureImage; diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.h b/src/mesa/drivers/dri/radeon/radeon_tex.h index a4aaddc74f..0113ffd3da 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.h +++ b/src/mesa/drivers/dri/radeon/radeon_tex.h @@ -52,6 +52,6 @@ extern int radeonUploadTexImages( r100ContextPtr rmesa, radeonTexObjPtr t, extern void radeonDestroyTexObj( r100ContextPtr rmesa, radeonTexObjPtr t ); -extern void radeonInitTextureFuncs( struct dd_function_table *functions ); +extern void radeonInitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ); #endif /* __RADEON_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_texcopy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c index ebc9c05b8a..d6aeb7049f 100644 --- a/src/mesa/drivers/dri/r300/r300_texcopy.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c @@ -26,7 +26,7 @@ */ #include "radeon_common.h" -#include "r300_context.h" +#include "radeon_texture.h" #include "main/image.h" #include "main/teximage.h" @@ -34,11 +34,7 @@ #include "drivers/common/meta.h" #include "radeon_mipmap_tree.h" -#include "r300_blit.h" -#include <main/debug.h> -// TODO: -// need to pass correct pitch for small dst textures! static GLboolean do_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, @@ -48,13 +44,13 @@ do_copy_texsubimage(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height) { - struct r300_context *r300 = R300_CONTEXT(ctx); + radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_renderbuffer *rrb; if (_mesa_get_format_bits(timg->base.TexFormat, GL_DEPTH_BITS) > 0) { - rrb = radeon_get_depthbuffer(&r300->radeon); + rrb = radeon_get_depthbuffer(radeon); } else { - rrb = radeon_get_colorbuffer(&r300->radeon); + rrb = radeon_get_colorbuffer(radeon); } if (!timg->mt) { @@ -69,10 +65,6 @@ do_copy_texsubimage(GLcontext *ctx, intptr_t src_offset = rrb->draw_offset; intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, _mesa_tex_target_to_face(target), level); - if (src_offset % 32 || dst_offset % 32) { - return GL_FALSE; - } - if (0) { fprintf(stderr, "%s: copying to face %d, level %d\n", __FUNCTION__, _mesa_tex_target_to_face(target), level); @@ -84,18 +76,19 @@ do_copy_texsubimage(GLcontext *ctx, } /* blit from src buffer to texture */ - return r300_blit(r300, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp, - rrb->base.Width, rrb->base.Height, x, y, - timg->mt->bo, dst_offset, timg->base.TexFormat, - timg->base.Width, timg->base.Width, timg->base.Height, - dstx, dsty, width, height, 1); + return radeon->vtbl.blit(ctx, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp, + rrb->base.Width, rrb->base.Height, x, y, + timg->mt->bo, dst_offset, timg->base.TexFormat, + timg->mt->levels[level].rowstride / _mesa_get_format_bytes(timg->base.TexFormat), + timg->base.Width, timg->base.Height, + dstx, dsty, width, height, 1); } -static void -r300CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border) +void +radeonCopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) { struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj = @@ -139,11 +132,11 @@ fail: width, height, border); } -static void -r300CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height) +void +radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height) { struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target); @@ -159,10 +152,3 @@ r300CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, xoffset, yoffset, x, y, width, height); } } - - -void r300_init_texcopy_functions(struct dd_function_table *table) -{ - table->CopyTexImage2D = r300CopyTexImage2D; - table->CopyTexSubImage2D = r300CopyTexSubImage2D; -}
\ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 03178116c1..86b213c05c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -33,6 +33,7 @@ #include "main/imports.h" #include "main/context.h" #include "main/convolve.h" +#include "main/enums.h" #include "main/mipmap.h" #include "main/texcompress.h" #include "main/texstore.h" @@ -53,6 +54,13 @@ void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, assert(rowsize <= dststride); assert(rowsize <= srcstride); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s dst %p, stride %u, src %p, stride %u, " + "numrows %u, rowsize %u.\n", + __func__, dst, dststride, + src, srcstride, + numrows, rowsize); + if (rowsize == srcstride && rowsize == dststride) { memcpy(dst, src, numrows*rowsize); } else { @@ -102,8 +110,12 @@ static void teximage_set_map_data(radeon_texture_image *image) { radeon_mipmap_level *lvl; - if (!image->mt) + if (!image->mt) { + radeon_warning("%s(%p) Trying to set map data without miptree.\n", + __func__, image); + return; + } lvl = &image->mt->levels[image->mtlevel]; @@ -162,15 +174,31 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeonTexObj* t = radeon_tex_obj(texObj); int face, level; - if (!radeon_validate_texture_miptree(ctx, texObj)) - return; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p)\n", + __func__, ctx, texObj); + + if (!radeon_validate_texture_miptree(ctx, texObj)) { + radeon_error("%s(%p, tex %p) Failed to validate miptree for " + "sw fallback.\n", + __func__, ctx, texObj); + return; + } + + if (t->image_override && t->bo) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p) Work around for missing miptree in r100.\n", + __func__, ctx, texObj); - /* for r100 3D sw fallbacks don't have mt */ - if (t->image_override && t->bo) map_override(ctx, t); + } - if (!t->mt) + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) { + radeon_warning("%s(%p, tex %p) No miptree in texture.\n", + __func__, ctx, texObj); return; + } radeon_bo_map(t->mt->bo, GL_FALSE); for(face = 0; face < t->mt->faces; ++face) { @@ -184,6 +212,10 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeonTexObj* t = radeon_tex_obj(texObj); int face, level; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p)\n", + __func__, ctx, texObj); + if (t->image_override && t->bo) unmap_override(ctx, t); /* for r100 3D sw fallbacks don't have mt */ @@ -197,21 +229,6 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeon_bo_unmap(t->mt->bo); } -GLuint radeon_face_for_target(GLenum target) -{ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - default: - return 0; - } -} - /** * Wraps Mesa's implementation to ensure that the base level image is mapped. * @@ -225,6 +242,10 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; int i, face; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p) Target type %s.\n", + __func__, ctx, texObj, + _mesa_lookup_enum_by_nr(target)); _mesa_generate_mipmap(ctx, target, texObj); @@ -248,8 +269,19 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) { - GLuint face = radeon_face_for_target(target); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_bo *bo; + GLuint face = _mesa_tex_target_to_face(target); radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); + bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo; + + if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p, tex %p) Trying to generate mipmap for texture " + "in processing by GPU.\n", + __func__, ctx, texObj); + radeon_firevertices(rmesa); + } radeon_teximage_map(baseimage, GL_FALSE); radeon_generate_mipmap(ctx, target, texObj); @@ -312,12 +344,14 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); (void)format; -#if 0 - fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s InternalFormat=%s(%d) type=%s format=%s\n", + __func__, _mesa_lookup_enum_by_nr(internalFormat), internalFormat, _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); - fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); -#endif + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s do32bpt=%d force16bpt=%d\n", + __func__, do32bpt, force16bpt); switch (internalFormat) { case 4: @@ -566,11 +600,10 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: texObj %p, texImage %p, face %d, level %d, " "texObj miptree doesn't match, allocated new miptree %p\n", __FUNCTION__, texObj, texImage, face, level, t->mt); - } } /* Miptree alocation may have failed, @@ -579,7 +612,9 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, image->mtface = face; image->mtlevel = level; radeon_miptree_reference(t->mt, &image->mt); - } + } else + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Failed to allocate miptree.\n", __func__); } static GLuint * allocate_image_offsets(GLcontext *ctx, @@ -623,6 +658,10 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, GLuint dstRowStride; GLuint *dstImageOffsets; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, tex %p, image %p) compressed %d\n", + __func__, ctx, texObj, texImage, compressed); + if (image->mt) { dstRowStride = image->mt->levels[image->mtlevel].rowstride; } else if (t->bo) { @@ -639,6 +678,7 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); if (!dstImageOffsets) { + radeon_warning("%s Failed to allocate dstImaeOffset.\n", __func__); return; } } else { @@ -710,20 +750,23 @@ static void radeon_teximage( radeon_texture_image* image = get_radeon_texture_image(texImage); GLint postConvWidth = width; GLint postConvHeight = height; - GLuint face = radeon_face_for_target(target); + GLuint face = _mesa_tex_target_to_face(target); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s %dd: texObj %p, texImage %p, face %d, level %d\n", + __func__, dims, texObj, texImage, face, level); { struct radeon_bo *bo; bo = !image->mt ? image->bo : image->mt->bo; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Calling teximage for texture that is " + "queued for GPU processing.\n", + __func__); radeon_firevertices(rmesa); } } - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", - dims, texObj, texImage, face, level); - } t->validated = GL_FALSE; @@ -755,11 +798,10 @@ static void radeon_teximage( texImage->Height, texImage->Depth); texImage->Data = _mesa_alloc_texmemory(size); - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s %dd: texObj %p, texImage %p, " " no miptree assigned, using local memory %p\n", - dims, texObj, texImage, texImage->Data); - } + __func__, dims, texObj, texImage, texImage->Data); } } @@ -853,18 +895,22 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s %dd: texObj %p, texImage %p, face %d, level %d\n", + __func__, dims, texObj, texImage, + _mesa_tex_target_to_face(target), level); { struct radeon_bo *bo; bo = !image->mt ? image->bo : image->mt->bo; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Calling texsubimage for texture that is " + "queued for GPU processing.\n", + __func__); radeon_firevertices(rmesa); } } - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", - dims, texObj, texImage, radeon_face_for_target(target), level); - } t->validated = GL_FALSE; if (compressed) { @@ -953,6 +999,10 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, { radeon_texture_image *image = get_radeon_texture_image(texImage); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p, tex %p, image %p) compressed %d.\n", + __func__, ctx, texObj, image, compressed); + if (image->mt) { /* Map the texture image read-only */ radeon_teximage_map(image, GL_FALSE); diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h index 906daf12d0..f09dd65214 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.h +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -44,7 +44,6 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); -GLuint radeon_face_for_target(GLenum target); gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx, GLint internalFormat, @@ -126,4 +125,14 @@ void radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +void radeonCopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + +void radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); + #endif diff --git a/src/mesa/drivers/dri/radeon/server/radeon_egl.c b/src/mesa/drivers/dri/radeon/server/radeon_egl.c deleted file mode 100644 index c16d66e4ec..0000000000 --- a/src/mesa/drivers/dri/radeon/server/radeon_egl.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * EGL driver for radeon_dri.so - */ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "egllog.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" -#include "egldri.h" - -#include "mtypes.h" -#include "memops.h" -#include "drm.h" -#include "drm_sarea.h" -#include "radeon_drm.h" -#include "radeon_dri.h" -#include "radeon.h" - -static size_t radeon_drm_page_size; - -/** - * radeon driver-specific driver class derived from _EGLDriver - */ -typedef struct radeon_driver -{ - _EGLDriver Base; /* base class/object */ - GLuint radeonStuff; -} radeonDriver; - -static int -RADEONSetParam(driDisplay *disp, int param, int value) -{ - drm_radeon_setparam_t sp; - int ret; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if ((ret=drmCommandWrite(disp->drmFD, DRM_RADEON_SETPARAM, &sp, sizeof(sp)))) { - fprintf(stderr,"Set param failed\n", ret); - return -1; - } - - return 0; -} - -static int -RADEONCheckDRMVersion(driDisplay *disp, RADEONInfoPtr info) -{ - drmVersionPtr version; - - version = drmGetVersion(disp->drmFD); - if (version) { - int req_minor, req_patch; - - /* Need 1.21.x for card type detection getparam - */ - req_minor = 21; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] RADEONDRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] radeon.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - info->drmMinor = version->version_minor; - drmFreeVersion(version); - } - - return 1; -} - - -/** - * \brief Compute base 2 logarithm. - * - * \param val value. - * - * \return base 2 logarithm of \p val. - */ -static int RADEONMinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - - -/* Initialize the PCI GART state. Request memory for use in PCI space, - * and initialize the Radeon registers to point to that memory. - */ -static int RADEONDRIPciInit(driDisplay *disp, RADEONInfoPtr info) -{ - int ret; - int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; - int s, l; - - ret = drmScatterGatherAlloc(disp->drmFD, info->gartSize*1024*1024, - &info->gartMemHandle); - if (ret < 0) { - fprintf(stderr, "[pci] Out of memory (%d)\n", ret); - return 0; - } - fprintf(stderr, - "[pci] %d kB allocated with handle 0x%04lx\n", - info->gartSize*1024, (long) info->gartMemHandle); - - info->gartOffset = 0; - - /* Initialize the CP ring buffer data */ - info->ringStart = info->gartOffset; - info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->gartTexStart = info->bufStart + info->bufMapSize; - s = (info->gartSize*1024*1024 - info->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->gartTexMapSize = (s >> l) << l; - info->log2GARTTexGran = l; - - if (drmAddMap(disp->drmFD, info->ringStart, info->ringMapSize, - DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] ring handle = 0x%08lx\n", info->ringHandle); - - if (drmAddMap(disp->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring read ptr mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(disp->drmFD, info->bufStart, info->bufMapSize, - DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[pci] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmAddMap(disp->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[pci] Could not add GART texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] GART texture map handle = 0x%08lx\n", - info->gartTexHandle); - - return 1; -} - - -/** - * \brief Initialize the AGP state - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Acquires and enables the AGP device. Reserves memory in the AGP space for - * the ring buffer, vertex buffers and textures. Initialize the Radeon - * registers to point to that memory and add client mappings. - */ -static int RADEONDRIAgpInit( driDisplay *disp, RADEONInfoPtr info) -{ - int mode, ret; - int s, l; - int agpmode = 1; - - if (drmAgpAcquire(disp->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - mode = drmAgpGetMode(disp->drmFD); /* Default mode */ - /* Disable fast write entirely - too many lockups. - */ - mode &= ~RADEON_AGP_MODE_MASK; - switch (agpmode) { - case 4: mode |= RADEON_AGP_4X_MODE; - case 2: mode |= RADEON_AGP_2X_MODE; - case 1: default: mode |= RADEON_AGP_1X_MODE; - } - - if (drmAgpEnable(disp->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(disp->drmFD); - return 0; - } - -#if 0 - /* Workaround for some hardware bugs */ - if (info->ChipFamily < CHIP_FAMILY_R200) - OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000); -#endif - info->gartOffset = 0; - - if ((ret = drmAgpAlloc(disp->drmFD, info->gartSize*1024*1024, 0, NULL, - &info->gartMemHandle)) < 0) { - fprintf(stderr, "[gart] Out of memory (%d)\n", ret); - drmAgpRelease(disp->drmFD); - return 0; - } - fprintf(stderr, - "[gart] %d kB allocated with handle 0x%08x\n", - info->gartSize*1024, (unsigned)info->gartMemHandle); - - if (drmAgpBind(disp->drmFD, - info->gartMemHandle, info->gartOffset) < 0) { - fprintf(stderr, "[gart] Could not bind\n"); - drmAgpFree(disp->drmFD, info->gartMemHandle); - drmAgpRelease(disp->drmFD); - return 0; - } - - /* Initialize the CP ring buffer data */ - info->ringStart = info->gartOffset; - info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->gartTexStart = info->bufStart + info->bufMapSize; - s = (info->gartSize*1024*1024 - info->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->gartTexMapSize = (s >> l) << l; - info->log2GARTTexGran = l; - - if (drmAddMap(disp->drmFD, info->ringStart, info->ringMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) { - fprintf(stderr, "[gart] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, "[gart] ring handle = 0x%08lx\n", info->ringHandle); - - - if (drmAddMap(disp->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[gart] Could not add ring read ptr mapping\n"); - return 0; - } - - fprintf(stderr, - "[gart] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(disp->drmFD, info->bufStart, info->bufMapSize, - DRM_AGP, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[gart] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmAddMap(disp->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_AGP, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[gart] Could not add AGP texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] AGP texture map handle = 0x%08lx\n", - info->gartTexHandle); - - return 1; -} - - -/** - * Initialize all the memory-related fields of the RADEONInfo object. - * This includes the various 'offset' and 'size' fields. - */ -static int -RADEONMemoryInit(driDisplay *disp, RADEONInfoPtr info) -{ - int width_bytes = disp->virtualWidth * disp->cpp; - int cpp = disp->cpp; - int bufferSize = ((disp->virtualHeight * width_bytes - + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - int depthSize = ((((disp->virtualHeight+15) & ~15) * width_bytes - + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - int l; - int pcie_gart_table_size = 0; - - info->frontOffset = 0; - info->frontPitch = disp->virtualWidth; - - if (disp->card_type==RADEON_CARD_PCIE) - pcie_gart_table_size = RADEON_PCIGART_TABLE_SIZE; - - /* Front, back and depth buffers - everything else texture?? - */ - info->textureSize = disp->fbSize - pcie_gart_table_size - 2 * bufferSize - depthSize; - - if (info->textureSize < 0) - return 0; - - l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - /* Reserve space for textures */ - info->textureOffset = ((disp->fbSize - pcie_gart_table_size - info->textureSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - - /* Reserve space for the shared depth - * buffer. - */ - info->depthOffset = ((info->textureOffset - depthSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - info->depthPitch = disp->virtualWidth; - - info->backOffset = ((info->depthOffset - bufferSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - info->backPitch = disp->virtualWidth; - - if (pcie_gart_table_size) - info->pcieGartTableOffset = disp->fbSize - pcie_gart_table_size; - - fprintf(stderr, - "Will use back buffer at offset 0x%x, pitch %d\n", - info->backOffset, info->backPitch); - fprintf(stderr, - "Will use depth buffer at offset 0x%x, pitch %d\n", - info->depthOffset, info->depthPitch); - fprintf(stderr, - "Will use %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - if (pcie_gart_table_size) - { - fprintf(stderr, - "Will use %d kb for PCIE GART Table at offset 0x%x\n", - pcie_gart_table_size/1024, info->pcieGartTableOffset); - } - - /* XXX I don't think these are needed. */ -#if 0 - info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | - (info->frontOffset >> 10)); - - info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | - (info->backOffset >> 10)); - - info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | - (info->depthOffset >> 10)); -#endif - - if (pcie_gart_table_size) - RADEONSetParam(disp, RADEON_SETPARAM_PCIGART_LOCATION, info->pcieGartTableOffset); - - return 1; -} - - -/** - * \brief Initialize the kernel data structures and enable the CP engine. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing - * all the parameters in a drm_radeon_init_t structure. - */ -static int RADEONDRIKernelInit( driDisplay *disp, - RADEONInfoPtr info) -{ - int cpp = disp->bpp / 8; - drm_radeon_init_t drmInfo; - int ret; - - memset(&drmInfo, 0, sizeof(drmInfo)); - - if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) - drmInfo.func = RADEON_INIT_R300_CP; - else if ( (info->ChipFamily == CHIP_FAMILY_R200) || - (info->ChipFamily == CHIP_FAMILY_RV250) || - (info->ChipFamily == CHIP_FAMILY_M9) || - (info->ChipFamily == CHIP_FAMILY_RV280) ) - drmInfo.func = RADEON_INIT_R200_CP; - else - drmInfo.func = RADEON_INIT_CP; - - /* This is the struct passed to the kernel module for its initialization */ - /* XXX problem here: - * The front/back/depth_offset/pitch fields may change depending upon - * which drawing surface we're using!!! They can't be set just once - * during initialization. - * Looks like we'll need a new ioctl to update these fields for drawing - * to other surfaces... - */ - drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); - drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE; - drmInfo.gart_size = info->gartSize*1024*1024; - drmInfo.ring_size = info->ringSize*1024*1024; - drmInfo.usec_timeout = 1000; - drmInfo.fb_bpp = disp->bpp; - drmInfo.depth_bpp = disp->bpp; - drmInfo.front_offset = info->frontOffset; - drmInfo.front_pitch = info->frontPitch * cpp; - drmInfo.back_offset = info->backOffset; - drmInfo.back_pitch = info->backPitch * cpp; - drmInfo.depth_offset = info->depthOffset; - drmInfo.depth_pitch = info->depthPitch * cpp; - drmInfo.ring_offset = info->ringHandle; - drmInfo.ring_rptr_offset = info->ringReadPtrHandle; - drmInfo.buffers_offset = info->bufHandle; - drmInfo.gart_textures_offset = info->gartTexHandle; - - ret = drmCommandWrite(disp->drmFD, DRM_RADEON_CP_INIT, &drmInfo, - sizeof(drm_radeon_init_t)); - - return ret >= 0; -} - - -/** - * \brief Add a map for the vertex buffers that will be accessed by any - * DRI-based clients. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Calls drmAddBufs() with the previously allocated vertex buffers. - */ -static int RADEONDRIBufInit( driDisplay *disp, RADEONInfoPtr info ) -{ - /* Initialize vertex buffers */ - info->bufNumBufs = drmAddBufs(disp->drmFD, - info->bufMapSize / RADEON_BUFFER_SIZE, - RADEON_BUFFER_SIZE, - (disp->card_type!=RADEON_CARD_AGP) ? DRM_SG_BUFFER : DRM_AGP_BUFFER, - info->bufStart); - - if (info->bufNumBufs <= 0) { - fprintf(stderr, - "[drm] Could not create vertex/indirect buffers list\n"); - return 0; - } - fprintf(stderr, - "[drm] Added %d %d byte vertex/indirect buffers\n", - info->bufNumBufs, RADEON_BUFFER_SIZE); - - return 1; -} - - -/** - * \brief Install an IRQ handler. - * - * \param disp display handle. - * \param info driver private data. - * - * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to - * IRQ-free operation on failure. - */ -static void RADEONDRIIrqInit(driDisplay *disp, RADEONInfoPtr info) -{ - if ((drmCtlInstHandler(disp->drmFD, 0)) != 0) - fprintf(stderr, "[drm] failure adding irq handler, " - "there is a device already using that irq\n" - "[drm] falling back to irq-free operation\n"); -} - - -/** - * \brief Initialize the AGP heap. - * - * \param disp display handle. - * \param info driver private data. - * - * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing - * all the parameters in a drm_radeon_mem_init_heap structure. - */ -static void RADEONDRIAgpHeapInit(driDisplay *disp, - RADEONInfoPtr info) -{ - drm_radeon_mem_init_heap_t drmHeap; - - /* Start up the simple memory manager for gart space */ - drmHeap.region = RADEON_MEM_REGION_GART; - drmHeap.start = 0; - drmHeap.size = info->gartTexMapSize; - - if (drmCommandWrite(disp->drmFD, DRM_RADEON_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - fprintf(stderr, - "[drm] Failed to initialized gart heap manager\n"); - } else { - fprintf(stderr, - "[drm] Initialized kernel gart heap manager, %d\n", - info->gartTexMapSize); - } -} - -static int RADEONGetCardType(driDisplay *disp, RADEONInfoPtr info) -{ - drm_radeon_getparam_t gp; - int ret; - - gp.param = RADEON_PARAM_CARD_TYPE; - gp.value = &disp->card_type; - - ret=drmCommandWriteRead(disp->drmFD, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_CARD_TYPE) : %d\n", ret); - return -1; - } - - return disp->card_type; -} - -/** - * Called at the start of each server generation. - * - * \param disp display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Performs static frame buffer allocation. Opens the DRM device and add maps - * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more - * information. Creates a \e server context to grab the lock for the - * initialization ioctls and calls the other initilization functions in this - * file. Starts the CP engine via the DRM_RADEON_CP_START command. - * - * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its - * initialization. - */ -static int -RADEONScreenInit( driDisplay *disp, RADEONInfoPtr info, - RADEONDRIPtr pRADEONDRI) -{ - int i, err; - - /* XXX this probably isn't needed here */ - { - int width_bytes = (disp->virtualWidth * disp->cpp); - int maxy = disp->fbSize / width_bytes; - - if (maxy <= disp->virtualHeight * 3) { - _eglLog(_EGL_WARNING, - "Static buffer allocation failed -- " - "need at least %d kB video memory (have %d kB)\n", - (disp->virtualWidth * disp->virtualHeight * - disp->cpp * 3 + 1023) / 1024, - disp->fbSize / 1024); - return 0; - } - } - - /* Memory manager setup */ - if (!RADEONMemoryInit(disp, info)) { - return 0; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(disp->drmFD, &disp->serverContext)) != 0) { - _eglLog(_EGL_WARNING, "%s: drmCreateContext failed %d\n", - __FUNCTION__, err); - return 0; - } - - DRM_LOCK(disp->drmFD, disp->pSAREA, disp->serverContext, 0); - - /* Initialize the kernel data structures */ - if (!RADEONDRIKernelInit(disp, info)) { - _eglLog(_EGL_WARNING, "RADEONDRIKernelInit failed\n"); - DRM_UNLOCK(disp->drmFD, disp->pSAREA, disp->serverContext); - return 0; - } - - /* Initialize the vertex buffers list */ - if (!RADEONDRIBufInit(disp, info)) { - fprintf(stderr, "RADEONDRIBufInit failed\n"); - DRM_UNLOCK(disp->drmFD, disp->pSAREA, disp->serverContext); - return 0; - } - - /* Initialize IRQ */ - RADEONDRIIrqInit(disp, info); - - /* Initialize kernel gart memory manager */ - RADEONDRIAgpHeapInit(disp, info); - - /* Initialize the SAREA private data structure */ - { - drm_radeon_sarea_t *pSAREAPriv; - pSAREAPriv = (drm_radeon_sarea_t *)(((char*)disp->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - pSAREAPriv->pfState = info->page_flip_enable; - } - - for ( i = 0;; i++ ) { - drmMapType type; - drmMapFlags flags; - drm_handle_t handle, offset; - drmSize size; - int rc, mtrr; - - if ( ( rc = drmGetMap( disp->drmFD, i, &offset, &size, &type, &flags, &handle, &mtrr ) ) != 0 ) - break; - if ( type == DRM_REGISTERS ) { - pRADEONDRI->registerHandle = offset; - pRADEONDRI->registerSize = size; - break; - } - } - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - drimemsetio((char *)disp->pFB + info->frontOffset, - 0xEE, - info->frontPitch * disp->cpp * disp->virtualHeight ); - - drimemsetio((char *)disp->pFB + info->backOffset, - 0x30, - info->backPitch * disp->cpp * disp->virtualHeight ); - - - /* This is the struct passed to radeon_dri.so for its initialization */ - pRADEONDRI->deviceID = info->Chipset; - pRADEONDRI->width = disp->virtualWidth; - pRADEONDRI->height = disp->virtualHeight; - pRADEONDRI->depth = disp->bpp; /* XXX: depth */ - pRADEONDRI->bpp = disp->bpp; - pRADEONDRI->IsPCI = (disp->card_type != RADEON_CARD_AGP);; - pRADEONDRI->frontOffset = info->frontOffset; - pRADEONDRI->frontPitch = info->frontPitch; - pRADEONDRI->backOffset = info->backOffset; - pRADEONDRI->backPitch = info->backPitch; - pRADEONDRI->depthOffset = info->depthOffset; - pRADEONDRI->depthPitch = info->depthPitch; - pRADEONDRI->textureOffset = info->textureOffset; - pRADEONDRI->textureSize = info->textureSize; - pRADEONDRI->log2TexGran = info->log2TexGran; - pRADEONDRI->statusHandle = info->ringReadPtrHandle; - pRADEONDRI->statusSize = info->ringReadMapSize; - pRADEONDRI->gartTexHandle = info->gartTexHandle; - pRADEONDRI->gartTexMapSize = info->gartTexMapSize; - pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran; - pRADEONDRI->gartTexOffset = info->gartTexStart; - pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t); - - /* Don't release the lock now - let the VT switch handler do it. */ - - return 1; -} - - -/** - * \brief Get Radeon chip family from chipset number. - * - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily - * according to the value of RADEONInfoRec::Chipset. Fails if the - * chipset is unrecognized or not appropriate for this driver (i.e., not - * an r100 style radeon) - */ -static int get_chipfamily_from_chipset( RADEONInfoPtr info ) -{ - switch (info->Chipset) { - case PCI_CHIP_RADEON_LY: - case PCI_CHIP_RADEON_LZ: - info->ChipFamily = CHIP_FAMILY_M6; - break; - - case PCI_CHIP_RADEON_QY: - case PCI_CHIP_RADEON_QZ: - info->ChipFamily = CHIP_FAMILY_VE; - break; - - case PCI_CHIP_R200_QL: - case PCI_CHIP_R200_QN: - case PCI_CHIP_R200_QO: - case PCI_CHIP_R200_Ql: - case PCI_CHIP_R200_BB: - info->ChipFamily = CHIP_FAMILY_R200; - break; - - case PCI_CHIP_RV200_QW: /* RV200 desktop */ - case PCI_CHIP_RV200_QX: - info->ChipFamily = CHIP_FAMILY_RV200; - break; - - case PCI_CHIP_RADEON_LW: - case PCI_CHIP_RADEON_LX: - info->ChipFamily = CHIP_FAMILY_M7; - break; - - case PCI_CHIP_RV250_Id: - case PCI_CHIP_RV250_Ie: - case PCI_CHIP_RV250_If: - case PCI_CHIP_RV250_Ig: - info->ChipFamily = CHIP_FAMILY_RV250; - break; - - case PCI_CHIP_RV250_Ld: - case PCI_CHIP_RV250_Le: - case PCI_CHIP_RV250_Lf: - case PCI_CHIP_RV250_Lg: - info->ChipFamily = CHIP_FAMILY_M9; - break; - - case PCI_CHIP_RV280_Y_: - case PCI_CHIP_RV280_Ya: - case PCI_CHIP_RV280_Yb: - case PCI_CHIP_RV280_Yc: - info->ChipFamily = CHIP_FAMILY_RV280; - break; - - case PCI_CHIP_R300_ND: - case PCI_CHIP_R300_NE: - case PCI_CHIP_R300_NF: - case PCI_CHIP_R300_NG: - info->ChipFamily = CHIP_FAMILY_R300; - break; - - case PCI_CHIP_RV370_5460: - info->ChipFamily = CHIP_FAMILY_RV380; - break; - - default: - /* Original Radeon/7200 */ - info->ChipFamily = CHIP_FAMILY_RADEON; - } - - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param disp display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p disp - * and then calls RADEONScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int radeonInitFBDev( driDisplay *disp, RADEONDRIPtr pRADEONDRI ) -{ - int err; - RADEONInfoPtr info = calloc(1, sizeof(*info)); - - disp->driverPrivate = (void *)info; - - info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE; - info->gartSize = RADEON_DEFAULT_AGP_SIZE; - info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; - info->bufSize = RADEON_DEFAULT_BUFFER_SIZE; - info->ringSize = RADEON_DEFAULT_RING_SIZE; - info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP; - - fprintf(stderr, - "Using %d MB AGP aperture\n", info->gartSize); - fprintf(stderr, - "Using %d MB for the ring buffer\n", info->ringSize); - fprintf(stderr, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - fprintf(stderr, - "Using %d MB for AGP textures\n", info->gartTexSize); - fprintf(stderr, - "page flipping %sabled\n", info->page_flip_enable?"en":"dis"); - - info->Chipset = disp->chipset; - - if (!get_chipfamily_from_chipset( info )) { - fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n"); - fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n"); - return 0; - } -#if 0 - if (info->ChipFamily >= CHIP_FAMILY_R300) { - fprintf(stderr, - "Direct rendering not yet supported on " - "Radeon 9700 and newer cards\n"); - return 0; - } -#endif - -#if 00 - /* don't seem to need this here */ - info->frontPitch = disp->virtualWidth; -#endif - - /* Check the radeon DRM version */ - if (!RADEONCheckDRMVersion(disp, info)) { - return 0; - } - - if (RADEONGetCardType(disp, info)<0) - return 0; - - if (disp->card_type!=RADEON_CARD_AGP) { - /* Initialize PCI */ - if (!RADEONDRIPciInit(disp, info)) - return 0; - } - else { - /* Initialize AGP */ - if (!RADEONDRIAgpInit(disp, info)) - return 0; - } - - if (!RADEONScreenInit( disp, info, pRADEONDRI)) - return 0; - - /* Initialize and start the CP if required */ - if ((err = drmCommandNone(disp->drmFD, DRM_RADEON_CP_START)) != 0) { - fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err); - return 0; - } - - return 1; -} - - -/** - * Create list of all supported surface configs, attach list to the display. - */ -static EGLBoolean -radeonFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, - unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - _EGLConfig *configs; - _EGLConfig *c; - unsigned int i, num_configs; - unsigned int depth_buffer_factor; - unsigned int back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy - * enough to add support. Basically, if a context is created with an - * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping - * will never be used. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ - }; - - uint8_t depth_bits_array[2]; - uint8_t stencil_bits_array[2]; - - depth_bits_array[0] = depth_bits; - depth_bits_array[1] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; - back_buffer_factor = (have_back_buffer) ? 2 : 1; - - num_configs = depth_buffer_factor * back_buffer_factor * 2; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } else { - fb_format = GL_RGBA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = calloc(sizeof(*configs), num_configs); - c = configs; - if (!_eglFillInConfigs(c, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return EGL_FALSE; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (i = 0, c = configs; i < num_configs; i++, c++) { - int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); - if ((stencil != 0) && (stencil != stencil_bits)) { - SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); - } - } - - for (i = 0, c = configs; i < num_configs; i++, c++) - _eglAddConfig(disp, c); - - free(configs); - - return EGL_TRUE; -} - - -/** - * Show the given surface on the named screen. - * If surface is EGL_NO_SURFACE, disable the screen's output. - */ -static EGLBoolean -radeonShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - EGLBoolean b = _eglDRIShowScreenSurfaceMESA(drv, dpy, screen, surface, m); - return b; -} - - -/** - * Called via eglInitialize() by user. - */ -static EGLBoolean -radeonInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - __DRIframebuffer framebuffer; - driDisplay *display; - - /* one-time init */ - radeon_drm_page_size = getpagesize(); - - if (!_eglDRIInitialize(drv, dpy, major, minor)) - return EGL_FALSE; - - display = Lookup_driDisplay(dpy); - - framebuffer.dev_priv_size = sizeof(RADEONDRIRec); - framebuffer.dev_priv = malloc(sizeof(RADEONDRIRec)); - - /* XXX we shouldn't hard-code values here! */ - /* we won't know the screen surface size until the user calls - * eglCreateScreenSurfaceMESA(). - */ -#if 0 - display->virtualWidth = 1024; - display->virtualHeight = 768; -#else - display->virtualWidth = 1280; - display->virtualHeight = 1024; -#endif - display->bpp = 32; - display->cpp = 4; - - if (!_eglDRIGetDisplayInfo(display)) - return EGL_FALSE; - - framebuffer.base = display->pFB; - framebuffer.width = display->virtualWidth; - framebuffer.height = display->virtualHeight; - framebuffer.stride = display->virtualWidth; - framebuffer.size = display->fbSize; - radeonInitFBDev( display, framebuffer.dev_priv ); - - if (!_eglDRICreateDisplay(display, &framebuffer)) - return EGL_FALSE; - - if (!_eglDRICreateScreens(display)) - return EGL_FALSE; - - /* create a variety of both 32 and 16-bit configurations */ - radeonFillInConfigs(&display->Base, 32, 24, 8, GL_TRUE); - radeonFillInConfigs(&display->Base, 16, 16, 0, GL_TRUE); - - drv->Initialized = EGL_TRUE; - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new radeonDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy) -{ - radeonDriver *radeon; - - radeon = (radeonDriver *) calloc(1, sizeof(*radeon)); - if (!radeon) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglDRIInitDriverFallbacks(&radeon->Base); - - /* then plug in our radeon-specific functions */ - radeon->Base.API.Initialize = radeonInitialize; - radeon->Base.API.ShowScreenSurfaceMESA = radeonShowScreenSurfaceMESA; - - return &radeon->Base; -} diff --git a/src/mesa/drivers/dri/radeon/server/radeon_reg.h b/src/mesa/drivers/dri/radeon/server/radeon_reg.h index e81d7fdcd0..1b33de1edf 100644 --- a/src/mesa/drivers/dri/radeon/server/radeon_reg.h +++ b/src/mesa/drivers/dri/radeon/server/radeon_reg.h @@ -1959,7 +1959,30 @@ #define RADEON_SE_ZBIAS_FACTOR 0x1db0 #define RADEON_SE_ZBIAS_CONSTANT 0x1db4 - +#define RADEON_SE_VTX_FMT 0x2080 +# define RADEON_SE_VTX_FMT_XY 0x00000000 +# define RADEON_SE_VTX_FMT_W0 0x00000001 +# define RADEON_SE_VTX_FMT_FPCOLOR 0x00000002 +# define RADEON_SE_VTX_FMT_FPALPHA 0x00000004 +# define RADEON_SE_VTX_FMT_PKCOLOR 0x00000008 +# define RADEON_SE_VTX_FMT_FPSPEC 0x00000010 +# define RADEON_SE_VTX_FMT_FPFOG 0x00000020 +# define RADEON_SE_VTX_FMT_PKSPEC 0x00000040 +# define RADEON_SE_VTX_FMT_ST0 0x00000080 +# define RADEON_SE_VTX_FMT_ST1 0x00000100 +# define RADEON_SE_VTX_FMT_Q1 0x00000200 +# define RADEON_SE_VTX_FMT_ST2 0x00000400 +# define RADEON_SE_VTX_FMT_Q2 0x00000800 +# define RADEON_SE_VTX_FMT_ST3 0x00001000 +# define RADEON_SE_VTX_FMT_Q3 0x00002000 +# define RADEON_SE_VTX_FMT_Q0 0x00004000 +# define RADEON_SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 +# define RADEON_SE_VTX_FMT_N0 0x00040000 +# define RADEON_SE_VTX_FMT_XY1 0x08000000 +# define RADEON_SE_VTX_FMT_Z1 0x10000000 +# define RADEON_SE_VTX_FMT_W1 0x20000000 +# define RADEON_SE_VTX_FMT_N1 0x40000000 +# define RADEON_SE_VTX_FMT_Z 0x80000000 /* Registers for CP and Microcode Engine */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 diff --git a/src/mesa/drivers/dri/savage/savagedd.c b/src/mesa/drivers/dri/savage/savagedd.c index 32ca86de8a..bbf49aec27 100644 --- a/src/mesa/drivers/dri/savage/savagedd.c +++ b/src/mesa/drivers/dri/savage/savagedd.c @@ -29,15 +29,11 @@ #include <stdio.h> #include "main/mm.h" -#include "swrast/swrast.h" #include "savagedd.h" #include "savagestate.h" -#include "savagespan.h" #include "savagetex.h" -#include "savagetris.h" #include "savagecontext.h" -#include "main/extensions.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index d0b64e801a..9e181ce3be 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -37,12 +37,10 @@ #include "savagecontext.h" #include "savageioctl.h" -#include "savage_bci.h" #include "savagestate.h" #include "savagespan.h" #include "drm.h" -#include <sys/ioctl.h> #include <sys/timeb.h> #define DEPTH_SCALE_16 ((1<<16)-1) diff --git a/src/mesa/drivers/dri/savage/savagerender.c b/src/mesa/drivers/dri/savage/savagerender.c index 8221edf387..c369bb124c 100644 --- a/src/mesa/drivers/dri/savage/savagerender.c +++ b/src/mesa/drivers/dri/savage/savagerender.c @@ -36,7 +36,6 @@ #include "tnl/t_context.h" #include "savagecontext.h" -#include "savagetris.h" #include "savagestate.h" #include "savageioctl.h" diff --git a/src/mesa/drivers/dri/savage/savagespan.c b/src/mesa/drivers/dri/savage/savagespan.c index 792e166d9c..0913dd1278 100644 --- a/src/mesa/drivers/dri/savage/savagespan.c +++ b/src/mesa/drivers/dri/savage/savagespan.c @@ -26,7 +26,6 @@ #include "savagedd.h" #include "savagespan.h" #include "savageioctl.h" -#include "savage_bci.h" #include "savage_3d_reg.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index 97598f599e..394be44eac 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -33,8 +33,6 @@ #include "main/simple_list.h" #include "main/enums.h" -#include "swrast/swrast.h" - #include "savagecontext.h" #include "savagetex.h" #include "savagetris.h" diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 9a92541ef7..a177a7d2b6 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -52,7 +52,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "savagestate.h" #include "savagetex.h" #include "savageioctl.h" -#include "savage_bci.h" static void savageRasterPrimitive( GLcontext *ctx, GLuint prim ); static void savageRenderPrimitive( GLcontext *ctx, GLenum prim ); diff --git a/src/mesa/drivers/dri/sis/sis6326_state.c b/src/mesa/drivers/dri/sis/sis6326_state.c index 65d4c06466..52008c7ea3 100644 --- a/src/mesa/drivers/dri/sis/sis6326_state.c +++ b/src/mesa/drivers/dri/sis/sis6326_state.c @@ -34,14 +34,12 @@ #include "sis_reg.h" #include "main/context.h" -#include "main/enums.h" #include "main/colormac.h" #include "swrast/swrast.h" #include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" /* ============================================================= * Alpha blending diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c index 0944f4d8b4..400681a04a 100644 --- a/src/mesa/drivers/dri/sis/sis_context.c +++ b/src/mesa/drivers/dri/sis/sis_context.c @@ -43,8 +43,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_alloc.h" #include "main/imports.h" -#include "main/matrix.h" -#include "main/extensions.h" #include "utils.h" #include "main/framebuffer.h" @@ -55,7 +53,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "vbo/vbo.h" #include "tnl/tnl.h" -#include "tnl/t_pipeline.h" #define need_GL_EXT_fog_coord #define need_GL_EXT_secondary_color diff --git a/src/mesa/drivers/dri/sis/sis_dd.c b/src/mesa/drivers/dri/sis/sis_dd.c index 217d77557f..fe4ade8592 100644 --- a/src/mesa/drivers/dri/sis/sis_dd.c +++ b/src/mesa/drivers/dri/sis/sis_dd.c @@ -40,9 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_state.h" #include "sis_tris.h" -#include "swrast/swrast.h" #include "main/formats.h" -#include "main/framebuffer.h" #include "main/renderbuffer.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/sis/sis_fog.c b/src/mesa/drivers/dri/sis/sis_fog.c index 517d5722e6..6c774e010e 100644 --- a/src/mesa/drivers/dri/sis/sis_fog.c +++ b/src/mesa/drivers/dri/sis/sis_fog.c @@ -33,7 +33,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_context.h" #include "sis_state.h" -#include "swrast/swrast.h" #include "main/macros.h" diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index d38b93ec9b..cb7ed8a08b 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -39,7 +39,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_context.h" #include "sis_dri.h" #include "sis_lock.h" -#include "sis_span.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c index 98e8d02fab..a22195ccce 100644 --- a/src/mesa/drivers/dri/sis/sis_state.c +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -35,17 +35,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_state.h" #include "sis_tris.h" #include "sis_lock.h" -#include "sis_tex.h" #include "main/context.h" -#include "main/enums.h" -#include "main/colormac.h" #include "swrast/swrast.h" #include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" /* ============================================================= * Alpha blending diff --git a/src/mesa/drivers/dri/sis/sis_tex.c b/src/mesa/drivers/dri/sis/sis_tex.c index 951c470dad..31709c3af6 100644 --- a/src/mesa/drivers/dri/sis/sis_tex.c +++ b/src/mesa/drivers/dri/sis/sis_tex.c @@ -31,7 +31,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "main/imports.h" #include "main/texstore.h" -#include "main/teximage.h" #include "main/texobj.h" #include "sis_context.h" diff --git a/src/mesa/drivers/dri/sis/sis_texstate.c b/src/mesa/drivers/dri/sis/sis_texstate.c index 4c22a10cf7..7b0eebd066 100644 --- a/src/mesa/drivers/dri/sis/sis_texstate.c +++ b/src/mesa/drivers/dri/sis/sis_texstate.c @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "sis_context.h" -#include "sis_state.h" #include "sis_tex.h" #include "sis_tris.h" #include "sis_alloc.h" diff --git a/src/mesa/drivers/dri/sis/sis_tris.c b/src/mesa/drivers/dri/sis/sis_tris.c index 4690274c3c..4b41d78d82 100644 --- a/src/mesa/drivers/dri/sis/sis_tris.c +++ b/src/mesa/drivers/dri/sis/sis_tris.c @@ -47,7 +47,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_state.h" #include "sis_lock.h" #include "sis_span.h" -#include "sis_alloc.h" #include "sis_tex.h" /* 6326 and 300-series shared */ diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index 8340861aff..4e823669bf 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -368,7 +368,7 @@ driCreateNewDrawable(__DRIscreen *screen, buf->row = _mesa_malloc(MAX_WIDTH * 4); /* basic framebuffer setup */ - _mesa_initialize_framebuffer(&buf->Base, &config->modes); + _mesa_initialize_window_framebuffer(&buf->Base, &config->modes); /* add front renderbuffer */ frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_dd.c b/src/mesa/drivers/dri/tdfx/tdfx_dd.c index ed8a331549..2cbbeb8114 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_dd.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_dd.c @@ -35,17 +35,10 @@ #include "tdfx_context.h" #include "tdfx_dd.h" #include "tdfx_lock.h" -#include "tdfx_vb.h" #include "tdfx_pixels.h" #include "utils.h" #include "main/context.h" -#include "main/enums.h" -#include "main/framebuffer.h" -#include "swrast/swrast.h" -#if defined(USE_X86_ASM) -#include "x86/common_x86_asm.h" -#endif #define DRIVER_DATE "20061113" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_lock.c b/src/mesa/drivers/dri/tdfx/tdfx_lock.c index 4f84240104..f218e4ee57 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_lock.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_lock.c @@ -38,7 +38,6 @@ #include "tdfx_state.h" #include "tdfx_render.h" #include "tdfx_texman.h" -#include "tdfx_tris.h" #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c index 65f0464f8a..4449627418 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c @@ -38,7 +38,6 @@ #include "tdfx_context.h" #include "tdfx_dd.h" #include "tdfx_lock.h" -#include "tdfx_vb.h" #include "tdfx_pixels.h" #include "tdfx_render.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 4422b5dec4..9f6b35faa2 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -36,9 +36,7 @@ #include "tdfx_dri.h" #include "tdfx_context.h" #include "tdfx_lock.h" -#include "tdfx_vb.h" #include "tdfx_span.h" -#include "tdfx_tris.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index cdb61a0ce0..dcbc7647f2 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -40,8 +40,6 @@ #include "main/mtypes.h" #include "main/colormac.h" -#include "main/texstore.h" -#include "main/teximage.h" #include "swrast/swrast.h" #include "vbo/vbo.h" @@ -51,11 +49,9 @@ #include "tdfx_context.h" #include "tdfx_state.h" -#include "tdfx_vb.h" #include "tdfx_tex.h" #include "tdfx_texman.h" #include "tdfx_texstate.h" -#include "tdfx_tris.h" #include "tdfx_render.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texman.c b/src/mesa/drivers/dri/tdfx/tdfx_texman.c index 35636ee5ef..726cc58a10 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_texman.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_texman.c @@ -35,7 +35,6 @@ */ #include "tdfx_context.h" -#include "tdfx_tex.h" #include "tdfx_texman.h" #include "main/texobj.h" #include "main/hash.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c index 3f737878ed..6658b4d0c3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c @@ -38,7 +38,6 @@ */ #include "tdfx_state.h" -#include "tdfx_tex.h" #include "tdfx_texman.h" #include "tdfx_texstate.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vb.c b/src/mesa/drivers/dri/tdfx/tdfx_vb.c index c200ba3255..0f3c877a3e 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_vb.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_vb.c @@ -29,13 +29,8 @@ #include "main/macros.h" #include "main/colormac.h" -#include "math/m_translate.h" -#include "swrast_setup/swrast_setup.h" - #include "tdfx_context.h" #include "tdfx_vb.h" -#include "tdfx_tris.h" -#include "tdfx_state.h" #include "tdfx_render.h" static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index d17a160271..9da96bdd45 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -33,10 +33,7 @@ #include "main/glheader.h" #include "main/context.h" #include "main/formats.h" -#include "main/matrix.h" -#include "main/state.h" #include "main/simple_list.h" -#include "main/extensions.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 8d4edfa305..c9a31f3383 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -34,7 +34,6 @@ #include "via_context.h" #include "via_tris.h" #include "via_ioctl.h" -#include "via_state.h" #include "via_fb.h" #include "via_3d_reg.h" diff --git a/src/mesa/drivers/dri/unichrome/via_render.c b/src/mesa/drivers/dri/unichrome/via_render.c index f676cc13c8..896c43db1b 100644 --- a/src/mesa/drivers/dri/unichrome/via_render.c +++ b/src/mesa/drivers/dri/unichrome/via_render.c @@ -37,7 +37,6 @@ #include "via_context.h" #include "via_tris.h" -#include "via_state.h" #include "via_ioctl.h" /* diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index 2cfb98317d..8c91c937c6 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -30,17 +30,13 @@ #include "main/context.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" -#include "main/matrix.h" #include "main/simple_list.h" #include "vblank.h" #include "via_state.h" #include "via_tex.h" #include "via_span.h" -#include "via_tris.h" -#include "via_ioctl.h" #include "via_screen.h" -#include "via_fb.h" #include "via_dri.h" #include "GL/internal/dri_interface.h" diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index e6e5526d34..f7029b9492 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -35,7 +35,6 @@ #include "via_context.h" #include "via_state.h" #include "via_tex.h" -#include "via_tris.h" #include "via_ioctl.h" #include "via_3d_reg.h" @@ -44,8 +43,6 @@ #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" - static GLuint ROP[16] = { HC_HROP_BLACK, /* GL_CLEAR 0 */ diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c index 24924d2613..917f975466 100644 --- a/src/mesa/drivers/dri/unichrome/via_tex.c +++ b/src/mesa/drivers/dri/unichrome/via_tex.c @@ -37,14 +37,12 @@ #include "main/mipmap.h" #include "main/mm.h" #include "main/simple_list.h" -#include "main/texcompress.h" #include "main/texobj.h" #include "main/texstore.h" #include "via_context.h" #include "via_fb.h" #include "via_tex.h" -#include "via_state.h" #include "via_ioctl.h" #include "via_3d_reg.h" diff --git a/src/mesa/drivers/dri/unichrome/via_texcombine.c b/src/mesa/drivers/dri/unichrome/via_texcombine.c index b646897848..f87ba071f3 100644 --- a/src/mesa/drivers/dri/unichrome/via_texcombine.c +++ b/src/mesa/drivers/dri/unichrome/via_texcombine.c @@ -38,7 +38,6 @@ #include "main/enums.h" #include "via_context.h" -#include "via_state.h" #include "via_tex.h" #include "via_3d_reg.h" |