diff options
author | Ben Skeggs <[email protected]> | 2008-07-14 01:14:52 +1000 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2008-07-14 01:14:52 +1000 |
commit | d68a3ebf0e7e853cf9680ddbb095fffe7c0fb1f9 (patch) | |
tree | e093bba7d7b0ff62e0a4f47bd622180e5cea1a22 /src | |
parent | 1d50e26f4afc0c7cdcd843a1336a90cdfc76765b (diff) | |
parent | 6410e94b966148dde81b5121e53a250d7b530d91 (diff) |
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src')
42 files changed, 2952 insertions, 202 deletions
diff --git a/src/egl/drivers/Makefile b/src/egl/drivers/Makefile index a2d67ca5a8a..6ce0e6b66d1 100644 --- a/src/egl/drivers/Makefile +++ b/src/egl/drivers/Makefile @@ -7,10 +7,10 @@ include $(TOP)/configs/current SUBDIRS = demo dri xdri -default: conditional_subdirs +default: dri_subdirs -# depending on $DRIVER_DIRS... +# (UNUSED) depending on $DRIVER_DIRS... conditional_subdirs: @if [ "${DRIVER_DIRS}" = "dri" ] ; then \ $(MAKE) dri_subdirs ; \ diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 5e50d6034ac..dfb491958b8 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -33,7 +33,7 @@ * to render into X-created windows. * * This is an EGL driver that, in turn, loads a regular DRI driver. - * There are some dependencies on code in libGL, but those coudl be + * There are some dependencies on code in libGL, but those could be * removed with some effort. * * Authors: Brian Paul @@ -77,11 +77,14 @@ struct xdri_egl_driver const char *dri_driver_name; /**< name of DRI driver to load */ void *dri_driver_handle; /**< returned by dlopen(dri_driver_name) */ + __GLXdisplayPrivate *glx_priv; + + + /* XXX we're not actually using these at this time: */ int chipset; int minor; int drmFD; - __DRIscreen driScreen; __DRIframebuffer framebuffer; drm_handle_t hSAREA; drmAddress pSAREA; @@ -118,9 +121,6 @@ struct xdri_egl_config }; -/* XXX temp hack */ -static struct xdri_egl_driver *TheDriver = NULL; - /** cast wrapper */ static struct xdri_egl_driver * @@ -179,11 +179,10 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) * This dependency on GLX lib will be removed someday. */ static void -create_configs(_EGLDisplay *disp) +create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) { + __GLXscreenConfigs *scrn = glx_priv->screenConfigs; const __GLcontextModes *m; - __GLXdisplayPrivate *priv = __glXInitialize(disp->Xdpy); - __GLXscreenConfigs *scrn = priv->screenConfigs; int id = 1; for (m = scrn->configs; m; m = m->next) { @@ -292,9 +291,9 @@ dri_context_modes_create(unsigned count, size_t minimum_size) static __DRIscreen * dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn) { - assert(TheDriver); - - return &TheDriver->driScreen; + __GLXdisplayPrivate *priv = __glXInitialize(ndpy); + __GLXscreenConfigs *scrnConf = priv->screenConfigs; + return &scrnConf->driScreen; } @@ -395,9 +394,6 @@ static const __DRIinterfaceMethods interface_methods = { static EGLBoolean init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) { - static const char createNewScreenName[] = "__driCreateNewScreen_20050727"; - PFNCREATENEWSCREENFUNC createNewScreen; - int api_ver = 0;/*__glXGetInternalVersion();*/ __DRIversion ddx_version; __DRIversion dri_version; __DRIversion drm_version; @@ -405,9 +401,9 @@ init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) drm_handle_t hFB; int newlyopened; int status; - __GLcontextModes *modes; int scrn = DefaultScreen(disp->Xdpy); +#if 0 createNewScreen = (PFNCREATENEWSCREENFUNC) dlsym(xdri_drv->dri_driver_handle, createNewScreenName); if (!createNewScreen) { @@ -418,6 +414,7 @@ init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) else { _eglLog(_EGL_DEBUG, "XDRI: Found %s", createNewScreenName); } +#endif /* * Get the DRI X extension version. @@ -426,7 +423,6 @@ init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) dri_version.minor = 0; dri_version.patch = 0; - if (!XF86DRIOpenConnection(disp->Xdpy, scrn, &xdri_drv->hSAREA, &xdri_drv->busID)) { _eglLog(_EGL_WARNING, "XF86DRIOpenConnection failed"); @@ -543,47 +539,19 @@ init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) _eglLog(_EGL_DEBUG, "XDRI: drmMap(sarea) success"); } - /* Create the DRI screen. - */ - xdri_drv->driScreen.private = createNewScreen(disp->Xdpy, - scrn, /* screen number */ - &xdri_drv->driScreen, - NULL, /* visuals */ - &ddx_version, - &dri_version, - &drm_version, - &xdri_drv->framebuffer, - xdri_drv->pSAREA, - xdri_drv->drmFD, - api_ver, - &interface_methods, - &modes); - if (!xdri_drv->driScreen.private) { - _eglLog(_EGL_WARNING, "XDRI: create new screen failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: create new screen success"); - } - - create_configs(disp); - - /* print modes / debug */ - if (0) { - __GLcontextModes *m; - - for (m = modes; m; m = m->next) { - _eglLog(_EGL_DEBUG, - "mode ID 0x%x rgba %d %d %d %d z %d s %d db %d\n", m->visualID, - m->redBits, m->greenBits, m->blueBits, m->alphaBits, - m->depthBits, m->stencilBits, m->doubleBufferMode); - } - } - return EGL_TRUE; } +/** + * Load the DRI driver named by "xdri_drv->dri_driver_name". + * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle". + * + * Later, we'll call dlsym(createNewScreenName) to get a pointer to + * the driver's createNewScreen() function which is the bootstrap function. + * + * \return EGL_TRUE for success, EGL_FALSE for failure + */ static EGLBoolean load_dri_driver(struct xdri_egl_driver *xdri_drv) { @@ -637,13 +605,30 @@ xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, } } +#if 0 /* choose the DRI driver to load */ xdri_drv->dri_driver_name = _eglChooseDRMDriver(0); if (!load_dri_driver(xdri_drv)) return EGL_FALSE; +#else + (void) load_dri_driver; +#endif +#if 0 if (!init_drm(xdri_drv, disp)) return EGL_FALSE; +#else + (void) init_drm; +#endif + + /* + * NOTE: this call to __glXInitialize() bootstraps the whole GLX/DRI + * interface, loads the DRI driver, etc. + * This replaces the load_dri_driver() and init_drm() code above. + */ + xdri_drv->glx_priv = __glXInitialize(disp->Xdpy); + + create_configs(disp, xdri_drv->glx_priv); xdri_drv->Base.Initialized = EGL_TRUE; @@ -678,6 +663,9 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) } +/* + * Called from eglGetProcAddress() via drv->API.GetProcAddress(). + */ static _EGLProc xdri_eglGetProcAddress(const char *procname) { @@ -688,8 +676,17 @@ xdri_eglGetProcAddress(const char *procname) /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/ _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname); return proc; -#elif 0 - return (_EGLProc) st_get_proc_address(procname); +#elif 1 + /* This is a bit of a hack to get at the gallium/Mesa state tracker + * function st_get_proc_address(). This will probably change at + * some point. + */ + _EGLProc (*st_get_proc_addr)(const char *procname); + st_get_proc_addr = dlsym(NULL, "st_get_proc_address"); + if (st_get_proc_addr) { + return st_get_proc_addr(procname); + } + return NULL; #else return NULL; #endif @@ -703,7 +700,6 @@ static EGLContext xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) { - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); void *shared = NULL; @@ -720,10 +716,15 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, assert(xdri_config); - xdri_ctx->driContext.private = - xdri_drv->driScreen.createNewContext(disp->Xdpy, - xdri_config->mode, renderType, - shared, &xdri_ctx->driContext); + { + struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); + __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; + xdri_ctx->driContext.private = + scrnConf->driScreen.createNewContext(disp->Xdpy, + xdri_config->mode, renderType, + shared, &xdri_ctx->driContext); + } + if (!xdri_ctx->driContext.private) { _eglLog(_EGL_DEBUG, "driScreen.createNewContext failed"); free(xdri_ctx); @@ -846,7 +847,8 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { struct xdri_egl_surface *xdri_surf = lookup_surface(draw); struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - __DRIscreen *psc = &xdri_drv->driScreen; + __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; + __DRIscreen *psc = &scrnConf->driScreen; __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy, xdri_surf->driDrawable, psc->private); @@ -872,8 +874,8 @@ _eglMain(_EGLDisplay *disp, const char *args) if (!xdri_drv) return NULL; - /* XXX temp hack */ - TheDriver = xdri_drv; + /* Tell libGL to prefer the EGL drivers over regular DRI drivers */ + __glXPreferEGL(1); _eglInitDriverFallbacks(&xdri_drv->Base); xdri_drv->Base.API.Initialize = xdri_eglInitialize; @@ -887,7 +889,10 @@ _eglMain(_EGLDisplay *disp, const char *args) xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface; xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers; - xdri_drv->Base.ClientAPIsMask = EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT; + xdri_drv->Base.ClientAPIsMask = (EGL_OPENGL_BIT | + EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENVG_BIT); xdri_drv->Base.Name = "X/DRI"; _eglLog(_EGL_DEBUG, "XDRI: main(%s)", args); diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 2653f91bd28..6a3e7e77ed8 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -25,3 +25,5 @@ SConscript([ for driver in env['drivers']: SConscript(os.path.join('drivers', driver, 'SConscript')) + +SConscript('state_trackers/python/SConscript') diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 621472ec7c8..c63bd51a106 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -119,7 +119,7 @@ draw_create_vs_llvm(struct draw_context *draw, vs->base.create_varient = draw_vs_varient_generic; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; - vs->machine = &draw->machine; + vs->machine = &draw->vs.machine; { struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); @@ -130,16 +130,16 @@ draw_create_vs_llvm(struct draw_context *draw, gallivm_ir_delete(ir); } - draw->engine = gallivm_global_cpu_engine(); + draw->vs.engine = gallivm_global_cpu_engine(); /* XXX: Why are there two versions of this? Shouldn't creating the * engine be a separate operation to compiling a shader? */ - if (!draw->engine) { - draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); + if (!draw->vs.engine) { + draw->vs.engine = gallivm_cpu_engine_create(vs->llvm_prog); } else { - gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); + gallivm_cpu_jit_compile(draw->vs.engine, vs->llvm_prog); } return &vs->base; diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h index 19ca84ddc68..3a476928b6d 100644 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -85,7 +85,7 @@ public: llvm::Value *lit(llvm::Value *in); llvm::Value *lg2(llvm::Value *in); llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in2); + llvm::Value *in3); llvm::Value *min(llvm::Value *in1, llvm::Value *in2); llvm::Value *max(llvm::Value *in1, llvm::Value *in2); llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index acb9d7ad146..affa6aa85c4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -142,12 +142,12 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf) assert(map); if(map) { if(!check_random_pattern(map, buf->underflow_size)) { - debug_printf("buffer underflow\n"); + debug_error("buffer underflow detected\n"); debug_assert(0); } if(!check_random_pattern(map + buf->underflow_size + buf->base.base.size, buf->overflow_size)) { - debug_printf("buffer overflow\n"); + debug_error("buffer overflow detected\n"); debug_assert(0); } pb_unmap(buf->buffer); diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 4632dcc0728..b62c8efe027 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -9,6 +9,7 @@ tgsi = env.ConvenienceLibrary( 'util/tgsi_dump.c', 'util/tgsi_parse.c', 'util/tgsi_scan.c', + 'util/tgsi_text.c', 'util/tgsi_transform.c', 'util/tgsi_util.c', ]) diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index e66d1152836..af838b2a25b 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -1,4 +1,31 @@ -#if !defined TGSI_SSE2_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SSE2_H #define TGSI_SSE2_H #if defined __cplusplus @@ -20,4 +47,3 @@ tgsi_emit_sse2( #endif #endif /* TGSI_SSE2_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c index 18e44b38c24..742ef14c352 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2007 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 "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -1295,4 +1322,3 @@ tgsi_build_dst_register_ext_modulate( return dst_register_ext_modulate; } - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h index 423cf141f56..ed258302487 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h @@ -1,4 +1,31 @@ -#if !defined TGSI_BUILD_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_BUILD_H #define TGSI_BUILD_H #if defined __cplusplus @@ -303,4 +330,3 @@ tgsi_build_dst_register_ext_modulate( #endif #endif /* TGSI_BUILD_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index a395c630cc7..0cf4454f254 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -119,8 +119,7 @@ static const char *TGSI_INTERPOLATES_SHORT[] = { "CONSTANT", "LINEAR", - "PERSPECTIVE", - "ATTRIB" + "PERSPECTIVE" }; static const char *TGSI_SEMANTICS[] = @@ -396,7 +395,8 @@ static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = "IFC", "BREAKC", "KIL", - "END" + "END", + "SWZ" }; static const char *TGSI_SATS[] = @@ -539,6 +539,17 @@ static const char *TGSI_MODULATES[] = "MODULATE_EIGHTH" }; +static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] = +{ + "", + "_2X", + "_4X", + "_8X", + "_D2", + "_D4", + "_D8" +}; + void tgsi_dump_declaration( const struct tgsi_full_declaration *decl ) @@ -716,7 +727,7 @@ tgsi_dump_instruction( TXT( "_SAT" ); break; case TGSI_SAT_MINUS_PLUS_ONE: - TXT( "_SAT[-1,1]" ); + TXT( "_SATNV" ); break; default: assert( 0 ); @@ -736,30 +747,7 @@ tgsi_dump_instruction( SID( dst->DstRegister.Index ); CHR( ']' ); - switch (dst->DstRegisterExtModulate.Modulate) { - case TGSI_MODULATE_1X: - break; - case TGSI_MODULATE_2X: - TXT( "_2X" ); - break; - case TGSI_MODULATE_4X: - TXT( "_4X" ); - break; - case TGSI_MODULATE_8X: - TXT( "_8X" ); - break; - case TGSI_MODULATE_HALF: - TXT( "_D2" ); - break; - case TGSI_MODULATE_QUARTER: - TXT( "_D4" ); - break; - case TGSI_MODULATE_EIGHTH: - TXT( "_D8" ); - break; - default: - assert( 0 ); - } + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES_SHORT ); if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { CHR( '.' ); @@ -805,10 +793,12 @@ tgsi_dump_instruction( CHR( '[' ); if (src->SrcRegister.Indirect) { - TXT( "addr" ); - if (src->SrcRegister.Index > 0) - CHR( '+' ); - SID( src->SrcRegister.Index ); + TXT( "ADDR[0]" ); + if (src->SrcRegister.Index != 0) { + if (src->SrcRegister.Index > 0) + CHR( '+' ); + SID( src->SrcRegister.Index ); + } } else SID( src->SrcRegister.Index ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index ca83bdef206..ba7692b5112 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -1,4 +1,31 @@ -#if !defined TGSI_DUMP_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_DUMP_H #define TGSI_DUMP_H #if defined __cplusplus @@ -31,10 +58,8 @@ void tgsi_dump_declaration( const struct tgsi_full_declaration *decl ); - #if defined __cplusplus } #endif #endif /* TGSI_DUMP_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c new file mode 100644 index 00000000000..1b283feb4c8 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -0,0 +1,1063 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_text.h" +#include "tgsi_build.h" +#include "tgsi_parse.h" +#include "tgsi_util.h" + +static boolean is_alpha_underscore( const char *cur ) +{ + return + (*cur >= 'a' && *cur <= 'z') || + (*cur >= 'A' && *cur <= 'Z') || + *cur == '_'; +} + +static boolean is_digit( const char *cur ) +{ + return *cur >= '0' && *cur <= '9'; +} + +static boolean is_digit_alpha_underscore( const char *cur ) +{ + return is_digit( cur ) || is_alpha_underscore( cur ); +} + +static boolean str_match_no_case( const char **pcur, const char *str ) +{ + const char *cur = *pcur; + + while (*str != '\0' && *str == toupper( *cur )) { + str++; + cur++; + } + if (*str == '\0') { + *pcur = cur; + return TRUE; + } + return FALSE; +} + +/* Eat zero or more whitespaces. + */ +static void eat_opt_white( const char **pcur ) +{ + while (**pcur == ' ' || **pcur == '\t' || **pcur == '\n') + (*pcur)++; +} + +/* Eat one or more whitespaces. + * Return TRUE if at least one whitespace eaten. + */ +static boolean eat_white( const char **pcur ) +{ + const char *cur = *pcur; + + eat_opt_white( pcur ); + return *pcur > cur; +} + +/* Parse unsigned integer. + * No checks for overflow. + */ +static boolean parse_uint( const char **pcur, uint *val ) +{ + const char *cur = *pcur; + + if (is_digit( cur )) { + *val = *cur++ - '0'; + while (is_digit( cur )) + *val = *val * 10 + *cur++ - '0'; + *pcur = cur; + return TRUE; + } + return FALSE; +} + +/* Parse floating point. + */ +static boolean parse_float( const char **pcur, float *val ) +{ + const char *cur = *pcur; + boolean integral_part = FALSE; + boolean fractional_part = FALSE; + + *val = (float) atof( cur ); + + if (*cur == '-' || *cur == '+') + cur++; + if (is_digit( cur )) { + cur++; + integral_part = TRUE; + while (is_digit( cur )) + cur++; + } + if (*cur == '.') { + cur++; + if (is_digit( cur )) { + cur++; + fractional_part = TRUE; + while (is_digit( cur )) + cur++; + } + } + if (!integral_part && !fractional_part) + return FALSE; + if (toupper( *cur ) == 'E') { + cur++; + if (*cur == '-' || *cur == '+') + cur++; + if (is_digit( cur )) { + cur++; + while (is_digit( cur )) + cur++; + } + else + return FALSE; + } + *pcur = cur; + return TRUE; +} + +struct translate_ctx +{ + const char *text; + const char *cur; + struct tgsi_token *tokens; + struct tgsi_token *tokens_cur; + struct tgsi_token *tokens_end; + struct tgsi_header *header; +}; + +static void report_error( struct translate_ctx *ctx, const char *msg ) +{ + debug_printf( "\nError: %s", msg ); +} + +/* Parse shader header. + * Return TRUE for one of the following headers. + * FRAG1.1 + * GEOM1.1 + * VERT1.1 + */ +static boolean parse_header( struct translate_ctx *ctx ) +{ + uint processor; + + if (str_match_no_case( &ctx->cur, "FRAG1.1" )) + processor = TGSI_PROCESSOR_FRAGMENT; + else if (str_match_no_case( &ctx->cur, "VERT1.1" )) + processor = TGSI_PROCESSOR_VERTEX; + else if (str_match_no_case( &ctx->cur, "GEOM1.1" )) + processor = TGSI_PROCESSOR_GEOMETRY; + else { + report_error( ctx, "Unknown header" ); + return FALSE; + } + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + *(struct tgsi_version *) ctx->tokens_cur++ = tgsi_build_version(); + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + ctx->header = (struct tgsi_header *) ctx->tokens_cur++; + *ctx->header = tgsi_build_header(); + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + *(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header ); + + return TRUE; +} + +static boolean parse_label( struct translate_ctx *ctx, uint *val ) +{ + const char *cur = ctx->cur; + + if (parse_uint( &cur, val )) { + eat_opt_white( &cur ); + if (*cur == ':') { + cur++; + ctx->cur = cur; + return TRUE; + } + } + return FALSE; +} + +static const char *file_names[TGSI_FILE_COUNT] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static boolean +parse_file( + struct translate_ctx *ctx, + uint *file ) +{ + uint i; + + for (i = 0; i < TGSI_FILE_COUNT; i++) { + const char *cur = ctx->cur; + + if (str_match_no_case( &cur, file_names[i] )) { + if (!is_digit_alpha_underscore( cur )) { + ctx->cur = cur; + *file = i; + return TRUE; + } + } + } + report_error( ctx, "Unknown register file" ); + return FALSE; +} + +static boolean +parse_opt_writemask( + struct translate_ctx *ctx, + uint *writemask ) +{ + const char *cur; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '.') { + cur++; + *writemask = TGSI_WRITEMASK_NONE; + eat_opt_white( &cur ); + if (toupper( *cur ) == 'X') { + cur++; + *writemask |= TGSI_WRITEMASK_X; + } + if (toupper( *cur ) == 'Y') { + cur++; + *writemask |= TGSI_WRITEMASK_Y; + } + if (toupper( *cur ) == 'Z') { + cur++; + *writemask |= TGSI_WRITEMASK_Z; + } + if (toupper( *cur ) == 'W') { + cur++; + *writemask |= TGSI_WRITEMASK_W; + } + + if (*writemask == TGSI_WRITEMASK_NONE) { + report_error( ctx, "Writemask expected" ); + return FALSE; + } + + ctx->cur = cur; + } + else { + *writemask = TGSI_WRITEMASK_XYZW; + } + return TRUE; +} + +/* Parse register part common for decls and operands. + * <register_prefix> ::= <file> `[' <index> + */ +static boolean +parse_register_prefix( + struct translate_ctx *ctx, + uint *file, + uint *index ) +{ + if (!parse_file( ctx, file )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '[') { + report_error( ctx, "Expected `['" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + return TRUE; +} + +/* Parse register operand. + * <register> ::= <register_prefix> `]' + */ +static boolean +parse_register( + struct translate_ctx *ctx, + uint *file, + uint *index ) +{ + if (!parse_register_prefix( ctx, file, index )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + ctx->cur++; + /* TODO: Modulate suffix */ + return TRUE; +} + +/* Parse register declaration. + * <register> ::= <register_prefix> `]' | <register_prefix> `..' <index> `]' + */ +static boolean +parse_register_dcl( + struct translate_ctx *ctx, + uint *file, + uint *first, + uint *last ) +{ + if (!parse_register_prefix( ctx, file, first )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (ctx->cur[0] == '.' && ctx->cur[1] == '.') { + ctx->cur += 2; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, last )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + } + else { + *last = *first; + } + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]' or `..'" ); + return FALSE; + } + ctx->cur++; + return TRUE; +} + +static const char *modulate_names[TGSI_MODULATE_COUNT] = +{ + "_1X", + "_2X", + "_4X", + "_8X", + "_D2", + "_D4", + "_D8" +}; + +static boolean +parse_dst_operand( + struct translate_ctx *ctx, + struct tgsi_full_dst_register *dst ) +{ + uint file; + uint index; + uint writemask; + const char *cur; + + if (!parse_register( ctx, &file, &index )) + return FALSE; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '_') { + uint i; + + for (i = 0; i < TGSI_MODULATE_COUNT; i++) { + if (str_match_no_case( &cur, modulate_names[i] )) { + if (!is_digit_alpha_underscore( cur )) { + dst->DstRegisterExtModulate.Modulate = i; + ctx->cur = cur; + break; + } + } + } + } + + if (!parse_opt_writemask( ctx, &writemask )) + return FALSE; + + dst->DstRegister.File = file; + dst->DstRegister.Index = index; + dst->DstRegister.WriteMask = writemask; + return TRUE; +} + +static boolean +parse_src_operand( + struct translate_ctx *ctx, + struct tgsi_full_src_register *src ) +{ + const char *cur; + float value; + uint file; + uint index; + + if (*ctx->cur == '-') { + cur = ctx->cur; + cur++; + eat_opt_white( &cur ); + if (*cur == '(') { + cur++; + src->SrcRegisterExtMod.Negate = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (*ctx->cur == '|') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegisterExtMod.Absolute = 1; + } + + if (*ctx->cur == '-') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegister.Negate = 1; + } + + cur = ctx->cur; + if (parse_float( &cur, &value )) { + if (value == 2.0f) { + eat_opt_white( &cur ); + if (*cur != '*') { + report_error( ctx, "Expected `*'" ); + return FALSE; + } + cur++; + if (*cur != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur++; + src->SrcRegisterExtMod.Scale2X = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (*ctx->cur == '(') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegisterExtMod.Bias = 1; + } + + cur = ctx->cur; + if (parse_float( &cur, &value )) { + if (value == 1.0f) { + eat_opt_white( &cur ); + if (*cur != '-') { + report_error( ctx, "Expected `-'" ); + return FALSE; + } + cur++; + if (*cur != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur++; + src->SrcRegisterExtMod.Complement = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (!parse_register( ctx, &file, &index )) + return FALSE; + src->SrcRegister.File = file; + src->SrcRegister.Index = index; + + /* Parse optional swizzle + */ + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '.') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < 4; i++) { + uint swizzle; + + if (toupper( *cur ) == 'X') + swizzle = TGSI_SWIZZLE_X; + else if (toupper( *cur ) == 'Y') + swizzle = TGSI_SWIZZLE_Y; + else if (toupper( *cur ) == 'Z') + swizzle = TGSI_SWIZZLE_Z; + else if (toupper( *cur ) == 'W') + swizzle = TGSI_SWIZZLE_W; + else { + report_error( ctx, "Expected register swizzle component either `x', `y', `z' or `w'" ); + return FALSE; + } + cur++; + tgsi_util_set_src_register_swizzle( &src->SrcRegister, swizzle, i ); + } + + ctx->cur = cur; + } + + if (src->SrcRegisterExtMod.Complement) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Bias) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '-') { + report_error( ctx, "Expected `-'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_float( &ctx->cur, &value )) { + report_error( ctx, "Expected literal floating point" ); + return FALSE; + } + if (value != 0.5f) { + report_error( ctx, "Expected 0.5" ); + return FALSE; + } + } + + if (src->SrcRegisterExtMod.Scale2X) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Absolute) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '|') { + report_error( ctx, "Expected `|'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Negate) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + return TRUE; +} + +struct opcode_info +{ + uint num_dst; + uint num_src; + uint is_tex; + const char *mnemonic; +}; + +static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = +{ + { 1, 1, 0, "ARL" }, + { 1, 1, 0, "MOV" }, + { 1, 1, 0, "LIT" }, + { 1, 1, 0, "RCP" }, + { 1, 1, 0, "RSQ" }, + { 1, 1, 0, "EXP" }, + { 1, 1, 0, "LOG" }, + { 1, 2, 0, "MUL" }, + { 1, 2, 0, "ADD" }, + { 1, 2, 0, "DP3" }, + { 1, 2, 0, "DP4" }, + { 1, 2, 0, "DST" }, + { 1, 2, 0, "MIN" }, + { 1, 2, 0, "MAX" }, + { 1, 2, 0, "SLT" }, + { 1, 2, 0, "SGE" }, + { 1, 3, 0, "MAD" }, + { 1, 2, 0, "SUB" }, + { 1, 3, 0, "LERP" }, + { 1, 3, 0, "CND" }, + { 1, 3, 0, "CND0" }, + { 1, 3, 0, "DOT2ADD" }, + { 1, 2, 0, "INDEX" }, + { 1, 1, 0, "NEGATE" }, + { 1, 1, 0, "FRAC" }, + { 1, 3, 0, "CLAMP" }, + { 1, 1, 0, "FLOOR" }, + { 1, 1, 0, "ROUND" }, + { 1, 1, 0, "EXPBASE2" }, + { 1, 1, 0, "LOGBASE2" }, + { 1, 2, 0, "POWER" }, + { 1, 2, 0, "CROSSPRODUCT" }, + { 1, 2, 0, "MULTIPLYMATRIX" }, + { 1, 1, 0, "ABS" }, + { 1, 1, 0, "RCC" }, + { 1, 2, 0, "DPH" }, + { 1, 1, 0, "COS" }, + { 1, 1, 0, "DDX" }, + { 1, 1, 0, "DDY" }, + { 0, 1, 0, "KILP" }, + { 1, 1, 0, "PK2H" }, + { 1, 1, 0, "PK2US" }, + { 1, 1, 0, "PK4B" }, + { 1, 1, 0, "PK4UB" }, + { 1, 2, 0, "RFL" }, + { 1, 2, 0, "SEQ" }, + { 1, 2, 0, "SFL" }, + { 1, 2, 0, "SGT" }, + { 1, 1, 0, "SIN" }, + { 1, 2, 0, "SLE" }, + { 1, 2, 0, "SNE" }, + { 1, 2, 0, "STR" }, + { 1, 2, 1, "TEX" }, + { 1, 4, 1, "TXD" }, + { 1, 2, 1, "TXP" }, + { 1, 1, 0, "UP2H" }, + { 1, 1, 0, "UP2US" }, + { 1, 1, 0, "UP4B" }, + { 1, 1, 0, "UP4UB" }, + { 1, 3, 0, "X2D" }, + { 1, 1, 0, "ARA" }, + { 1, 1, 0, "ARR" }, + { 0, 1, 0, "BRA" }, + { 0, 0, 0, "CAL" }, + { 0, 0, 0, "RET" }, + { 1, 1, 0, "SSG" }, + { 1, 3, 0, "CMP" }, + { 1, 1, 0, "SCS" }, + { 1, 2, 1, "TXB" }, + { 1, 1, 0, "NRM" }, + { 1, 2, 0, "DIV" }, + { 1, 2, 0, "DP2" }, + { 1, 2, 1, "TXL" }, + { 0, 0, 0, "BRK" }, + { 0, 1, 0, "IF" }, + { 0, 0, 0, "LOOP" }, + { 0, 1, 0, "REP" }, + { 0, 0, 0, "ELSE" }, + { 0, 0, 0, "ENDIF" }, + { 0, 0, 0, "ENDLOOP" }, + { 0, 0, 0, "ENDREP" }, + { 0, 1, 0, "PUSHA" }, + { 1, 0, 0, "POPA" }, + { 1, 1, 0, "CEIL" }, + { 1, 1, 0, "I2F" }, + { 1, 1, 0, "NOT" }, + { 1, 1, 0, "TRUNC" }, + { 1, 2, 0, "SHL" }, + { 1, 2, 0, "SHR" }, + { 1, 2, 0, "AND" }, + { 1, 2, 0, "OR" }, + { 1, 2, 0, "MOD" }, + { 1, 2, 0, "XOR" }, + { 1, 3, 0, "SAD" }, + { 1, 2, 1, "TXF" }, + { 1, 2, 1, "TXQ" }, + { 0, 0, 0, "CONT" }, + { 0, 0, 0, "EMIT" }, + { 0, 0, 0, "ENDPRIM" }, + { 0, 0, 0, "BGNLOOP2" }, + { 0, 0, 0, "BGNSUB" }, + { 0, 0, 0, "ENDLOOP2" }, + { 0, 0, 0, "ENDSUB" }, + { 1, 1, 0, "NOISE1" }, + { 1, 1, 0, "NOISE2" }, + { 1, 1, 0, "NOISE3" }, + { 1, 1, 0, "NOISE4" }, + { 0, 0, 0, "NOP" }, + { 1, 2, 0, "M4X3" }, + { 1, 2, 0, "M3X4" }, + { 1, 2, 0, "M3X3" }, + { 1, 2, 0, "M3X2" }, + { 1, 1, 0, "NRM4" }, + { 0, 1, 0, "CALLNZ" }, + { 0, 1, 0, "IFC" }, + { 0, 1, 0, "BREAKC" }, + { 0, 0, 0, "KIL" }, + { 0, 0, 0, "END" }, + { 1, 1, 0, "SWZ" } +}; + +static const char *texture_names[TGSI_TEXTURE_COUNT] = +{ + "UNKNOWN", + "1D", + "2D", + "3D", + "CUBE", + "RECT", + "SHADOW1D", + "SHADOW2D", + "SHADOWRECT" +}; + +static boolean parse_instruction( struct translate_ctx *ctx ) +{ + uint i; + uint saturate = TGSI_SAT_NONE; + const struct opcode_info *info; + struct tgsi_full_instruction inst; + uint advance; + + /* Parse instruction name. + */ + eat_opt_white( &ctx->cur ); + for (i = 0; i < TGSI_OPCODE_LAST; i++) { + const char *cur = ctx->cur; + + if (str_match_no_case( &cur, opcode_info[i].mnemonic )) { + if (str_match_no_case( &cur, "_SATNV" )) + saturate = TGSI_SAT_MINUS_PLUS_ONE; + else if (str_match_no_case( &cur, "_SAT" )) + saturate = TGSI_SAT_ZERO_ONE; + + if (*cur == '\0' || eat_white( &cur )) { + ctx->cur = cur; + break; + } + } + } + if (i == TGSI_OPCODE_LAST) { + report_error( ctx, "Unknown opcode" ); + return FALSE; + } + info = &opcode_info[i]; + + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = i; + inst.Instruction.Saturate = saturate; + inst.Instruction.NumDstRegs = info->num_dst; + inst.Instruction.NumSrcRegs = info->num_src; + + /* Parse instruction operands. + */ + for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) { + if (i > 0) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + } + + if (i < info->num_dst) { + if (!parse_dst_operand( ctx, &inst.FullDstRegisters[i] )) + return FALSE; + } + else if (i < info->num_dst + info->num_src) { + if (!parse_src_operand( ctx, &inst.FullSrcRegisters[i - info->num_dst] )) + return FALSE; + } + else { + uint j; + + for (j = 0; j < TGSI_TEXTURE_COUNT; j++) { + if (str_match_no_case( &ctx->cur, texture_names[j] )) { + if (!is_digit_alpha_underscore( ctx->cur )) { + inst.InstructionExtTexture.Texture = j; + break; + } + } + } + if (j == TGSI_TEXTURE_COUNT) { + report_error( ctx, "Expected texture target" ); + return FALSE; + } + } + } + + advance = tgsi_build_full_instruction( + &inst, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static const char *semantic_names[TGSI_SEMANTIC_COUNT] = +{ + "POSITION", + "COLOR", + "BCOLOR", + "FOG", + "PSIZE", + "GENERIC", + "NORMAL" +}; + +static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] = +{ + "CONSTANT", + "LINEAR", + "PERSPECTIVE" +}; + +static boolean parse_declaration( struct translate_ctx *ctx ) +{ + struct tgsi_full_declaration decl; + uint file; + uint first; + uint last; + uint writemask; + const char *cur; + uint advance; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (!parse_register_dcl( ctx, &file, &first, &last )) + return FALSE; + if (!parse_opt_writemask( ctx, &writemask )) + return FALSE; + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = file; + decl.Declaration.UsageMask = writemask; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { + if (str_match_no_case( &cur, semantic_names[i] )) { + const char *cur2 = cur; + uint index; + + if (is_digit_alpha_underscore( cur )) + continue; + eat_opt_white( &cur2 ); + if (*cur2 == '[') { + cur2++; + eat_opt_white( &cur2 ); + if (!parse_uint( &cur2, &index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &cur2 ); + if (*cur2 != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + cur2++; + + decl.Semantic.SemanticIndex = index; + + cur = cur2; + } + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = i; + + ctx->cur = cur; + break; + } + } + } + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) { + if (str_match_no_case( &cur, interpolate_names[i] )) { + if (is_digit_alpha_underscore( cur )) + continue; + decl.Declaration.Interpolate = i; + + ctx->cur = cur; + break; + } + } + if (i == TGSI_INTERPOLATE_COUNT) { + report_error( ctx, "Expected semantic or interpolate attribute" ); + return FALSE; + } + } + + advance = tgsi_build_full_declaration( + &decl, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static boolean parse_immediate( struct translate_ctx *ctx ) +{ + struct tgsi_full_immediate imm; + uint i; + float values[4]; + uint advance; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (!str_match_no_case( &ctx->cur, "FLT32" ) || is_digit_alpha_underscore( ctx->cur )) { + report_error( ctx, "Expected `FLT32'" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '{') { + report_error( ctx, "Expected `{'" ); + return FALSE; + } + ctx->cur++; + for (i = 0; i < 4; i++) { + eat_opt_white( &ctx->cur ); + if (i > 0) { + if (*ctx->cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + } + if (!parse_float( &ctx->cur, &values[i] )) { + report_error( ctx, "Expected literal floating point" ); + return FALSE; + } + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '}') { + report_error( ctx, "Expected `}'" ); + return FALSE; + } + ctx->cur++; + + imm = tgsi_default_full_immediate(); + imm.Immediate.Size += 4; + imm.Immediate.DataType = TGSI_IMM_FLOAT32; + imm.u.Pointer = values; + + advance = tgsi_build_full_immediate( + &imm, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static boolean translate( struct translate_ctx *ctx ) +{ + eat_opt_white( &ctx->cur ); + if (!parse_header( ctx )) + return FALSE; + + while (*ctx->cur != '\0') { + uint label_val = 0; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + + if (parse_label( ctx, &label_val )) { + if (!parse_instruction( ctx )) + return FALSE; + } + else if (str_match_no_case( &ctx->cur, "DCL" )) { + if (!parse_declaration( ctx )) + return FALSE; + } + else if (str_match_no_case( &ctx->cur, "IMM" )) { + if (!parse_immediate( ctx )) + return FALSE; + } + else { + report_error( ctx, "Expected `DCL', `IMM' or a label" ); + return FALSE; + } + } + + return TRUE; +} + +boolean +tgsi_text_translate( + const char *text, + struct tgsi_token *tokens, + uint num_tokens ) +{ + struct translate_ctx ctx; + + ctx.text = text; + ctx.cur = text; + ctx.tokens = tokens; + ctx.tokens_cur = tokens; + ctx.tokens_end = tokens + num_tokens; + + return translate( &ctx ); +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.h b/src/gallium/auxiliary/tgsi/util/tgsi_text.h new file mode 100644 index 00000000000..8eeeeef1402 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_TEXT_H +#define TGSI_TEXT_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +boolean +tgsi_text_translate( + const char *text, + struct tgsi_token *tokens, + uint num_tokens ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_TEXT_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c index 56a50d3b210..10762b6c1a0 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2007 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 "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -271,4 +298,3 @@ tgsi_util_set_full_src_register_sign_mode( assert( 0 ); } } - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.h b/src/gallium/auxiliary/tgsi/util/tgsi_util.h index 45f5f0be0e4..7877f345587 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.h @@ -1,4 +1,31 @@ -#if !defined TGSI_UTIL_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_UTIL_H #define TGSI_UTIL_H #if defined __cplusplus @@ -67,4 +94,3 @@ tgsi_util_set_full_src_register_sign_mode( #endif #endif /* TGSI_UTIL_H */ - diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 93abef98792..1a1a2d96cc6 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -45,12 +45,10 @@ * This should be usable by any hw driver that has mappable surfaces. */ void -pipe_get_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *dst, int dst_stride) { - struct pipe_screen *screen = pipe->screen; const void *src; if (pipe_clip_tile(x, y, &w, &h, ps)) @@ -59,14 +57,14 @@ pipe_get_tile_raw(struct pipe_context *pipe, if (dst_stride == 0) dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - src = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); assert(src); if(!src) return; pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y); - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } @@ -75,12 +73,10 @@ pipe_get_tile_raw(struct pipe_context *pipe, * This should be usable by any hw driver that has mappable surfaces. */ void -pipe_put_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *src, int src_stride) { - struct pipe_screen *screen = pipe->screen; void *dst; if (pipe_clip_tile(x, y, &w, &h, ps)) @@ -89,14 +85,14 @@ pipe_put_tile_raw(struct pipe_context *pipe, if (src_stride == 0) src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - dst = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); assert(dst); if(!dst) return; pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0); - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } @@ -686,8 +682,7 @@ ycbcr_get_tile_rgba(ushort *src, void -pipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p) { @@ -702,7 +697,7 @@ pipe_get_tile_rgba(struct pipe_context *pipe, if (!packed) return; - pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, 0); + pipe_get_tile_raw(ps, x, y, w, h, packed, 0); switch (ps->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: @@ -768,8 +763,7 @@ pipe_get_tile_rgba(struct pipe_context *pipe, void -pipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p) { @@ -838,7 +832,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, assert(0); } - pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, 0); + pipe_put_tile_raw(ps, x, y, w, h, packed, 0); FREE(packed); } @@ -848,12 +842,10 @@ pipe_put_tile_rgba(struct pipe_context *pipe, * Get a block of Z values, converted to 32-bit range. */ void -pipe_get_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, uint *z) { - struct pipe_screen *screen = pipe->screen; const uint dstStride = w; ubyte *map; uint *pDest = z; @@ -862,7 +854,7 @@ pipe_get_tile_z(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); if (!map) { assert(0); return; @@ -913,17 +905,15 @@ pipe_get_tile_z(struct pipe_context *pipe, assert(0); } - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } void -pipe_put_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const uint *zSrc) { - struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; ubyte *map; @@ -932,7 +922,7 @@ pipe_put_tile_z(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); if (!map) { assert(0); return; @@ -980,7 +970,7 @@ pipe_put_tile_z(struct pipe_context *pipe, assert(0); } - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h index fdc80a13b38..adfec8bcee7 100644 --- a/src/gallium/auxiliary/util/p_tile.h +++ b/src/gallium/auxiliary/util/p_tile.h @@ -30,7 +30,6 @@ #include "pipe/p_compiler.h" -struct pipe_context; struct pipe_surface; @@ -57,40 +56,34 @@ extern "C" { #endif void -pipe_get_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *p, int dst_stride); void -pipe_put_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *p, int src_stride); void -pipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p); void -pipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p); void -pipe_get_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, uint *z); void -pipe_put_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const uint *z); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 2d5d2b50f51..bfdaaa6b8f4 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -339,7 +339,7 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe, for (y = 0; y < h; y += TILE_SIZE) { for (x = 0; x < w; x += TILE_SIZE) { if (is_clear_flag_set(tc->clear_flags, x, y)) { - pipe_put_tile_raw(pipe, ps, + pipe_put_tile_raw(ps, x, y, TILE_SIZE, TILE_SIZE, tc->tile.data.color32, 0/*STRIDE*/); @@ -374,12 +374,12 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_cached_tile *tile = tc->entries + pos; if (tile->x >= 0) { if (tc->depth_stencil) { - pipe_put_tile_raw(pipe, ps, + pipe_put_tile_raw(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(pipe, ps, + pipe_put_tile_rgba(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } @@ -431,12 +431,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe, if (tile->x != -1) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { - pipe_put_tile_raw(pipe, ps, + pipe_put_tile_raw(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(pipe, ps, + pipe_put_tile_rgba(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } @@ -458,12 +458,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe, else { /* get new tile data from surface */ if (tc->depth_stencil) { - pipe_get_tile_raw(pipe, ps, + pipe_get_tile_raw(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_get_tile_rgba(pipe, ps, + pipe_get_tile_rgba(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } @@ -544,7 +544,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, } /* get tile from the surface (view into texture) */ - pipe_get_tile_rgba(pipe, tc->tex_surf, + pipe_get_tile_rgba(tc->tex_surf, tile_x, tile_y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); tile->x = tile_x; diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 84e5096418b..ed931d24b99 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -75,6 +75,7 @@ enum tgsi_file_type { #define TGSI_INTERPOLATE_CONSTANT 0 #define TGSI_INTERPOLATE_LINEAR 1 #define TGSI_INTERPOLATE_PERSPECTIVE 2 +#define TGSI_INTERPOLATE_COUNT 3 struct tgsi_declaration { @@ -528,6 +529,7 @@ struct tgsi_instruction_ext_label #define TGSI_TEXTURE_SHADOW1D 6 #define TGSI_TEXTURE_SHADOW2D 7 #define TGSI_TEXTURE_SHADOWRECT 8 +#define TGSI_TEXTURE_COUNT 9 struct tgsi_instruction_ext_texture { @@ -741,6 +743,7 @@ struct tgsi_dst_register_ext_concode #define TGSI_MODULATE_HALF 4 #define TGSI_MODULATE_QUARTER 5 #define TGSI_MODULATE_EIGHTH 6 +#define TGSI_MODULATE_COUNT 7 struct tgsi_dst_register_ext_modulate { diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README new file mode 100644 index 00000000000..75341aa28cc --- /dev/null +++ b/src/gallium/state_trackers/python/README @@ -0,0 +1,32 @@ +This directory contains Python bindings to Gallium3D. It looks like a state +tracker from the pipe driver perspective, and it looks like a pipe driver from +the python script perspective. + + +To build you'll need: +* Python (with development packages) +* SCons +* SWIG +* Python Imaging Library (for the samples) + +Invoke scons on the top dir as + + scons statetrackers=python + +To use do + + export PYTHONPATH=build/XXXX-XXXX-XXXX/gallium/state_trackers/python + +and then try running + + python src/gallium/state_trackers/python/samples/simple.py + +which should create a simple.png + + +This is still in experimental phase, and there many limitations to what you can +do with from Python. + + +-- +Jose Fonseca <[email protected]> diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript new file mode 100644 index 00000000000..57a3fb20759 --- /dev/null +++ b/src/gallium/state_trackers/python/SConscript @@ -0,0 +1,24 @@ +Import('*') + +if 'python' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = '.') + + env.Tool('swig') + env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) + env.Append(SWIGFLAGS = ['-python', '-keyword']) + + env.ParseConfig('python-config --cflags --ldflags --libs') + + env.SharedLibrary( + target = '_gallium', + source = [ + 'gallium.i', + 'st_device.c', + 'st_softpipe_winsys.c', + ], + SHLIBPREFIX = '', + LIBS = softpipe + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i new file mode 100644 index 00000000000..d6594f3a87a --- /dev/null +++ b/src/gallium/state_trackers/python/gallium.i @@ -0,0 +1,448 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca <[email protected]> + */ + +%module gallium; + +%{ + +#include <stdio.h> +#include <Python.h> + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "util/u_draw_quad.h" +#include "util/p_tile.h" +#include "cso_cache/cso_context.h" + +#include "st_device.h" + +%} + +%include "carrays.i" +%array_class(int, IntArray); +%array_class(float, FloatArray); + + +%rename(Device) st_device; +%rename(Context) st_context; +%rename(Texture) pipe_texture; +%rename(Surface) pipe_surface; + +%rename(Buffer) pipe_buffer; +%rename(BlendColor) pipe_blend_color; +%rename(Blend) pipe_blend_state; +%rename(Clip) pipe_clip_state; +%rename(ConstantBuffer) pipe_constant_buffer; +%rename(DepthStencilAlpha) pipe_depth_stencil_alpha_state; +%rename(FormatBlock) pipe_format_block; +%rename(Framebuffer) pipe_framebuffer_state; +%rename(PolyStipple) pipe_poly_stipple; +%rename(Rasterizer) pipe_rasterizer_state; +%rename(Sampler) pipe_sampler_state; +%rename(Scissor) pipe_scissor_state; +%rename(Shader) pipe_shader_state; +%rename(VertexBuffer) pipe_vertex_buffer; +%rename(VertexElement) pipe_vertex_element; +%rename(Viewport) pipe_viewport_state; + +%include "p_format.i"; +%include "pipe/p_defines.h"; +%include "pipe/p_state.h"; +%include "pipe/p_shader_tokens.h"; + + +%nodefaultctor; +%nodefaultdtor; + +struct st_device { +}; + +struct st_context { +}; + + +%extend st_device { + + st_device(int hardware = 0) { + return st_device_create(hardware ? TRUE : FALSE); + } + + ~st_device() { + st_device_destroy($self); + } + + const char * get_name( void ) { + return $self->screen->get_name($self->screen); + } + + const char * get_vendor( void ) { + return $self->screen->get_vendor($self->screen); + } + + /** + * Query an integer-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + int get_param( int param ) { + return $self->screen->get_param($self->screen, param); + } + + /** + * Query a float-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + float get_paramf( int param ) { + return $self->screen->get_paramf($self->screen, param); + } + + /** + * Check if the given pipe_format is supported as a texture or + * drawing surface. + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ + int is_format_supported( enum pipe_format format, unsigned type ) { + return $self->screen->is_format_supported( $self->screen, format, type); + } + + struct st_context * + context_create(void) { + return st_context_create($self); + } + + struct pipe_texture * + texture_create( + enum pipe_format format, + unsigned width, + unsigned height, + unsigned depth = 1, + unsigned last_level = 0, + enum pipe_texture_target target = PIPE_TEXTURE_2D, + unsigned usage = 0 + ) { + struct pipe_texture templat; + memset(&templat, 0, sizeof(templat)); + templat.format = format; + pf_get_block(templat.format, &templat.block); + templat.width[0] = width; + templat.height[0] = height; + templat.depth[0] = depth; + templat.last_level = last_level; + templat.target = target; + templat.tex_usage = usage; + return $self->screen->texture_create($self->screen, &templat); + } + + struct pipe_buffer * + buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { + return $self->screen->winsys->buffer_create($self->screen->winsys, alignment, usage, size); + } + +}; + + +%extend st_context { + + ~st_context() { + st_context_destroy($self); + } + + /* + * State functions (create/bind/destroy state objects) + */ + + void set_blend( const struct pipe_blend_state *state ) { + cso_set_blend($self->cso, state); + } + + void set_sampler( unsigned index, const struct pipe_sampler_state *state ) { + cso_single_sampler($self->cso, index, state); + cso_single_sampler_done($self->cso); + } + + void set_rasterizer( const struct pipe_rasterizer_state *state ) { + cso_set_rasterizer($self->cso, state); + } + + void set_depth_stencil_alpha(const struct pipe_depth_stencil_alpha_state *state) { + cso_set_depth_stencil_alpha($self->cso, state); + } + + + void * create_fs( const struct pipe_shader_state *state ) { + return $self->pipe->create_fs_state($self->pipe, state); + } + + void bind_fs( void *state_obj ) { + $self->pipe->bind_fs_state($self->pipe, state_obj); + } + + void delete_fs( void *state_obj ) { + $self->pipe->delete_fs_state($self->pipe, state_obj); + } + + void * create_vs( const struct pipe_shader_state *state ) { + return $self->pipe->create_vs_state($self->pipe, state); + } + + void bind_vs( void *state_obj ) { + $self->pipe->bind_vs_state($self->pipe, state_obj); + } + + void delete_vs( void *state_obj ) { + $self->pipe->delete_vs_state($self->pipe, state_obj); + } + + /* + * Parameter-like state (or properties) + */ + + void set_blend_color(const struct pipe_blend_color *state ) { + cso_set_blend_color($self->cso, state); + } + + void set_clip(const struct pipe_clip_state *state ) { + $self->pipe->set_clip_state($self->pipe, state); + } + + void set_constant_buffer(unsigned shader, unsigned index, + const struct pipe_constant_buffer *buf ) { + $self->pipe->set_constant_buffer($self->pipe, shader, index, buf); + } + + void set_framebuffer(const struct pipe_framebuffer_state *state ) { + cso_set_framebuffer($self->cso, state); + } + + void set_polygon_stipple(const struct pipe_poly_stipple *state ) { + $self->pipe->set_polygon_stipple($self->pipe, state); + } + + void set_scissor(const struct pipe_scissor_state *state ) { + $self->pipe->set_scissor_state($self->pipe, state); + } + + void set_viewport(const struct pipe_viewport_state *state) { + cso_set_viewport($self->cso, state); + } + + void set_sampler_texture(unsigned index, + struct pipe_texture *texture) { + pipe_texture_reference(&$self->sampler_textures[index], texture); + $self->pipe->set_sampler_textures($self->pipe, + PIPE_MAX_SAMPLERS, + $self->sampler_textures); + } + + void set_vertex_buffer(unsigned index, + const struct pipe_vertex_buffer *buffer) { + memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer)); + $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers); + } + + void set_vertex_element(unsigned index, + const struct pipe_vertex_element *element) { + memcpy(&$self->vertex_elements[index], element, sizeof(*element)); + $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_elements); + } + + /* + * Draw functions + */ + + void draw_arrays(unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_arrays($self->pipe, mode, start, count); + } + + void draw_elements( struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_elements($self->pipe, indexBuffer, indexSize, mode, start, count); + } + + void draw_vertices(unsigned prim, + unsigned num_verts, + unsigned num_attribs, + const float *vertices) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_winsys *winsys = pipe->winsys; + struct pipe_buffer *vbuf; + float *map; + unsigned size; + + size = num_verts * num_attribs * 4 * sizeof(float); + + vbuf = winsys->buffer_create(winsys, + 32, + PIPE_BUFFER_USAGE_VERTEX, + size); + if(!vbuf) + goto error1; + + map = winsys->buffer_map(winsys, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) + goto error2; + memcpy(map, vertices, size); + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + + util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs); + +error2: + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); +error1: + ; + } + + void draw_quad(float x0, float y0, float x1, float y1, float z = 0.0f) { + util_draw_texquad($self->pipe, x0, y0, x1, y1, z); + } + + void + flush(void) { + struct pipe_fence_handle *fence = NULL; + $self->pipe->flush($self->pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + /* TODO: allow asynchronous operation */ + $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); + $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); + } + + /* + * Surface functions + */ + + void surface_copy(int do_flip, + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) { + $self->pipe->surface_copy($self->pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); + } + + void surface_fill(struct pipe_surface *dst, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value) { + $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); + } + + void clear(struct pipe_surface *surface, unsigned value) { + $self->pipe->clear($self->pipe, surface, value); + } + +}; + + +%extend pipe_texture { + + ~pipe_texture() { + struct pipe_texture *ptr = $self; + pipe_texture_reference(&ptr, NULL); + } + + /** Get a surface which is a "view" into a texture */ + struct pipe_surface * + get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) + { + struct pipe_screen *screen = $self->screen; + return screen->get_tex_surface(screen, $self, face, level, zslice, usage); + } + +}; + + +%extend pipe_surface { + + ~pipe_surface() { + struct pipe_surface *ptr = $self; + pipe_surface_reference(&ptr, NULL); + } + + // gets mapped to pipe_surface_map automatically + void * map( unsigned flags ); + + // gets mapped to pipe_surface_unmap automatically + void unmap( void ); + + void + get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) { + pipe_get_tile_rgba($self, x, y, w, h, p); + } + + void + put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *p) { + pipe_put_tile_rgba($self, x, y, w, h, p); + } + + void + get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { + pipe_get_tile_z($self, x, y, w, h, z); + } + + void + put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { + pipe_put_tile_z($self, x, y, w, h, z); + } + +}; + + +%extend pipe_framebuffer_state { + + pipe_framebuffer_state(void) { + return CALLOC_STRUCT(pipe_framebuffer_state); + } + + ~pipe_framebuffer_state() { + unsigned index; + for(index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) + pipe_surface_reference(&$self->cbufs[index], NULL); + pipe_surface_reference(&$self->zsbuf, NULL); + FREE($self); + } + + void + set_cbuf(unsigned index, struct pipe_surface *surface) { + pipe_surface_reference(&$self->cbufs[index], surface); + } + + void + set_zsbuf(struct pipe_surface *surface) { + pipe_surface_reference(&$self->zsbuf, surface); + } + +}; diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i new file mode 100644 index 00000000000..51ad4bebcdc --- /dev/null +++ b/src/gallium/state_trackers/python/p_format.i @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * XXX: SWIG can't parse p_format.h, so we need to duplicate the relevant + * declarations here + */ + +%{ +#include "pipe/p_format.h" +%} + +enum pipe_format { + PIPE_FORMAT_NONE, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A2B10G10R10_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, + PIPE_FORMAT_A8L8_UNORM, + PIPE_FORMAT_L16_UNORM, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z32_FLOAT, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_X8Z24_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_R64_FLOAT, + PIPE_FORMAT_R64G64_FLOAT, + PIPE_FORMAT_R64G64B64_FLOAT, + PIPE_FORMAT_R64G64B64A64_FLOAT, + PIPE_FORMAT_R32_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, + PIPE_FORMAT_R32_UNORM, + PIPE_FORMAT_R32G32_UNORM, + PIPE_FORMAT_R32G32B32_UNORM, + PIPE_FORMAT_R32G32B32A32_UNORM, + PIPE_FORMAT_R32_USCALED, + PIPE_FORMAT_R32G32_USCALED, + PIPE_FORMAT_R32G32B32_USCALED, + PIPE_FORMAT_R32G32B32A32_USCALED, + PIPE_FORMAT_R32_SNORM, + PIPE_FORMAT_R32G32_SNORM, + PIPE_FORMAT_R32G32B32_SNORM, + PIPE_FORMAT_R32G32B32A32_SNORM, + PIPE_FORMAT_R32_SSCALED, + PIPE_FORMAT_R32G32_SSCALED, + PIPE_FORMAT_R32G32B32_SSCALED, + PIPE_FORMAT_R32G32B32A32_SSCALED, + PIPE_FORMAT_R16_UNORM, + PIPE_FORMAT_R16G16_UNORM, + PIPE_FORMAT_R16G16B16_UNORM, + PIPE_FORMAT_R16G16B16A16_UNORM, + PIPE_FORMAT_R16_USCALED, + PIPE_FORMAT_R16G16_USCALED, + PIPE_FORMAT_R16G16B16_USCALED, + PIPE_FORMAT_R16G16B16A16_USCALED, + PIPE_FORMAT_R16_SNORM, + PIPE_FORMAT_R16G16_SNORM, + PIPE_FORMAT_R16G16B16_SNORM, + PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_R16_SSCALED, + PIPE_FORMAT_R16G16_SSCALED, + PIPE_FORMAT_R16G16B16_SSCALED, + PIPE_FORMAT_R16G16B16A16_SSCALED, + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8G8_UNORM, + PIPE_FORMAT_R8G8B8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_R8G8B8X8_UNORM, + PIPE_FORMAT_R8_USCALED, + PIPE_FORMAT_R8G8_USCALED, + PIPE_FORMAT_R8G8B8_USCALED, + PIPE_FORMAT_R8G8B8A8_USCALED, + PIPE_FORMAT_R8G8B8X8_USCALED, + PIPE_FORMAT_R8_SNORM, + PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM, + PIPE_FORMAT_R8G8B8X8_SNORM, + PIPE_FORMAT_B6G5R5_SNORM, + PIPE_FORMAT_A8B8G8R8_SNORM, + PIPE_FORMAT_X8B8G8R8_SNORM, + PIPE_FORMAT_R8_SSCALED, + PIPE_FORMAT_R8G8_SSCALED, + PIPE_FORMAT_R8G8B8_SSCALED, + PIPE_FORMAT_R8G8B8A8_SSCALED, + PIPE_FORMAT_R8G8B8X8_SSCALED, + PIPE_FORMAT_R32_FIXED, + PIPE_FORMAT_R32G32_FIXED, + PIPE_FORMAT_R32G32B32_FIXED, + PIPE_FORMAT_R32G32B32A32_FIXED, + + PIPE_FORMAT_L8_SRGB, + PIPE_FORMAT_A8_L8_SRGB, + PIPE_FORMAT_R8G8B8_SRGB, + PIPE_FORMAT_R8G8B8A8_SRGB, + PIPE_FORMAT_R8G8B8X8_SRGB, + + PIPE_FORMAT_X8UB8UG8SR8S_NORM, + PIPE_FORMAT_B6UG5SR5S_NORM, + + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, +}; + + +struct pipe_format_block +{ + unsigned size; + unsigned width; + unsigned height; +}; + diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py new file mode 100644 index 00000000000..77e182b6447 --- /dev/null +++ b/src/gallium/state_trackers/python/samples/simple.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +########################################################################## + + +from gallium import * + + +def save_image(filename, surface): + pixels = FloatArray(surface.height*surface.width*4) + surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + + import Image + outimage = Image.new( + mode='RGB', + size=(surface.width, surface.height), + color=(0,0,0)) + outpixels = outimage.load() + for y in range(0, surface.height): + for x in range(0, surface.width): + offset = (y*surface.width + x)*4 + r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + outpixels[x, y] = r, g, b + outimage.save(filename, "PNG") + + +def test(dev): + ctx = dev.context_create() + + width = 256 + height = 256 + + # disabled blending/masking + blend = Blend() + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.colormask = PIPE_MASK_RGBA + ctx.set_blend(blend) + + # no-op depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.bypass_clipping = 1 + #rasterizer.bypass_vs = 1 + ctx.set_rasterizer(rasterizer) + + # viewport (identity, we setup vertices in wincoords) + viewport = Viewport() + scale = FloatArray(4) + scale[0] = 1.0 + scale[1] = 1.0 + scale[2] = 1.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = 0.0 + translate[1] = 0.0 + translate[2] = 0.0 + translate[3] = 0.0 + viewport.translate = translate + ctx.set_viewport(viewport) + + # samplers + sampler = Sampler() + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # texture + texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) + ctx.set_sampler_texture(0, texture) + + # drawing dest + surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + fb = Framebuffer() + fb.width = surface.width + fb.height = surface.height + fb.num_cbufs = 1 + fb.set_cbuf(0, surface) + ctx.set_framebuffer(fb) + + # vertex shader + # vs = Shader() + #ctx.set_vertex_shader(vs) + + # fragment shader + #fs = Shader() + #ctx.set_fragment_shader(fs) + + if 0: + nverts = 4 + nattrs = 1 + vertices = FloatArray(n_verts * nattrs * 4) + + # init vertex data that doesn't change + for i in range(nverts): + for j in range(nattrs): + vertices[(i*nattrs +j)*4 + 0] = 0.0 + vertices[(i*nattrs +j)*4 + 1] = 0.0 + vertices[(i*nattrs +j)*4 + 2] = 0.0 + vertices[(i*nattrs +j)*4 + 3] = 0.0 + + ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, + 4, # verts + 2, # attribs/vert + vertices) + else: + ctx.draw_quad(32.0, 32.0, 224.0, 224.0) + + ctx.flush() + + save_image("simple.png", surface) + + + +def main(): + dev = Device(0) + test(dev) + + +if __name__ == '__main__': + main() diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c new file mode 100644 index 00000000000..430a7af1765 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.c @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_inlines.h" +#include "cso_cache/cso_context.h" +#include "util/u_simple_shaders.h" +#include "st_device.h" +#include "st_winsys.h" + + +static void +st_device_really_destroy(struct st_device *st_dev) +{ + if(st_dev->screen) + st_dev->st_ws->screen_destroy(st_dev->screen); + + FREE(st_dev); +} + + +void +st_device_destroy(struct st_device *st_dev) +{ + if(!--st_dev->refcount) + st_device_really_destroy(st_dev); +} + + +static struct st_device * +st_device_create_from_st_winsys(const struct st_winsys *st_ws) +{ + struct st_device *st_dev; + + if(!st_ws->screen_create || + !st_ws->screen_destroy || + !st_ws->context_create || + !st_ws->context_destroy) + return NULL; + + st_dev = CALLOC_STRUCT(st_device); + if(!st_dev) + return NULL; + + st_dev->st_ws = st_ws; + + st_dev->screen = st_ws->screen_create(); + if(!st_dev->screen) + st_device_destroy(st_dev); + + return st_dev; +} + + +struct st_device * +st_device_create(boolean hardware) { +#if 0 + if(hardware) + return st_device_create_from_st_winsys(&st_hardware_winsys); + else +#endif + return st_device_create_from_st_winsys(&st_software_winsys); +} + + +void +st_context_destroy(struct st_context *st_ctx) +{ + unsigned i; + + if(st_ctx) { + struct st_device *st_dev = st_ctx->st_dev; + + if(st_ctx->vs) { + st_ctx->pipe->bind_vs_state(st_ctx->pipe, NULL); + st_ctx->pipe->delete_vs_state(st_ctx->pipe, st_ctx->vs); + } + + if(st_ctx->fs) { + st_ctx->pipe->bind_fs_state(st_ctx->pipe, NULL); + st_ctx->pipe->delete_fs_state(st_ctx->pipe, st_ctx->fs); + } + + if(st_ctx->cso) + cso_destroy_context(st_ctx->cso); + + if(st_ctx->pipe) + st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe); + + for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) + pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); + + FREE(st_ctx); + + if(!--st_dev->refcount) + st_device_really_destroy(st_dev); + } +} + + +struct st_context * +st_context_create(struct st_device *st_dev) +{ + struct st_context *st_ctx; + + st_ctx = CALLOC_STRUCT(st_context); + if(!st_ctx) + return NULL; + + st_ctx->st_dev = st_dev; + ++st_dev->refcount; + + st_ctx->pipe = st_dev->st_ws->context_create(st_dev->screen); + if(!st_ctx->pipe) + st_context_destroy(st_ctx); + + st_ctx->cso = cso_create_context(st_ctx->pipe); + if(!st_ctx->cso) + st_context_destroy(st_ctx); + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + st_ctx->vs = util_make_vertex_passthrough_shader(st_ctx->pipe, + 2, + semantic_names, + semantic_indexes, + &st_ctx->vert_shader); + } + + /* fragment shader */ + st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, + &st_ctx->frag_shader); + + st_ctx->pipe->bind_fs_state(st_ctx->pipe, st_ctx->fs); + st_ctx->pipe->bind_vs_state(st_ctx->pipe, st_ctx->vs); + + return st_ctx; +} diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h new file mode 100644 index 00000000000..46db20acd76 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.h @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_DEVICE_H_ +#define ST_DEVICE_H_ + + +#include "pipe/p_state.h" + +struct cso_context; +struct pipe_screen; +struct pipe_context; +struct st_winsys; + + +struct st_context { + struct st_device *st_dev; + + struct pipe_context *pipe; + + struct cso_context *cso; + + struct pipe_shader_state vert_shader; + struct pipe_shader_state frag_shader; + + void *vs; + void *fs; + + struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS]; + struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; +}; + + +struct st_device { + const struct st_winsys *st_ws; + + struct pipe_screen *screen; + + /* FIXME: we also need to refcount for textures and surfaces... */ + unsigned refcount; +}; + + +struct st_context * +st_context_create(struct st_device *st_dev); + +void +st_context_destroy(struct st_context *st_ctx); + +struct st_device * +st_device_create(boolean hardware); + +void +st_device_destroy(struct st_device *st_dev); + + +#endif /* ST_DEVICE_H_ */ diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c new file mode 100644 index 00000000000..964d60de1d8 --- /dev/null +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -0,0 +1,321 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Softpipe support. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "softpipe/sp_winsys.h" +#include "st_winsys.h" + + +struct st_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = st_softpipe_buf->data; + return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct st_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(st_softpipe_buffer); + if(!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static int +st_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); + if(!surf->buffer) + return -1; + + return 0; +} + + +static struct pipe_surface * +st_softpipe_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(winsys); + + surface->refcount = 1; + surface->winsys = winsys; + + return surface; +} + + +static void +st_softpipe_surface_release(struct pipe_winsys *winsys, + struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +st_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +st_softpipe_screen_destroy(struct pipe_screen *screen) +{ + struct pipe_winsys *winsys = screen->winsys; + + screen->destroy(screen); + + FREE(winsys); +} + + +static struct pipe_screen * +st_softpipe_screen_create(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->buffer_create = st_softpipe_buffer_create; + winsys->user_buffer_create = st_softpipe_user_buffer_create; + winsys->buffer_map = st_softpipe_buffer_map; + winsys->buffer_unmap = st_softpipe_buffer_unmap; + winsys->buffer_destroy = st_softpipe_buffer_destroy; + + winsys->surface_alloc = st_softpipe_surface_alloc; + winsys->surface_alloc_storage = st_softpipe_surface_alloc_storage; + winsys->surface_release = st_softpipe_surface_release; + + winsys->fence_reference = st_softpipe_fence_reference; + winsys->fence_signalled = st_softpipe_fence_signalled; + winsys->fence_finish = st_softpipe_fence_finish; + + winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; + winsys->get_name = st_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + FREE(winsys); + + return screen; +} + + +static void +st_softpipe_context_destroy(struct pipe_context *pipe) +{ + pipe->destroy(pipe); +} + + +static struct pipe_context * +st_softpipe_context_create(struct pipe_screen *screen) +{ + return softpipe_create(screen, screen->winsys, NULL); +} + + +const struct st_winsys st_software_winsys = { + &st_softpipe_screen_create, + &st_softpipe_screen_destroy, + &st_softpipe_context_create, + &st_softpipe_context_destroy +}; diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h new file mode 100644 index 00000000000..992fc9ab4ba --- /dev/null +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_WINSYS_H_ +#define ST_WINSYS_H_ + + +struct pipe_screen; +struct pipe_context; + + +struct st_winsys +{ + struct pipe_screen * + (*screen_create)(void); + + void + (*screen_destroy)(struct pipe_screen *screen); + + struct pipe_context * + (*context_create)(struct pipe_screen *screen); + + void + (*context_destroy)(struct pipe_context *pipe); +}; + + +extern const struct st_winsys st_software_winsys; + +extern const struct st_winsys st_hardware_winsys; + + +#endif /* ST_WINSYS_H_ */ diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 07abfa53f38..80e817b8082 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -79,17 +79,25 @@ SHARED_INCLUDES = \ ##### TARGETS ##### -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/bin/mklib -noprefix -o $@ \ $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) +$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ + -linker "$(CC)" \ + -noprefix \ + $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ + --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) +$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) + $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) rm -f depend diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 5b51f0815d5..e0716ea28ea 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -3,6 +3,7 @@ TOP = ../../../../.. include $(TOP)/configs/current LIBNAME = i915_dri.so +LIBNAME_EGL = egl_i915_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 708a58b781f..829732eea8b 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -350,6 +350,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, /* API-dependent context creation */ switch (ctx->Base.ClientAPI) { + case EGL_OPENVG_API: case EGL_OPENGL_ES_API: _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n", ctx->Base.ClientVersion); diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 21e07c19355..e637c96ac9b 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -64,6 +64,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static __DRIdriver *Drivers = NULL; +/** If non-zero, prefer an "egl_foo_dri.so" driver over "foo_dri.so" */ +static int PreferEGL = 0; + + +/** + * This may be called by libEGL.so to tell libGL to prefer "egl_" drivers + * over regular DRI drivers". + */ +void __glXPreferEGL(int state) +{ + PreferEGL = state; +} + + /* * printf wrappers */ @@ -161,6 +175,33 @@ ExtractDir(int index, const char *paths, int dirLen, char *dir) /** + * Try to dlopen() a driver. + * \param libDir the directory to search + * \param driverName the name of the driver (such as "r300"). + * \param tls if true, try to find TLS version of driver + * \param preferEGL if true, try to find EGL-specific driver + * \return handle from dlopen(), will be NULL if fails. + */ +static void * +try_open(const char *libDir, const char *driverName, + GLboolean tls, GLboolean preferEGL) +{ + const char *tlsDir = tls ? "/tls/" : ""; + const char *eglPrefix = preferEGL ? "egl_" : ""; + char fullPathName[200]; + void *handle = NULL; + + snprintf(fullPathName, 200, "%s%s/%s%s_dri.so", + libDir, tlsDir, eglPrefix, driverName); + InfoMessageF("OpenDriver: trying %s\n", fullPathName); + handle = dlopen(fullPathName, RTLD_NOW | RTLD_GLOBAL); + + return handle; +} + + + +/** * Versioned name of the expected \c __driCreateNewScreen function. * * The version of the last incompatible loader/driver inteface change is @@ -214,24 +255,16 @@ static __DRIdriver *OpenDriver(const char *driverName) libPaths = DEFAULT_DRIVER_DIR; for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) { - char realDriverName[200]; void *handle = NULL; - - /* If TLS support is enabled, try to open the TLS version of the driver - * binary first. If that fails, try the non-TLS version. - */ + if (PreferEGL) + handle = try_open(libDir, driverName, GL_FALSE, GL_TRUE); #ifdef GLX_USE_TLS - snprintf(realDriverName, 200, "%s/tls/%s_dri.so", libDir, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); + if (!handle) + handle = try_open(libDir, driverName, GL_TRUE, GL_FALSE); #endif - - if ( handle == NULL ) { - snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); - } + if (!handle) + handle = try_open(libDir, driverName, GL_FALSE, GL_FALSE); if ( handle != NULL ) { /* allocate __DRIdriver struct */ @@ -268,7 +301,8 @@ static __DRIdriver *OpenDriver(const char *driverName) break; } else { - ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); + ErrorMessageF("Unable to find/open driver for %s (%s)\n", + driverName, dlerror()); } } @@ -402,7 +436,7 @@ static void driDestroyDisplay(Display *dpy, void *private) else Drivers = driver->next; - Xfree(driver->name); + Xfree((void *) driver->name); Xfree(driver); break; } diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 03e44e5d048..f9d076f56f8 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -541,6 +541,8 @@ extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint, /* Initialize the GLX extension for dpy */ extern __GLXdisplayPrivate *__glXInitialize(Display*); +extern void __glXPreferEGL(int state); + /************************************************************************/ extern int __glXDebug; diff --git a/src/mesa/drivers/x11/xm_surface.c b/src/mesa/drivers/x11/xm_surface.c index 81616b92d96..a3f2fe7d685 100644 --- a/src/mesa/drivers/x11/xm_surface.c +++ b/src/mesa/drivers/x11/xm_surface.c @@ -106,7 +106,7 @@ xmesa_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, } else { /* other softpipe surface */ - softpipe_get_tile_rgba(pipe, ps, x, y, w, h, p); + softpipe_get_tile_rgba(ps, x, y, w, h, p); } } @@ -142,7 +142,7 @@ xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, } else { /* other softpipe surface */ - softpipe_put_tile_rgba(pipe, ps, x, y, w, h, p); + softpipe_put_tile_rgba(ps, x, y, w, h, p); } } diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 2283905662f..c0e8c6bf33e 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -73,7 +73,7 @@ acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, acc_ps->block.width = 1; acc_ps->block.height = 1; - pipe_get_tile_rgba(pipe, acc_ps, x, y, w, h, p); + pipe_get_tile_rgba(acc_ps, x, y, w, h, p); acc_ps->format = f; acc_ps->block = b; @@ -97,7 +97,7 @@ acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, acc_ps->block.width = 1; acc_ps->block.height = 1; - pipe_put_tile_rgba(pipe, acc_ps, x, y, w, h, p); + pipe_put_tile_rgba(acc_ps, x, y, w, h, p); acc_ps->format = f; acc_ps->block = b; @@ -208,7 +208,7 @@ accum_accum(struct pipe_context *pipe, GLfloat value, colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, colorBuf); + pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, colorBuf); acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); for (i = 0; i < 4 * width * height; i++) { @@ -243,7 +243,7 @@ accum_load(struct pipe_context *pipe, GLfloat value, buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, buf); + pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, buf); for (i = 0; i < 4 * width * height; i++) { buf[i] = buf[i] * value; @@ -283,7 +283,7 @@ accum_return(GLcontext *ctx, GLfloat value, if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, cbuf); + pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, cbuf); } for (i = 0; i < width * height; i++) { @@ -298,7 +298,7 @@ accum_return(GLcontext *ctx, GLfloat value, } } - pipe_put_tile_rgba(pipe, color_surf, xpos, ypos, width, height, abuf); + pipe_put_tile_rgba(color_surf, xpos, ypos, width, height, abuf); free(abuf); if (cbuf) diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index a7781f3ab2a..6b0137dcf87 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -1049,16 +1049,16 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* alternate path using get/put_tile() */ GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf); - pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf); + pipe_get_tile_rgba(psRead, srcx, srcy, width, height, buf); + pipe_put_tile_rgba(psTex, 0, 0, width, height, buf); free(buf); } else { /* GL_DEPTH */ GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); - pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf); - pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf); + pipe_get_tile_z(psRead, srcx, srcy, width, height, buf); + pipe_put_tile_z(psTex, 0, 0, width, height, buf); free(buf); } pipe_surface_reference(&psRead, NULL); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 11ba5d56f30..ea0fa20012e 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -144,9 +144,11 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) } if (stvp->draw_shader) { +#if FEATURE_feedback || FEATURE_drawpix /* this would only have been allocated for the RasterPos path */ draw_delete_vertex_shader(st->draw, stvp->draw_shader); stvp->draw_shader = NULL; +#endif } if (stvp->state.tokens) { @@ -232,9 +234,11 @@ static void st_program_string_notify( GLcontext *ctx, } if (stvp->draw_shader) { +#if FEATURE_feedback || FEATURE_drawpix /* this would only have been allocated for the RasterPos path */ draw_delete_vertex_shader(st->draw, stvp->draw_shader); stvp->draw_shader = NULL; +#endif } if (stvp->state.tokens) { diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 09d9c29e446..eb71779cc9f 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -262,7 +262,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLuint ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / ((1 << 24) - 1); - pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); @@ -276,7 +276,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* untested, but simple: */ assert(format == GL_DEPTH_STENCIL_EXT); for (i = 0; i < height; i++) { - pipe_get_tile_raw(pipe, surf, x, y, width, 1, dst, 0); + pipe_get_tile_raw(surf, x, y, width, 1, dst, 0); y += yStep; dst += dstStride; } @@ -287,7 +287,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLushort ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffff; - pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -302,7 +302,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLuint ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffffffff; - pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -316,7 +316,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* RGBA format */ /* Do a row at a time to flip image data vertically */ for (i = 0; i < height; i++) { - pipe_get_tile_rgba(pipe, surf, x, y, width, 1, df); + pipe_get_tile_rgba(surf, x, y, width, 1, df); y += yStep; df += dfStride; if (!dfStride) { diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b9aa513d723..73f8b8f7880 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1100,25 +1100,25 @@ fallback_copy_texsubimage(GLcontext *ctx, for (row = 0; row < height; row++, srcY++, destY += yStep) { uint data[MAX_WIDTH]; - pipe_get_tile_z(pipe, src_surf, srcX, srcY, width, 1, data); + pipe_get_tile_z(src_surf, srcX, srcY, width, 1, data); if (scaleOrBias) { _mesa_scale_and_bias_depth_uint(ctx, width, data); } - pipe_put_tile_z(pipe, dest_surf, destX, destY, width, 1, data); + pipe_put_tile_z(dest_surf, destX, destY, width, 1, data); } } else { /* RGBA format */ for (row = 0; row < height; row++, srcY++, destY += yStep) { float data[4 * MAX_WIDTH]; - pipe_get_tile_rgba(pipe, src_surf, srcX, srcY, width, 1, data); + pipe_get_tile_rgba(src_surf, srcX, srcY, width, 1, data); /* XXX we're ignoring convolution for now */ if (ctx->_ImageTransferState) { _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT, width, (GLfloat (*)[4]) data); } - pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data); + pipe_put_tile_rgba(dest_surf, destX, destY, width, 1, data); } } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index bf78cacb8ea..8b30e35684b 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -98,6 +98,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) /* state tracker needs the VBO module */ _vbo_CreateContext(ctx); +#if FEATURE_feedback || FEATURE_drawpix st->draw = draw_create(); /* for selection/feedback */ /* Disable draw options that might convert points/lines to tris, etc. @@ -107,6 +108,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) draw_wide_point_threshold(st->draw, 1000.0f); draw_enable_line_stipple(st->draw, FALSE); draw_enable_point_sprites(st->draw, FALSE); +#endif st->dirty.mesa = ~0; st->dirty.st = ~0; @@ -164,7 +166,9 @@ static void st_destroy_context_priv( struct st_context *st ) { uint i; +#if FEATURE_feedback || FEATURE_drawpix draw_destroy(st->draw); +#endif st_destroy_atoms( st ); st_destroy_draw( st ); st_destroy_generate_mipmap(st); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index a57d7b6a7aa..30c2bdb723f 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -447,6 +447,7 @@ st_draw_vbo(GLcontext *ctx, } +#if FEATURE_feedback || FEATURE_drawpix /** * Set the (private) draw module's post-transformed vertex format when in @@ -657,6 +658,7 @@ st_feedback_draw_vbo(GLcontext *ctx, } } +#endif /* FEATURE_feedback || FEATURE_drawpix */ void st_init_draw( struct st_context *st ) |