diff options
156 files changed, 5462 insertions, 1879 deletions
diff --git a/SConstruct b/SConstruct index 89144f7579d..4a0fb94debc 100644 --- a/SConstruct +++ b/SConstruct @@ -32,10 +32,10 @@ import common default_statetrackers = 'mesa' if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_drivers = 'softpipe,failover,i915simple,trace' + default_drivers = 'softpipe,failover,i915simple,trace,identity' default_winsys = 'xlib' elif common.default_platform in ('winddk',): - default_drivers = 'softpipe,i915simple,trace' + default_drivers = 'softpipe,i915simple,trace,identity' default_winsys = 'all' else: default_drivers = 'all' @@ -46,7 +46,7 @@ common.AddOptions(opts) opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python'])) opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, - ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300'])) + ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity'])) opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi', 'radeon'])) diff --git a/configs/darwin b/configs/darwin index 29fa0f13ff4..213c397287e 100644 --- a/configs/darwin +++ b/configs/darwin @@ -10,7 +10,7 @@ X11_DIR = $(INSTALL_DIR) # Compiler and flags CC = gcc -CXX = gcc +CXX = g++ PIC_FLAGS = -fPIC DEFINES = -D_DARWIN_C_SOURCE -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L \ -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -DPTHREADS \ diff --git a/configs/default b/configs/default index dc28be37ddf..a8996702d70 100644 --- a/configs/default +++ b/configs/default @@ -95,7 +95,7 @@ EGL_DRIVERS_DIRS = demo GALLIUM_DIRS = auxiliary drivers state_trackers GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVERS_DIRS = softpipe i915simple failover trace +GALLIUM_DRIVERS_DIRS = softpipe i915simple failover trace identity GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib egl_xlib GALLIUM_WINSYS_DRM_DIRS = diff --git a/configure.ac b/configure.ac index f34a4740b31..6db237c7938 100644 --- a/configure.ac +++ b/configure.ac @@ -417,7 +417,7 @@ GALLIUM_DIRS="auxiliary drivers state_trackers" GALLIUM_WINSYS_DIRS="" GALLIUM_WINSYS_DRM_DIRS="" GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices" -GALLIUM_DRIVERS_DIRS="softpipe failover trace" +GALLIUM_DRIVERS_DIRS="softpipe failover trace identity" GALLIUM_STATE_TRACKERS_DIRS="" case "$mesa_driver" in diff --git a/docs/devinfo.html b/docs/devinfo.html index 3cebf5f36db..0fb816749ed 100644 --- a/docs/devinfo.html +++ b/docs/devinfo.html @@ -123,20 +123,21 @@ These are the instructions for making a new Mesa release. <H3>Get latest source files</H3> <p> -Use "cvs update -dAP " to get the latest Mesa files from CVS. +Use git to get the latest Mesa files from the git repository, from whatever +branch is relevant. </p> <H3>Verify and update version info</H3> <p> -Create/edit the docs/RELNOTES-X.Y file to document what's new in the release. -Add the new RELNOTES-X.Y file to <a href="relnotes.html">relnotes.html</a>. -Update the docs/VERSIONS file too. +Create/edit the docs/relnotes-x.y.html file to document what's new in the release. +Add the new relnotes-x.y.html file to <a href="relnotes.html">relnotes.html</a>. </p> <p> -Edit the MESA_MAJOR, MESA_MINOR and MESA_TINY version numbers in +Update the MESA_MAJOR, MESA_MINOR and MESA_TINY version numbers in configs/default. +Also update the VERSION line in the top-level Makefile. </p> <p> @@ -144,27 +145,24 @@ Make sure the values in src/mesa/main/version.h are correct. </p> <p> -Edit the top-level Makefile and verify that DIRECTORY, LIB_NAME and -DEMO_NAME are correct. -</p> - -<p> Update the docs/news.html file and docs/download.html files. </p> <p> -Check in all updates to CVS. +Check in all updates to git. </p> <p> -Tag the CVS files with the release name (in the form <b>mesa_X_Y</b>). +Tag the files with the release name (in the form <b>mesa_X_Y</b>) +with: <code>git tag -a mesa_X_Y</code> +Then: <code>git push origin mesa_X_Y</code> </p> <H3>Make the tarballs</H3> <p> Make a symbolic link from $(DIRECTORY) to 'Mesa'. For example, -ln -s Mesa Mesa-6.3 +<code>ln -s Mesa Mesa-7.5</code> This is needed in order to make a correct tar file in the next step. </p> @@ -177,7 +175,7 @@ Make the distribution files. From inside the Mesa directory: <p> After the tarballs are created, the md5 checksums for the files will be computed. -Add them to the docs/news.html file. +Add them to the docs/relnotes-X.Y.html file. </p> <p> @@ -192,8 +190,20 @@ uploading the tarballs. </p> <p> +Basically, to upload the tarball files with: +<br> +<code> +rsync -avP ssh Mesa*-X.Y.* [email protected]:uploads/ +</code> +</p> + +<p> Update the web site by copying the docs/ directory's files to -/home/users/b/br/brianp/mesa-www/htdocs/ +/home/users/b/br/brianp/mesa-www/htdocs/ with: +<br> +<code> +sftp USERNAME,[email protected] +</code> </p> <p> diff --git a/docs/install.html b/docs/install.html index be61ef30433..953d2094d5b 100644 --- a/docs/install.html +++ b/docs/install.html @@ -21,6 +21,7 @@ <li><a href="#pkg-config">Building OpenGL programs with pkg-config </ul> <li><a href="#windows">Windows</a> +<li><a href="#scons">SCons</a> <li><a href="#other">Other</a> </ol> <br> @@ -328,13 +329,60 @@ For example, compiling and linking a GLUT application can be done with: <H2>2. Windows Compilation and Installation</H1> <p> -Please see the <a href="README.WIN32">README.WIN32</a> file. +Please see the <a href="#scons">instructions on building with SCons</a>. +Alternatively see <a href="README.WIN32">README.WIN32</a> file. </p> +<a name="scons"> +<H2>3. Building with SCons</H1> + +<p> +To build Mesa with SCons on Linux or Windows do +</p> +<pre> + scons +</pre> +<p> +The build output will be placed in +build/<i>platform</i>-<i>machine</i>-<i>debug</i>/..., where <i>platform</i> is for +example linux or windows, <i>machine</i> is x86 or x86_64, optionally followed +by -debug for debug builds. +</p> + +<p> +The sample programs are built seperately. To build them do +<pre> + scons -C progs +</pre> +And the build output will be placed in progs/build/... +</p> + +<p> +To build Mesa with SCons for Windows on Linux using the MinGW crosscompiler toolchain do +</p> +<pre> + scons platform=windows toolchain=crossmingw machine=x86 statetrackers=mesa drivers=softpipe,trace winsys=gdi + scons -C progs platform=windows toolchain=crossmingw machine=x86 -k +</pre> +<p> +This will create: +</p> +<ul> +<li>build/windows-x86-debug/gallium/winsys/gdi/opengl32.dll — Mesa + Gallium + softpipe, binary compatible with Windows's opengl32.dll +<li>build/windows-x86-debug/glut/glx/glut32.dll +<li>progs/build/windows-x86-debug/wgl/wglinfo.exe +<li>progs/build/windows-x86-debug/trivial/tri.exe +<li>and many other samples in progs/build/windows-x86-debug/... +</ul> +<p> +Put them all in the same directory to test them. +</p> + + <a name="other"> -<H2>3. Other systems</H1> +<H2>4. Other systems</H1> <p> Documentation for other environments (some may be very out of date): diff --git a/docs/news.html b/docs/news.html index 8cf2f91dd03..ee4a86c2a21 100644 --- a/docs/news.html +++ b/docs/news.html @@ -11,6 +11,21 @@ <H1>News</H1> +<h2>June 23, 2009</h2> +<p> +<a href="relnotes-7.4.4.html">Mesa 7.4.4</a> is released. +This is a stable release that fixes a regression in the i915/i965 drivers +that slipped into the 7.4.3 release. +</p> + + +<h2>June 19, 2009</h2> +<p> +<a href="relnotes-7.4.3.html">Mesa 7.4.3</a> is released. +This is a stable release fixing bugs since the 7.4.2 release. +</p> + + <h2>May 15, 2009</h2> <p> <a href="relnotes-7.4.2.html">Mesa 7.4.2</a> is released. diff --git a/docs/relnotes-7.4.3.html b/docs/relnotes-7.4.3.html new file mode 100644 index 00000000000..35b5dccbb0a --- /dev/null +++ b/docs/relnotes-7.4.3.html @@ -0,0 +1,79 @@ +<HTML> + +<TITLE>Mesa Release Notes</TITLE> + +<head><link rel="stylesheet" type="text/css" href="mesa.css"></head> + +<BODY> + +<body bgcolor="#eeeeee"> + +<H1>Mesa 7.4.3 Release Notes / 19 June 2009</H1> + +<p> +Mesa 7.4.3 is a stable development release fixing bugs since the 7.4.2 release. +</p> +<p> +Mesa 7.4.3 implements the OpenGL 2.1 API, but the version reported by +glGetString(GL_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 2.1. +</p> +<p> +See the <a href="install.html">Compiling/Installing page</a> for prerequisites +for DRI hardware acceleration. +</p> + + +<h2>MD5 checksums</h2> +<pre> +34c5a6c47ed51f31c4fa36e269831352 MesaLib-7.4.3.tar.gz +70a983ba3deaa8bd63b18bbab283f698 MesaLib-7.4.3.tar.bz2 +34f21b3205b271d575030aa98a2dda51 MesaLib-7.4.3.zip +56752b7adede212e6097afb10d0c0d59 MesaDemos-7.4.3.tar.gz +8ffa51c4833b1e298300a005e2d7ca2a MesaDemos-7.4.3.tar.bz2 +0037d24d41400d6fb9800ae55b8c863f MesaDemos-7.4.3.zip +20e24f6692c0c90e7e3b220f79c4108d MesaGLUT-7.4.3.tar.gz +03a4beeef74fc5ef0b1d6d04710e5a8a MesaGLUT-7.4.3.tar.bz2 +273788230adbdb9d57371309adedcf5f MesaGLUT-7.4.3.zip +</pre> + + +<h2>Bug fixes</h2> +<ul> +<li>Fixed texture object reference counting bug (bug 21756) +<li>Allow depth/stencil textures to be attached to GL_STENCIL_ATTACHMENT point + (SF bug 2793846) +<li>Added missing glGet case for GL_VERTEX_ARRAY_BINDING_APPLE +<li>Fixed some OSMesa build issues +<li>Fixed a vertex buffer object crash +<li>Fixed broken glTexImage3D() when image type = GL_BITMAP +<li>Fixed some GLSL preprocessor bugs +<li>Fixed framebuffer mem leak in i945/i965 DRI drivers +<li>Fixed texture coordinate repeat bug in swrast (bug 21872) +<li>Fixed incorrect viewport clamping (lower bound is zero, not one) +<li>GLX fix for glean's makeCurrent test case +</ul> + + + +<h2>Driver Status</h2> + +<pre> +Driver Status +---------------------- ---------------------- +DRI drivers varies with the driver +XMesa/GLX (on Xlib) implements OpenGL 2.1 +OSMesa (off-screen) implements OpenGL 2.1 +Windows/Win32 implements OpenGL 2.1 +Glide (3dfx Voodoo1/2) implements OpenGL 1.3 +SVGA unsupported +Wind River UGL unsupported +DJGPP unsupported +GGI unsupported +BeOS unsupported +Allegro unsupported +D3D unsupported +</pre> + +</body> +</html> diff --git a/docs/relnotes-7.4.4.html b/docs/relnotes-7.4.4.html new file mode 100644 index 00000000000..2a34568a7e4 --- /dev/null +++ b/docs/relnotes-7.4.4.html @@ -0,0 +1,68 @@ +<HTML> + +<TITLE>Mesa Release Notes</TITLE> + +<head><link rel="stylesheet" type="text/css" href="mesa.css"></head> + +<BODY> + +<body bgcolor="#eeeeee"> + +<H1>Mesa 7.4.4 Release Notes / 23 June 2009</H1> + +<p> +Mesa 7.4.4 is a stable development release fixing bugs since the 7.4.3 release. +</p> +<p> +Mesa 7.4.4 implements the OpenGL 2.1 API, but the version reported by +glGetString(GL_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 2.1. +</p> +<p> +See the <a href="install.html">Compiling/Installing page</a> for prerequisites +for DRI hardware acceleration. +</p> + + +<h2>MD5 checksums</h2> +<pre> +0b56fe5a88ab0c3c5b2da5068f63f416 MesaLib-7.4.4.tar.gz +b66528d314c574dccbe0ed963cac5e93 MesaLib-7.4.4.tar.bz2 +2818076f3ba23fa87fdfe4602a637a18 MesaLib-7.4.4.zip +3e77b208386c47b18165bce5ae317e2c MesaDemos-7.4.4.tar.gz +628142ec9a54cd28cc027e6ce26cff47 MesaDemos-7.4.4.tar.bz2 +d08a30d30ab7174859aa709cba6c726d MesaDemos-7.4.4.zip +e6e91ba16e274d40cf3a97ad3218af01 MesaGLUT-7.4.4.tar.gz +e14bbb52517e8121b31f1387515365ab MesaGLUT-7.4.4.tar.bz2 +f10ed20469753c2b3d68c99854f80fd4 MesaGLUT-7.4.4.zip +</pre> + + +<h2>Bug fixes</h2> +<ul> +<li>Fixed i965/i915 segfault in screen destruction (bug 22408) +</ul> + + + +<h2>Driver Status</h2> + +<pre> +Driver Status +---------------------- ---------------------- +DRI drivers varies with the driver +XMesa/GLX (on Xlib) implements OpenGL 2.1 +OSMesa (off-screen) implements OpenGL 2.1 +Windows/Win32 implements OpenGL 2.1 +Glide (3dfx Voodoo1/2) implements OpenGL 1.3 +SVGA unsupported +Wind River UGL unsupported +DJGPP unsupported +GGI unsupported +BeOS unsupported +Allegro unsupported +D3D unsupported +</pre> + +</body> +</html> diff --git a/docs/relnotes-7.5.html b/docs/relnotes-7.5.html index 663626cb05a..045692113df 100644 --- a/docs/relnotes-7.5.html +++ b/docs/relnotes-7.5.html @@ -68,6 +68,8 @@ including GL_ATI_separate_stencil, GL_EXT_stencil_two_side and OpenGL 2.0 <li>GL_EXT_texture_swizzle extension (software drivers, i965 driver) <li>Updated SPARC assembly optimizations (David S. Miller) <li>Initial support for separate compilation units in GLSL compiler. +<li>Increased max number of generic GLSL varying variables to 16 (formerly 8). +<li>GLSL linker now detects when too many varying variables are used. </ul> @@ -75,6 +77,7 @@ including GL_ATI_separate_stencil, GL_EXT_stencil_two_side and OpenGL 2.0 <ul> <li>Lots of i965 driver bug fixes <li>Fixed some GLSL preprocessor bugs +<li>GLSL: continue inside of a for-loop didn't work </ul> diff --git a/docs/relnotes.html b/docs/relnotes.html index ad5b74bad3c..35a4c7385f7 100644 --- a/docs/relnotes.html +++ b/docs/relnotes.html @@ -9,19 +9,14 @@ <H1>Release Notes</H1> <p> -Mesa uses an even/odd version number scheme like the Linux kernel. -Odd numbered versions (such as 6.5) designate new developmental releases. -Even numbered versions (such as 6.4) designate stable releases. -</p> - - -<p> The release notes summarize what's new or changed in each Mesa release. </p> <UL> <LI><A HREF="relnotes-7.6.html">7.6 release notes</A> <LI><A HREF="relnotes-7.5.html">7.5 release notes</A> +<LI><A HREF="relnotes-7.4.4.html">7.4.4 release notes</A> +<LI><A HREF="relnotes-7.4.3.html">7.4.3 release notes</A> <LI><A HREF="relnotes-7.4.2.html">7.4.2 release notes</A> <LI><A HREF="relnotes-7.4.1.html">7.4.1 release notes</A> <LI><A HREF="relnotes-7.4.html">7.4 release notes</A> diff --git a/include/GL/glew.h b/include/GL/glew.h index 2014092e877..7932a1ce199 100644 --- a/include/GL/glew.h +++ b/include/GL/glew.h @@ -2702,7 +2702,7 @@ typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURLAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); @@ -2723,7 +2723,7 @@ typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum targ #define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) #define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) #define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) -#define glFramebufferTexturLayer GLEW_GET_FUN(__glewFramebufferTexturLayer) +#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer) #define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) #define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) #define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) @@ -10563,7 +10563,7 @@ GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; -GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer; GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c index 26db42aed5e..1f9f2905759 100644 --- a/progs/demos/cubemap.c +++ b/progs/demos/cubemap.c @@ -52,6 +52,7 @@ static GLboolean NoClear = GL_FALSE; static GLint FrameParity = 0; static GLenum FilterIndex = 0; static GLint ClampIndex = 0; +static GLboolean supportFBO = GL_FALSE; static struct { @@ -403,6 +404,10 @@ static void init_checkers( void ) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (!supportFBO) + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); + + /* make colored checkerboard cube faces */ for (f = 0; f < 6; f++) { for (i = 0; i < CUBE_TEX_SIZE; i++) { @@ -426,7 +431,8 @@ static void init_checkers( void ) GL_BGRA, GL_UNSIGNED_BYTE, image); } - glGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP_ARB); + if (supportFBO) + glGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP_ARB); } @@ -503,10 +509,13 @@ static void init( GLboolean useImageFiles ) exit(0); } - /* Needed for glGenerateMipmapEXT + /* Needed for glGenerateMipmapEXT / auto mipmapping */ - if (!strstr(exten, "GL_EXT_framebuffer_object")) { - printf("Sorry, this demo requires GL_EXT_framebuffer_object\n"); + if (strstr(exten, "GL_EXT_framebuffer_object")) { + supportFBO = GL_TRUE; + } + else if (!strstr(exten, "GL_SGIS_generate_mipmap")) { + printf("Sorry, this demo requires GL_EXT_framebuffer_object or GL_SGIS_generate_mipmap\n"); exit(0); } } diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c index 41a13cc9f46..f0d76a4a06f 100644 --- a/progs/demos/fslight.c +++ b/progs/demos/fslight.c @@ -583,10 +583,14 @@ ParseOptions(int argc, char *argv[]) int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-fs") == 0) { - FragProgFile = argv[i+1]; + FragProgFile = argv[++i]; } else if (strcmp(argv[i], "-vs") == 0) { - VertProgFile = argv[i+1]; + VertProgFile = argv[++i]; + } + else { + fprintf(stderr, "unknown option %s\n", argv[i]); + break; } } } diff --git a/progs/tests/.gitignore b/progs/tests/.gitignore index d6a85387676..917c4f3e8d2 100644 --- a/progs/tests/.gitignore +++ b/progs/tests/.gitignore @@ -5,6 +5,7 @@ arbfpspec arbfptest1 arbfptexture arbfptrig +arbgpuprog arbnpot arbnpot-mipmap arbvptest1 @@ -38,6 +39,7 @@ fptest1 fptexture getprocaddress getproclist.h +getteximage glutfx interleave invert @@ -49,11 +51,13 @@ mapvbo minmag mipgen mipmap_comp +mipmap_comp_tests mipmap_limits mipmap_view multipal no_s3tc packedpixels +persp_hint pbo prog_parameter quads diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 46f5b1c3a22..f380ed4f547 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -61,6 +61,7 @@ SOURCES = \ minmag.c \ mipgen.c \ mipmap_comp.c \ + mipmap_comp_tests.c \ mipmap_limits.c \ mipmap_view.c \ multipal.c \ diff --git a/progs/tests/SConscript b/progs/tests/SConscript index 9e3a646f806..4c75246c30e 100644 --- a/progs/tests/SConscript +++ b/progs/tests/SConscript @@ -82,6 +82,7 @@ progs = [ 'minmag', 'mipgen', 'mipmap_comp', + 'mipmap_comp_tests', 'mipmap_limits', 'mipmap_view', 'multipal', diff --git a/progs/tests/mipmap_comp_tests.c b/progs/tests/mipmap_comp_tests.c new file mode 100644 index 00000000000..8f206253786 --- /dev/null +++ b/progs/tests/mipmap_comp_tests.c @@ -0,0 +1,313 @@ +/* Copyright (c) Mark J. Kilgard, 1994. */ +/* + * (c) Copyright 1993, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ + +/* mipmap_comp + * Test compressed texture mipmaps + * + * Based on mipmap_limits + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <GL/glew.h> +#include <GL/glut.h> + +#include "readtex.h" + +#define SIZE 16 /* not larger then 16 */ + +static GLint BaseLevel = 0, MaxLevel ; +static GLfloat MinLod, MaxLod; +static GLfloat LodBias; +static GLboolean NearestFilter; +static GLuint texImage; +static GLuint View; + +struct view { + GLfloat minLod; + GLfloat maxLod; + const char *string; +}; + +static struct view views[] = +{ + { 0, 0, "Green" }, + { 0, 1, "Green, Red" }, + { 0, 2, "Green, Red, Blue" }, + { 0, 3, "Green, Red, Blue, Black" }, + { 0, 4, "Green, Red, Blue, Black, White" }, + { 1, 4, "Red, Blue, Black, White" }, + { 2, 4, "Blue, Black, White" }, + { 3, 4, "Black, White" }, + { 4, 4, "White" }, + { 1, 3, "Red, Blue, Black" }, + { 1, 2, "Red, Blue" }, + { 2, 3, "Blue, Black" }, + { 0, 0, NULL }, +}; + +static void +initValues(void) +{ + View = 9; + BaseLevel = 0; + MaxLevel = 9; + MinLod = views[View].minLod; + MaxLod = views[View].maxLod; + LodBias = 5.0; + NearestFilter = GL_TRUE; +} + + +static void +changeView(void) +{ + if (views[++View].string == NULL) + View = 0; + + MinLod = views[View].minLod; + MaxLod = views[View].maxLod; +} + + +static void +makeImage(int level, int width, int height) +{ + GLubyte img[SIZE*SIZE*3]; + GLubyte color[5][3] = { + { 0, 255, 0 }, + { 255, 0, 0 }, + { 0, 0, 255 }, + { 0, 0, 0 }, + { 255, 255, 255 }, + }; + int i, j; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + int k = (i * width + j) * 3; + img[k + 0] = color[level][0]; + img[k + 1] = color[level][1]; + img[k + 2] = color[level][2]; + } + } + + glTexImage2D(GL_TEXTURE_2D, level, 3, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, img); +} + + +static void +makeImages(void) +{ + int i, sz; + + for (i = 0, sz = SIZE; sz >= 1; i++, sz /= 2) { + makeImage(i, sz, sz); + printf("Level %d size: %d x %d\n", i, sz, sz); + } +} + + +static void +myInit(void) +{ + + initValues(); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glShadeModel(GL_FLAT); + + glTranslatef(0.0, 0.0, -3.6); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &texImage); + glBindTexture(GL_TEXTURE_2D, texImage); + makeImages(); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + glEnable(GL_TEXTURE_2D); +} + + +static void +display(void) +{ + GLfloat tcm = 1.0; + glBindTexture(GL_TEXTURE_2D, texImage); + + printf("BASE_LEVEL=%d MAX_LEVEL=%d MIN_LOD=%.2g MAX_LOD=%.2g Bias=%.2g Filter=%s\n", + BaseLevel, MaxLevel, MinLod, MaxLod, LodBias, + NearestFilter ? "NEAREST" : "LINEAR"); + printf("You should see: %s\n", views[View].string ); + fflush(stdout); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, MinLod); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, MaxLod); + + if (NearestFilter) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST_MIPMAP_NEAREST); + } + else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + } + + glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, LodBias); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0); + glTexCoord2f(0.0, tcm); glVertex3f(-2.0, 1.0, 0.0); + glTexCoord2f(tcm * 3000.0, tcm); glVertex3f(3000.0, 1.0, -6000.0); + glTexCoord2f(tcm * 3000.0, 0.0); glVertex3f(3000.0, -1.0, -6000.0); + glEnd(); + glFlush(); +} + + +static void +myReshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30000.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +key(unsigned char k, int x, int y) +{ + (void) x; + (void) y; + switch (k) { +#if 0 + case 'b': + BaseLevel--; + if (BaseLevel < 0) + BaseLevel = 0; + break; + case 'B': + BaseLevel++; + if (BaseLevel > 10) + BaseLevel = 10; + break; + case 'm': + MaxLevel--; + if (MaxLevel < 0) + MaxLevel = 0; + break; + case 'M': + MaxLevel++; + if (MaxLevel > 10) + MaxLevel = 10; + break; + case 'l': + LodBias -= 0.25; + break; + case 'L': + LodBias += 0.25; + break; + case 'n': + MinLod -= 0.25; + break; + case 'N': + MinLod += 0.25; + break; + case 'x': + MaxLod -= 0.25; + break; + case 'X': + MaxLod += 0.25; + break; + case 'f': + NearestFilter = !NearestFilter; + break; +#endif + case ' ': + initValues(); + break; + case 27: /* Escape */ + exit(0); + break; + default: + changeView(); + break; + } + glutPostRedisplay(); +} + + +static void +usage(void) +{ + printf("usage:\n"); + printf(" Any Change view\n"); + printf(" SPACE reset values\n"); +} + + +int +main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize (600, 600); + glutCreateWindow (argv[0]); + glewInit(); + myInit(); + glutReshapeFunc (myReshape); + glutDisplayFunc(display); + glutKeyboardFunc(key); + usage(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/progs/wgl/sharedtex_mt/sharedtex_mt.c b/progs/wgl/sharedtex_mt/sharedtex_mt.c index 010eb873b85..779e15001db 100644 --- a/progs/wgl/sharedtex_mt/sharedtex_mt.c +++ b/progs/wgl/sharedtex_mt/sharedtex_mt.c @@ -50,6 +50,7 @@ struct window { float Angle; int Id; HGLRC sharedContext; + HANDLE hEventInitialised; }; @@ -414,6 +415,10 @@ threadRunner (void *arg) Error("Couldn't obtain HDC"); } + /* Wait for the previous thread */ + if(tia->id > 0) + WaitForSingleObject(Windows[tia->id - 1].hEventInitialised, INFINITE); + pfd.cColorBits = 24; pfd.cDepthBits = 24; pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; @@ -434,9 +439,16 @@ threadRunner (void *arg) } if (win->sharedContext) { - wglShareLists(win->sharedContext, win->Context); + if(!wglShareLists(win->sharedContext, win->Context)) + Error("Couldn't share WGL context lists"); } + SetEvent(win->hEventInitialised); + + /* Wait for all threads to initialize otherwise wglShareLists will fail */ + if(tia->id < NumWindows - 1) + WaitForSingleObject(Windows[NumWindows - 1].hEventInitialised, INFINITE); + SendMessage(win->Win, WM_SIZE, 0, 0); while (1) { @@ -511,20 +523,26 @@ main(int argc, char *argv[]) h[2] = AddWindow( 10, 350, gCtx); h[3] = AddWindow(330, 350, gCtx); - if (!wglMakeCurrent(gHDC, gCtx)) { - Error("wglMakeCurrent failed for init thread."); - return -1; + for (i = 0; i < NumWindows; i++) { + Windows[i].hEventInitialised = CreateEvent(NULL, TRUE, FALSE, NULL); } - InitGLstuff(); - for (i = 0; i < NumWindows; i++) { DWORD id; tia[i].id = i; threads[i] = CreateThread(NULL, 0, threadRunner, &tia[i], 0, &id); + + WaitForSingleObject(Windows[i].hEventInitialised, INFINITE); + } + + if (!wglMakeCurrent(gHDC, gCtx)) { + Error("wglMakeCurrent failed for init thread."); + return -1; } + InitGLstuff(); + while (1) { MSG msg; diff --git a/progs/wgl/wglthreads/wglthreads.c b/progs/wgl/wglthreads/wglthreads.c index 1a8219ccc94..27dca10f2a0 100644 --- a/progs/wgl/wglthreads/wglthreads.c +++ b/progs/wgl/wglthreads/wglthreads.c @@ -331,7 +331,9 @@ draw_loop(struct winthread *wt) if (Locking) EnterCriticalSection(&Mutex); + SwapBuffers(wt->hDC); + if (Locking) LeaveCriticalSection(&Mutex); @@ -443,7 +445,7 @@ create_window(struct winthread *wt, HGLRC shareCtx) win = CreateWindowEx(0, wc.lpszClassName, "wglthreads", - WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TILEDWINDOW, xpos, ypos, width, @@ -481,7 +483,8 @@ create_window(struct winthread *wt, HGLRC shareCtx) } if (shareCtx) { - wglShareLists(shareCtx, ctx); + if(!wglShareLists(shareCtx, ctx)) + Error("Couldn't share WGL context lists"); } /* save the info for this window/context */ @@ -504,10 +507,22 @@ ThreadProc(void *p) struct winthread *wt = (struct winthread *) p; HGLRC share; + /* Wait for the previous thread */ + if(Texture && wt->Index > 0) { + WaitForSingleObject(WinThreads[wt->Index - 1].hEventInitialised, INFINITE); + share = WinThreads[0].Context; + } + else + share = 0; + share = (Texture && wt->Index > 0) ? WinThreads[0].Context : 0; create_window(wt, share); SetEvent(wt->hEventInitialised); + /* Wait for all threads to initialize otherwise wglShareLists will fail */ + if(wt->Index < NumWinThreads - 1) + WaitForSingleObject(WinThreads[NumWinThreads - 1].hEventInitialised, INFINITE); + draw_loop(wt); return 0; } @@ -591,13 +606,17 @@ main(int argc, char *argv[]) printf("wglthreads: creating threads\n"); - /* Create the threads */ + /* Create the events */ for (i = 0; i < NumWinThreads; i++) { - DWORD id; - WinThreads[i].Index = i; WinThreads[i].hEventInitialised = CreateEvent(NULL, TRUE, FALSE, NULL); WinThreads[i].hEventRedraw = CreateEvent(NULL, FALSE, FALSE, NULL); + } + + /* Create the threads */ + for (i = 0; i < NumWinThreads; i++) { + DWORD id; + WinThreads[i].Thread = CreateThread(NULL, 0, ThreadProc, @@ -606,8 +625,6 @@ main(int argc, char *argv[]) &id); printf("wglthreads: Created thread %p\n", (void *) WinThreads[i].Thread); - WaitForSingleObject(WinThreads[i].hEventInitialised, INFINITE); - threads[i] = WinThreads[i].Thread; } diff --git a/progs/xdemos/glxcontexts.c b/progs/xdemos/glxcontexts.c index a97b62a9081..481749be3d8 100644 --- a/progs/xdemos/glxcontexts.c +++ b/progs/xdemos/glxcontexts.c @@ -20,16 +20,17 @@ */ /* - * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT) - * Port by Brian Paul 23 March 2001 + * Version of glxgears that creates/destroys the rendering context for each + * frame. Also periodically destroy/recreate the window. + * Good for finding memory leaks, etc. * * Command line options: * -info print GL implementation information - * -stereo use stereo enabled GLX visual * */ +#include <assert.h> #include <math.h> #include <stdlib.h> #include <stdio.h> @@ -92,13 +93,8 @@ static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; static GLint gear1, gear2, gear3; static GLfloat angle = 0.0; -static GLboolean fullscreen = GL_FALSE; /* Create a single fullscreen window */ -static GLboolean stereo = GL_FALSE; /* Enable stereo. */ -static GLfloat eyesep = 5.0; /* Eye separation. */ -static GLfloat fix_point = 40.0; /* Fixation point distance. */ -static GLfloat left, right, asp; /* Stereo frustum params. */ - - XVisualInfo *visinfo; +static XVisualInfo *visinfo = NULL; +static int WinWidth = 300, WinHeight = 300; /* @@ -272,22 +268,13 @@ do_draw(void) } - /* new window size or exposure */ static void reshape(int width, int height) { glViewport(0, 0, (GLint) width, (GLint) height); - if (stereo) { - GLfloat w; - - asp = (GLfloat) height / (GLfloat) width; - w = fix_point * (1.0 / 5.0); - - left = -5.0 * ((w - 0.5 * eyesep) / fix_point); - right = 5.0 * ((w + 0.5 * eyesep) / fix_point); - } else { + { GLfloat h = (GLfloat) height / (GLfloat) width; glMatrixMode(GL_PROJECTION); @@ -299,7 +286,6 @@ reshape(int width, int height) glLoadIdentity(); glTranslatef(0.0, 0.0, -40.0); } - static void @@ -337,7 +323,7 @@ init(void) glEnable(GL_NORMALIZE); } - + static void draw( Display *dpy, Window win ) @@ -354,36 +340,9 @@ draw( Display *dpy, Window win ) init(); - if (stereo) { - /* First left eye. */ - glDrawBuffer(GL_BACK_LEFT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(left, right, -asp, asp, 5.0, 60.0); + reshape(WinWidth, WinHeight); - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); - glTranslated(+0.5 * eyesep, 0.0, 0.0); - do_draw(); - glPopMatrix(); - - /* Then right eye. */ - glDrawBuffer(GL_BACK_RIGHT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-right, -left, -asp, asp, 5.0, 60.0); - - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); - glTranslated(-0.5 * eyesep, 0.0, 0.0); - do_draw(); - glPopMatrix(); - } else - do_draw(); + do_draw(); glDeleteLists(gear1, 1); glDeleteLists(gear2, 1); @@ -410,14 +369,6 @@ make_window( Display *dpy, const char *name, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; - int stereoAttribs[] = { GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_DOUBLEBUFFER, - GLX_DEPTH_SIZE, 1, - GLX_STEREO, - None }; int scrnum; XSetWindowAttributes attr; unsigned long mask; @@ -427,22 +378,9 @@ make_window( Display *dpy, const char *name, scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); - if (fullscreen) { - x = 0; y = 0; - width = DisplayWidth( dpy, scrnum ); - height = DisplayHeight( dpy, scrnum ); - } - - if (stereo) - visinfo = glXChooseVisual( dpy, scrnum, stereoAttribs ); - else - visinfo = glXChooseVisual( dpy, scrnum, attribs ); + visinfo = glXChooseVisual( dpy, scrnum, attribs ); if (!visinfo) { - if (stereo) { - printf("Error: couldn't get an RGB, " - "Double-buffered, Stereo visual\n"); - } else - printf("Error: couldn't get an RGB, Double-buffered visual\n"); + printf("Error: couldn't get an RGB, Double-buffered visual\n"); exit(1); } @@ -451,7 +389,7 @@ make_window( Display *dpy, const char *name, attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; - attr.override_redirect = fullscreen; + attr.override_redirect = 0; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect; win = XCreateWindow( dpy, root, x, y, width, height, @@ -479,10 +417,9 @@ static void event_loop(Display *dpy) { Window win; - make_window(dpy, "glxgears", 0, 0, 300, 300, &win); + make_window(dpy, "glxgears", 0, 0, WinWidth, WinHeight, &win); XMapWindow(dpy, win); - while (1) { while (XPending(dpy) > 0) { XEvent event; @@ -492,34 +429,35 @@ event_loop(Display *dpy) /* we'll redraw below */ break; case ConfigureNotify: - reshape(event.xconfigure.width, event.xconfigure.height); + WinWidth = event.xconfigure.width; + WinHeight = event.xconfigure.height; break; case KeyPress: - { - char buffer[10]; - int r, code; - code = XLookupKeysym(&event.xkey, 0); - if (code == XK_Left) { - view_roty += 5.0; - } - else if (code == XK_Right) { - view_roty -= 5.0; - } - else if (code == XK_Up) { - view_rotx += 5.0; - } - else if (code == XK_Down) { - view_rotx -= 5.0; - } - else { - r = XLookupString(&event.xkey, buffer, sizeof(buffer), - NULL, NULL); - if (buffer[0] == 27) { - /* escape */ - return; - } - } - } + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (code == XK_Left) { + view_roty += 5.0; + } + else if (code == XK_Right) { + view_roty -= 5.0; + } + else if (code == XK_Up) { + view_rotx += 5.0; + } + else if (code == XK_Down) { + view_rotx -= 5.0; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == 27) { + /* escape */ + return; + } + } + } } } @@ -550,9 +488,12 @@ event_loop(Display *dpy) printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds, fps); tRate0 = t; - + + /* Destroy window and create new one */ XDestroyWindow(dpy, win); - make_window(dpy, "glxgears", (int)(fps * 100) % 100, (int)(fps * 100) % 100, 300, 300, &win); + make_window(dpy, "glxgears", + (int)(fps * 100) % 100, (int)(fps * 100) % 100, /* x,y */ + WinWidth, WinHeight, &win); XMapWindow(dpy, win); frames = 0; @@ -562,7 +503,6 @@ event_loop(Display *dpy) } - int main(int argc, char *argv[]) { @@ -579,12 +519,6 @@ main(int argc, char *argv[]) else if (strcmp(argv[i], "-info") == 0) { printInfo = GL_TRUE; } - else if (strcmp(argv[i], "-stereo") == 0) { - stereo = GL_TRUE; - } - else if (strcmp(argv[i], "-fullscreen") == 0) { - fullscreen = GL_TRUE; - } else printf("Warrning: unknown parameter: %s\n", argv[i]); } @@ -596,7 +530,6 @@ main(int argc, char *argv[]) return -1; } - if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); @@ -604,7 +537,6 @@ main(int argc, char *argv[]) printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); } - event_loop(dpy); XCloseDisplay(dpy); diff --git a/scons/crossmingw.py b/scons/crossmingw.py index bf81f16fd64..3aed4843502 100644 --- a/scons/crossmingw.py +++ b/scons/crossmingw.py @@ -108,7 +108,7 @@ def shlib_emitter(target, source, env): return (target, source) -shlib_action = SCons.Action.Action(shlib_generator, generator=1) +shlib_action = SCons.Action.Action(shlib_generator, '$SHLINKCOMSTR', generator=1) res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') diff --git a/scons/dxsdk.py b/scons/dxsdk.py new file mode 100644 index 00000000000..a369e1da10c --- /dev/null +++ b/scons/dxsdk.py @@ -0,0 +1,66 @@ +"""dxsdk + +Tool-specific initialization for Microsoft DirectX SDK + +""" + +# +# Copyright (c) 2009 VMware, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os +import os.path + +import SCons.Errors +import SCons.Util + + +def get_dxsdk_root(env): + try: + return os.environ['DXSDK_DIR'] + except KeyError: + return None + +def get_dxsdk_paths(env): + dxsdk_root = get_dxsdk_root(env) + if dxsdk_root is None: + raise SCons.Errors.InternalError, "DirectX SDK not found" + + if env['machine'] in ('generic', 'x86'): + target_cpu = 'x86' + elif env['machine'] == 'x86_64': + target_cpu = 'x64' + else: + raise SCons.Errors.InternalError, "Unsupported target machine" + include_dir = 'Include' + + env.Append(CPPDEFINES = [('HAVE_DXSDK', '1')]) + env.Prepend(CPPPATH = [os.path.join(dxsdk_root, 'Include')]) + env.Prepend(LIBPATH = [os.path.join(dxsdk_root, 'Lib', target_cpu)]) + +def generate(env): + get_dxsdk_paths(env) + +def exists(env): + return get_dxsdk_root(env) is not None + +# vim:set ts=4 sw=4 et: diff --git a/scons/gallium.py b/scons/gallium.py index 6e924da303b..aed813f0279 100644 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -319,74 +319,78 @@ def generate(env): env.Append(CPPDEFINES = cppdefines) # C compiler options - cflags = [] + cflags = [] # C + cxxflags = [] # C++ + ccflags = [] # C & C++ if gcc: if debug: - cflags += ['-O0', '-g3'] + ccflags += ['-O0', '-g3'] elif env['toolchain'] == 'crossmingw': - cflags += ['-O0', '-g3'] # mingw 4.2.1 optimizer is broken + ccflags += ['-O0', '-g3'] # mingw 4.2.1 optimizer is broken else: - cflags += ['-O3', '-g3'] + ccflags += ['-O3', '-g3'] if env['profile']: - cflags += ['-pg'] + ccflags += ['-pg'] if env['machine'] == 'x86': - cflags += [ + ccflags += [ '-m32', #'-march=pentium4', '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics #'-mfpmath=sse', ] if env['machine'] == 'x86_64': - cflags += ['-m64'] + ccflags += ['-m64'] # See also: # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html - cflags += [ - '-Werror=declaration-after-statement', + ccflags += [ '-Wall', - '-Wmissing-prototypes', '-Wmissing-field-initializers', '-Wpointer-arith', '-Wno-long-long', '-ffast-math', - '-std=gnu99', '-fmessage-length=0', # be nice to Eclipse ] + cflags += [ + '-Werror=declaration-after-statement', + '-Wmissing-prototypes', + '-std=gnu99', + ] if msvc: # See also: # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx # - cl /? if debug: - cflags += [ + ccflags += [ '/Od', # disable optimizations '/Oi', # enable intrinsic functions '/Oy-', # disable frame pointer omission '/GL-', # disable whole program optimization ] else: - cflags += [ + ccflags += [ '/O2', # optimize for speed #'/fp:fast', # fast floating point ] if env['profile']: - cflags += [ + ccflags += [ '/Gh', # enable _penter hook function '/GH', # enable _pexit hook function ] - cflags += [ + ccflags += [ '/W3', # warning level #'/Wp64', # enable 64 bit porting warnings ] if env['machine'] == 'x86': - cflags += [ + ccflags += [ #'/QIfist', # Suppress _ftol #'/arch:SSE2', # use the SSE2 instructions ] if platform == 'windows': - cflags += [ + ccflags += [ # TODO ] if platform == 'winddk': - cflags += [ + ccflags += [ '/Zl', # omit default library name in .OBJ '/Zp8', # 8bytes struct member alignment '/Gy', # separate functions for linker @@ -405,7 +409,7 @@ def generate(env): ] if platform == 'wince': # See also C:\WINCE600\public\common\oak\misc\makefile.def - cflags += [ + ccflags += [ '/Zl', # omit default library name in .OBJ '/GF', # enable read-only string pooling '/GR-', # disable C++ RTTI @@ -422,8 +426,9 @@ def generate(env): # See http://scons.tigris.org/issues/show_bug.cgi?id=1656 env.EnsureSConsVersion(0, 98, 0) env['PDB'] = '${TARGET.base}.pdb' + env.Append(CCFLAGS = ccflags) env.Append(CFLAGS = cflags) - env.Append(CXXFLAGS = cflags) + env.Append(CXXFLAGS = cxxflags) if env['platform'] == 'windows' and msvc: # Choose the appropriate MSVC CRT diff --git a/scons/generic.py b/scons/generic.py index 29ddf76d6ff..a9c2244a74f 100644 --- a/scons/generic.py +++ b/scons/generic.py @@ -416,16 +416,18 @@ def generate(env): # See also: # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html ccflags += [ - '-Werror=declaration-after-statement', '-Wall', - '-Wmissing-prototypes', '-Wmissing-field-initializers', '-Wpointer-arith', '-Wno-long-long', '-ffast-math', - '-std=gnu99', '-fmessage-length=0', # be nice to Eclipse ] + cflags += [ + '-Werror=declaration-after-statement', + '-Wmissing-prototypes', + '-std=gnu99', + ] if msvc: # See also: # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index b7780fb5073..88f4d9f495a 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -54,7 +54,8 @@ static unsigned elt_ubyte( const void *elts, unsigned idx ) static unsigned elt_vert( const void *elts, unsigned idx ) { - return (const ubyte *)elts - (const ubyte *)NULL + idx; + /* unsigned index is packed in the pointer */ + return (unsigned)(uintptr_t)elts + idx; } pt_elt_func draw_pt_elt_func( struct draw_context *draw ) diff --git a/src/gallium/auxiliary/indices/u_indices.c b/src/gallium/auxiliary/indices/u_indices.c index 0cf7d88653c..03d7453f303 100644 --- a/src/gallium/auxiliary/indices/u_indices.c +++ b/src/gallium/auxiliary/indices/u_indices.c @@ -244,7 +244,7 @@ int u_index_generator( unsigned hw_mask, default: assert(0); - *out_generate = generate[out_idx][in_pv][out_pv][prim]; + *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS]; *out_prim = PIPE_PRIM_POINTS; *out_nr = nr; return U_TRANSLATE_ERROR; diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 92b6fd00564..2590546cb4a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -72,6 +72,12 @@ struct pb_desc /** + * Size. Regular (32bit) unsigned for now. + */ +typedef unsigned pb_size; + + +/** * Base class for all pb_* buffers. */ struct pb_buffer @@ -126,7 +132,7 @@ struct pb_vtbl */ void (*get_base_buffer)( struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset ); + pb_size *offset ); }; @@ -177,7 +183,7 @@ pb_unmap(struct pb_buffer *buf) static INLINE void pb_get_base_buffer( struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset ) + pb_size *offset ) { assert(buf); if(!buf) { @@ -241,7 +247,7 @@ pb_reference(struct pb_buffer **dst, * the requested or not. */ static INLINE boolean -pb_check_alignment(size_t requested, size_t provided) +pb_check_alignment(pb_size requested, pb_size provided) { if(!requested) return TRUE; @@ -269,7 +275,7 @@ pb_check_usage(unsigned requested, unsigned provided) * hardware. */ struct pb_buffer * -pb_malloc_buffer_create(size_t size, +pb_malloc_buffer_create(pb_size size, const struct pb_desc *desc); diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 4698efa69cf..109ac7c9d63 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -65,11 +65,11 @@ struct fenced_buffer_list struct pb_fence_ops *ops; - size_t numDelayed; + pb_size numDelayed; struct list_head delayed; #ifdef DEBUG - size_t numUnfenced; + pb_size numUnfenced; struct list_head unfenced; #endif }; @@ -433,7 +433,7 @@ fenced_buffer_fence(struct pb_buffer *buf, static void fenced_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); pb_get_base_buffer(fenced_buf->buffer, base_buf, offset); diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index 689fd74771f..0760d607161 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -102,7 +102,7 @@ malloc_buffer_fence(struct pb_buffer *buf, static void malloc_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { *base_buf = buf; *offset = 0; @@ -121,7 +121,7 @@ malloc_buffer_vtbl = { struct pb_buffer * -pb_malloc_buffer_create(size_t size, +pb_malloc_buffer_create(pb_size size, const struct pb_desc *desc) { struct malloc_buffer *buf; @@ -150,7 +150,7 @@ pb_malloc_buffer_create(size_t size, static struct pb_buffer * pb_malloc_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { return pb_malloc_buffer_create(size, desc); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 74077f82774..39ab8e722c1 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -73,7 +73,7 @@ struct pb_manager struct pb_buffer * (*create_buffer)( struct pb_manager *mgr, - size_t size, + pb_size size, const struct pb_desc *desc); /** @@ -106,7 +106,7 @@ pb_malloc_bufmgr_create(void); */ struct pb_manager * pool_bufmgr_create(struct pb_manager *provider, - size_t n, size_t size, + pb_size n, pb_size size, const struct pb_desc *desc); @@ -119,7 +119,7 @@ pool_bufmgr_create(struct pb_manager *provider, */ struct pb_manager * mm_bufmgr_create(struct pb_manager *provider, - size_t size, size_t align2); + pb_size size, pb_size align2); /** * Same as mm_bufmgr_create. @@ -128,7 +128,7 @@ mm_bufmgr_create(struct pb_manager *provider, */ struct pb_manager * mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, - size_t size, size_t align2); + pb_size size, pb_size align2); /** @@ -136,8 +136,8 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, */ struct pb_manager * pb_slab_manager_create(struct pb_manager *provider, - size_t bufSize, - size_t slabSize, + pb_size bufSize, + pb_size slabSize, const struct pb_desc *desc); /** @@ -146,9 +146,9 @@ pb_slab_manager_create(struct pb_manager *provider, */ struct pb_manager * pb_slab_range_manager_create(struct pb_manager *provider, - size_t minBufSize, - size_t maxBufSize, - size_t slabSize, + pb_size minBufSize, + pb_size maxBufSize, + pb_size slabSize, const struct pb_desc *desc); @@ -204,7 +204,7 @@ pb_ondemand_manager_create(struct pb_manager *provider); */ struct pb_manager * pb_debug_manager_create(struct pb_manager *provider, - size_t underflow_size, size_t overflow_size); + pb_size underflow_size, pb_size overflow_size); #ifdef __cplusplus diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c index db67d46c561..f60c836f18b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c @@ -60,7 +60,7 @@ pb_alt_manager(struct pb_manager *mgr) static struct pb_buffer * pb_alt_manager_create_buffer(struct pb_manager *_mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pb_alt_manager *mgr = pb_alt_manager(_mgr); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 35358430b43..57d1ede45a4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -81,7 +81,7 @@ struct pb_cache_manager pipe_mutex mutex; struct list_head delayed; - size_t numDelayed; + pb_size numDelayed; }; @@ -204,7 +204,7 @@ pb_cache_buffer_fence(struct pb_buffer *_buf, static void pb_cache_buffer_get_base_buffer(struct pb_buffer *_buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct pb_cache_buffer *buf = pb_cache_buffer(_buf); pb_get_base_buffer(buf->buffer, base_buf, offset); @@ -224,7 +224,7 @@ pb_cache_buffer_vtbl = { static INLINE boolean pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, - size_t size, + pb_size size, const struct pb_desc *desc) { if(buf->base.base.size < size) @@ -246,7 +246,7 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, static struct pb_buffer * pb_cache_manager_create_buffer(struct pb_manager *_mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pb_cache_manager *mgr = pb_cache_manager(_mgr); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index cedf745bdac..1b4df28c707 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -72,8 +72,8 @@ struct pb_debug_buffer struct pb_buffer *buffer; struct pb_debug_manager *mgr; - size_t underflow_size; - size_t overflow_size; + pb_size underflow_size; + pb_size overflow_size; struct debug_stack_frame create_backtrace[PB_DEBUG_CREATE_BACKTRACE]; @@ -91,8 +91,8 @@ struct pb_debug_manager struct pb_manager *provider; - size_t underflow_size; - size_t overflow_size; + pb_size underflow_size; + pb_size overflow_size; pipe_mutex mutex; struct list_head list; @@ -124,9 +124,9 @@ static const uint8_t random_pattern[32] = { static INLINE void -fill_random_pattern(uint8_t *dst, size_t size) +fill_random_pattern(uint8_t *dst, pb_size size) { - size_t i = 0; + pb_size i = 0; while(size--) { *dst++ = random_pattern[i++]; i &= sizeof(random_pattern) - 1; @@ -135,11 +135,11 @@ fill_random_pattern(uint8_t *dst, size_t size) static INLINE boolean -check_random_pattern(const uint8_t *dst, size_t size, - size_t *min_ofs, size_t *max_ofs) +check_random_pattern(const uint8_t *dst, pb_size size, + pb_size *min_ofs, pb_size *max_ofs) { boolean result = TRUE; - size_t i; + pb_size i; *min_ofs = size; *max_ofs = 0; for(i = 0; i < size; ++i) { @@ -183,7 +183,7 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf) assert(map); if(map) { boolean underflow, overflow; - size_t min_ofs, max_ofs; + pb_size min_ofs, max_ofs; underflow = !check_random_pattern(map, buf->underflow_size, &min_ofs, &max_ofs); @@ -287,7 +287,7 @@ pb_debug_buffer_unmap(struct pb_buffer *_buf) static void pb_debug_buffer_get_base_buffer(struct pb_buffer *_buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct pb_debug_buffer *buf = pb_debug_buffer(_buf); pb_get_base_buffer(buf->buffer, base_buf, offset); @@ -363,13 +363,13 @@ pb_debug_manager_dump(struct pb_debug_manager *mgr) static struct pb_buffer * pb_debug_manager_create_buffer(struct pb_manager *_mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pb_debug_manager *mgr = pb_debug_manager(_mgr); struct pb_debug_buffer *buf; struct pb_desc real_desc; - size_t real_size; + pb_size real_size; buf = CALLOC_STRUCT(pb_debug_buffer); if(!buf) @@ -455,7 +455,7 @@ pb_debug_manager_destroy(struct pb_manager *_mgr) struct pb_manager * pb_debug_manager_create(struct pb_manager *provider, - size_t underflow_size, size_t overflow_size) + pb_size underflow_size, pb_size overflow_size) { struct pb_debug_manager *mgr; @@ -485,7 +485,7 @@ pb_debug_manager_create(struct pb_manager *provider, struct pb_manager * pb_debug_manager_create(struct pb_manager *provider, - size_t underflow_size, size_t overflow_size) + pb_size underflow_size, pb_size overflow_size) { return provider; } diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index 144db5669b6..97dd1427fda 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -62,7 +62,7 @@ fenced_pb_manager(struct pb_manager *mgr) static struct pb_buffer * fenced_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index d8decba49df..6400fc5b0a3 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -55,10 +55,10 @@ struct mm_pb_manager pipe_mutex mutex; - size_t size; + pb_size size; struct mem_block *heap; - size_t align2; + pb_size align2; struct pb_buffer *buffer; void *map; @@ -148,7 +148,7 @@ mm_buffer_fence(struct pb_buffer *buf, static void mm_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct mm_buffer *mm_buf = mm_buffer(buf); struct mm_pb_manager *mm = mm_buf->mgr; @@ -170,15 +170,15 @@ mm_buffer_vtbl = { static struct pb_buffer * mm_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct mm_pb_manager *mm = mm_pb_manager(mgr); struct mm_buffer *mm_buf; /* We don't handle alignments larger then the one initially setup */ - assert(pb_check_alignment(desc->alignment, 1 << mm->align2)); - if(!pb_check_alignment(desc->alignment, 1 << mm->align2)) + assert(pb_check_alignment(desc->alignment, (pb_size)1 << mm->align2)); + if(!pb_check_alignment(desc->alignment, (pb_size)1 << mm->align2)) return NULL; pipe_mutex_lock(mm->mutex); @@ -198,7 +198,7 @@ mm_bufmgr_create_buffer(struct pb_manager *mgr, mm_buf->mgr = mm; - mm_buf->block = u_mmAllocMem(mm->heap, size, mm->align2, 0); + mm_buf->block = u_mmAllocMem(mm->heap, (int)size, (int)mm->align2, 0); if(!mm_buf->block) { #if 0 debug_printf("warning: heap full\n"); @@ -210,8 +210,8 @@ mm_bufmgr_create_buffer(struct pb_manager *mgr, } /* Some sanity checks */ - assert(0 <= (unsigned)mm_buf->block->ofs && (unsigned)mm_buf->block->ofs < mm->size); - assert(size <= (unsigned)mm_buf->block->size && (unsigned)mm_buf->block->ofs + (unsigned)mm_buf->block->size <= mm->size); + assert(0 <= (pb_size)mm_buf->block->ofs && (pb_size)mm_buf->block->ofs < mm->size); + assert(size <= (pb_size)mm_buf->block->size && (pb_size)mm_buf->block->ofs + (pb_size)mm_buf->block->size <= mm->size); pipe_mutex_unlock(mm->mutex); return SUPER(mm_buf); @@ -245,7 +245,7 @@ mm_bufmgr_destroy(struct pb_manager *mgr) struct pb_manager * mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, - size_t size, size_t align2) + pb_size size, pb_size align2) { struct mm_pb_manager *mm; @@ -273,7 +273,7 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, if(!mm->map) goto failure; - mm->heap = u_mmInit(0, size); + mm->heap = u_mmInit(0, (int)size); if (!mm->heap) goto failure; @@ -292,7 +292,7 @@ if(mm->heap) struct pb_manager * mm_bufmgr_create(struct pb_manager *provider, - size_t size, size_t align2) + pb_size size, pb_size align2) { struct pb_buffer *buffer; struct pb_manager *mgr; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c index 4f7e6b1c4df..bc3093f620f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c @@ -55,7 +55,7 @@ struct pb_ondemand_buffer /** Real buffer */ struct pb_buffer *buffer; - size_t size; + pb_size size; struct pb_desc desc; }; @@ -204,7 +204,7 @@ pb_ondemand_buffer_fence(struct pb_buffer *_buf, static void pb_ondemand_buffer_get_base_buffer(struct pb_buffer *_buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); @@ -232,7 +232,7 @@ pb_ondemand_buffer_vtbl = { static struct pb_buffer * pb_ondemand_manager_create_buffer(struct pb_manager *_mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pb_ondemand_manager *mgr = pb_ondemand_manager(_mgr); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 07fd1a22d93..7fd65ed2261 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -58,11 +58,11 @@ struct pool_pb_manager pipe_mutex mutex; - size_t bufSize; - size_t bufAlign; + pb_size bufSize; + pb_size bufAlign; - size_t numFree; - size_t numTot; + pb_size numFree; + pb_size numTot; struct list_head free; @@ -89,7 +89,7 @@ struct pool_buffer struct list_head head; - size_t start; + pb_size start; }; @@ -162,7 +162,7 @@ pool_buffer_fence(struct pb_buffer *buf, static void pool_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct pool_buffer *pool_buf = pool_buffer(buf); struct pool_pb_manager *pool = pool_buf->mgr; @@ -184,7 +184,7 @@ pool_buffer_vtbl = { static struct pb_buffer * pool_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pool_pb_manager *pool = pool_pb_manager(mgr); @@ -251,13 +251,13 @@ pool_bufmgr_destroy(struct pb_manager *mgr) struct pb_manager * pool_bufmgr_create(struct pb_manager *provider, - size_t numBufs, - size_t bufSize, + pb_size numBufs, + pb_size bufSize, const struct pb_desc *desc) { struct pool_pb_manager *pool; struct pool_buffer *pool_buf; - size_t i; + pb_size i; if(!provider) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 724aaadb436..e7352e90db9 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -68,7 +68,7 @@ struct pb_slab_buffer unsigned mapCount; /** Offset relative to the start of the slab buffer. */ - size_t start; + pb_size start; /** Use when validating, to signal that all mappings are finished */ /* TODO: Actually validation does not reach this stage yet */ @@ -83,8 +83,8 @@ struct pb_slab { struct list_head head; struct list_head freeBuffers; - size_t numBuffers; - size_t numFree; + pb_size numBuffers; + pb_size numFree; struct pb_slab_buffer *buffers; struct pb_slab_manager *mgr; @@ -108,10 +108,10 @@ struct pb_slab_manager struct pb_manager *provider; /** Size of the buffers we hand on downstream */ - size_t bufSize; + pb_size bufSize; /** Size of the buffers we request upstream */ - size_t slabSize; + pb_size slabSize; /** * Alignment, usage to be used to allocate the slab buffers. @@ -150,14 +150,14 @@ struct pb_slab_range_manager struct pb_manager *provider; - size_t minBufSize; - size_t maxBufSize; + pb_size minBufSize; + pb_size maxBufSize; /** @sa pb_slab_manager::desc */ struct pb_desc desc; unsigned numBuckets; - size_t *bucketSizes; + pb_size *bucketSizes; /** Array of pb_slab_manager, one for each bucket size */ struct pb_manager **buckets; @@ -270,7 +270,7 @@ pb_slab_buffer_fence(struct pb_buffer *_buf, static void pb_slab_buffer_get_base_buffer(struct pb_buffer *_buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { struct pb_slab_buffer *buf = pb_slab_buffer(_buf); pb_get_base_buffer(buf->slab->bo, base_buf, offset); @@ -369,7 +369,7 @@ out_err0: static struct pb_buffer * pb_slab_manager_create_buffer(struct pb_manager *_mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pb_slab_manager *mgr = pb_slab_manager(_mgr); @@ -450,8 +450,8 @@ pb_slab_manager_destroy(struct pb_manager *_mgr) struct pb_manager * pb_slab_manager_create(struct pb_manager *provider, - size_t bufSize, - size_t slabSize, + pb_size bufSize, + pb_size slabSize, const struct pb_desc *desc) { struct pb_slab_manager *mgr; @@ -479,11 +479,11 @@ pb_slab_manager_create(struct pb_manager *provider, static struct pb_buffer * pb_slab_range_manager_create_buffer(struct pb_manager *_mgr, - size_t size, + pb_size size, const struct pb_desc *desc) { struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); - size_t bufSize; + pb_size bufSize; unsigned i; bufSize = mgr->minBufSize; @@ -527,13 +527,13 @@ pb_slab_range_manager_destroy(struct pb_manager *_mgr) struct pb_manager * pb_slab_range_manager_create(struct pb_manager *provider, - size_t minBufSize, - size_t maxBufSize, - size_t slabSize, + pb_size minBufSize, + pb_size maxBufSize, + pb_size slabSize, const struct pb_desc *desc) { struct pb_slab_range_manager *mgr; - size_t bufSize; + pb_size bufSize; unsigned i; if(!provider) diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index a784b7cc3c1..76a09af18ee 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -27,6 +27,7 @@ #include "util/u_debug.h" #include "util/u_string.h" +#include "util/u_math.h" #include "tgsi_dump.h" #include "tgsi_info.h" #include "tgsi_iterate.h" @@ -516,7 +517,7 @@ struct str_dump_ctx struct dump_ctx base; char *str; char *ptr; - size_t left; + int left; }; static void @@ -525,13 +526,20 @@ str_dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) struct str_dump_ctx *sctx = (struct str_dump_ctx *)ctx; if(sctx->left > 1) { - size_t written; + int written; va_list ap; va_start(ap, format); written = util_vsnprintf(sctx->ptr, sctx->left, format, ap); va_end(ap); - sctx->ptr += written; - sctx->left -= written; + + /* Some complicated logic needed to handle the return value of + * vsnprintf: + */ + if (written > 0) { + written = MIN2(sctx->left, written); + sctx->ptr += written; + sctx->left -= written; + } } } @@ -556,7 +564,7 @@ tgsi_dump_str( ctx.str = str; ctx.str[0] = 0; ctx.ptr = str; - ctx.left = size; + ctx.left = (int)size; tgsi_iterate_shader( tokens, &ctx.base.iter ); } diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c index 0d54299b28a..65bdd0df2b7 100644 --- a/src/gallium/auxiliary/util/u_snprintf.c +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -829,7 +829,7 @@ util_vsnprintf(char *str, size_t size, const char *format, va_list args) break; default: intptr = va_arg(args, int *); - *intptr = len; + *intptr = (int)len; break; } break; diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 512d85d3525..bd48ce70050 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -86,6 +86,8 @@ cell_get_param(struct pipe_screen *screen, int param) return 1; /* XXX not really true */ case PIPE_CAP_TEXTURE_MIRROR_CLAMP: return 0; /* XXX to do */ + case PIPE_CAP_TGSI_CONT_SUPPORTED: + return 1; default: return 0; } diff --git a/src/gallium/drivers/identity/Makefile b/src/gallium/drivers/identity/Makefile new file mode 100644 index 00000000000..74692d97610 --- /dev/null +++ b/src/gallium/drivers/identity/Makefile @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = identity + +C_SOURCES = \ + id_objects.c \ + id_context.c \ + id_screen.c + +include ../../Makefile.template diff --git a/src/gallium/drivers/identity/SConscript b/src/gallium/drivers/identity/SConscript new file mode 100644 index 00000000000..7f079dd0a8b --- /dev/null +++ b/src/gallium/drivers/identity/SConscript @@ -0,0 +1,13 @@ +Import('*') + +env = env.Clone() + +identity = env.ConvenienceLibrary( + target = 'identity', + source = [ + 'id_screen.c', + 'id_context.c', + 'id_objects.c', + ]) + +Export('identity') diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c new file mode 100644 index 00000000000..a500ec60454 --- /dev/null +++ b/src/gallium/drivers/identity/id_context.c @@ -0,0 +1,719 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_context.h" +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_context.h" +#include "id_objects.h" + + +static void +identity_destroy(struct pipe_context *_pipe) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->destroy(pipe); + + free(id_pipe); +} + +static void +identity_set_edgeflags(struct pipe_context *_pipe, + const unsigned *bitfield) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_edgeflags(pipe, + bitfield); +} + +static boolean +identity_draw_arrays(struct pipe_context *_pipe, + unsigned prim, + unsigned start, + unsigned count) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->draw_arrays(pipe, + prim, + start, + count); +} + +static boolean +identity_draw_elements(struct pipe_context *_pipe, + struct pipe_buffer *_indexBuffer, + unsigned indexSize, + unsigned prim, + unsigned start, + unsigned count) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_buffer *indexBuffer = id_buffer->buffer; + + return pipe->draw_elements(pipe, + indexBuffer, + indexSize, + prim, + start, + count); +} + +static boolean +identity_draw_range_elements(struct pipe_context *_pipe, + struct pipe_buffer *_indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_buffer *indexBuffer = id_buffer->buffer; + + return pipe->draw_range_elements(pipe, + indexBuffer, + indexSize, + minIndex, + maxIndex, + mode, + start, + count); +} + +static struct pipe_query * +identity_create_query(struct pipe_context *_pipe, + unsigned query_type) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_query(pipe, + query_type); +} + +static void +identity_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->destroy_query(pipe, + query); +} + +static void +identity_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->begin_query(pipe, + query); +} + +static void +identity_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->end_query(pipe, + query); +} + +static boolean +identity_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + uint64_t *result) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->get_query_result(pipe, + query, + wait, + result); +} + +static void * +identity_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *blend) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_blend_state(pipe, + blend); +} + +static void +identity_bind_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_blend_state(pipe, + blend); +} + +static void +identity_delete_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_blend_state(pipe, + blend); +} + +static void * +identity_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *sampler) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_sampler_state(pipe, + sampler); +} + +static void +identity_bind_sampler_states(struct pipe_context *_pipe, + unsigned num, + void **samplers) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_sampler_states(pipe, + num, + samplers); +} + +static void +identity_delete_sampler_state(struct pipe_context *_pipe, + void *sampler) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_sampler_state(pipe, + sampler); +} + +static void * +identity_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_rasterizer_state(pipe, + rasterizer); +} + +static void +identity_bind_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_rasterizer_state(pipe, + rasterizer); +} + +static void +identity_delete_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_rasterizer_state(pipe, + rasterizer); +} + +static void * +identity_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +identity_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +identity_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void * +identity_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *fs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_fs_state(pipe, + fs); +} + +static void +identity_bind_fs_state(struct pipe_context *_pipe, + void *fs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_fs_state(pipe, + fs); +} + +static void +identity_delete_fs_state(struct pipe_context *_pipe, + void *fs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_fs_state(pipe, + fs); +} + +static void * +identity_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *vs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_vs_state(pipe, + vs); +} + +static void +identity_bind_vs_state(struct pipe_context *_pipe, + void *vs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_vs_state(pipe, + vs); +} + +static void +identity_delete_vs_state(struct pipe_context *_pipe, + void *vs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_vs_state(pipe, + vs); +} + +static void +identity_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *blend_color) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_blend_color(pipe, + blend_color); +} + +static void +identity_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *clip) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_clip_state(pipe, + clip); +} + +static void +identity_set_constant_buffer(struct pipe_context *_pipe, + uint shader, + uint index, + const struct pipe_constant_buffer *_buffer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_constant_buffer unwrapped_buffer; + struct pipe_constant_buffer *buffer = NULL; + + /* unwrap the input state */ + if (_buffer) { + unwrapped_buffer.buffer = identity_buffer_unwrap(_buffer->buffer); + buffer = &unwrapped_buffer; + } + + pipe->set_constant_buffer(pipe, + shader, + index, + buffer); +} + +static void +identity_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *_state) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_framebuffer_state unwrapped_state; + struct pipe_framebuffer_state *state = NULL; + unsigned i; + + /* unwrap the input state */ + if (_state) { + memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); + for(i = 0; i < _state->nr_cbufs; i++) + unwrapped_state.cbufs[i] = identity_surface_unwrap(_state->cbufs[i]); + for (; i < PIPE_MAX_COLOR_BUFS; i++) + unwrapped_state.cbufs[i] = NULL; + unwrapped_state.zsbuf = identity_surface_unwrap(_state->zsbuf); + state = &unwrapped_state; + } + + pipe->set_framebuffer_state(pipe, + state); +} + +static void +identity_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *poly_stipple) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_polygon_stipple(pipe, + poly_stipple); +} + +static void +identity_set_scissor_state(struct pipe_context *_pipe, + const struct pipe_scissor_state *scissor) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_scissor_state(pipe, + scissor); +} + +static void +identity_set_viewport_state(struct pipe_context *_pipe, + const struct pipe_viewport_state *viewport) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_viewport_state(pipe, + viewport); +} + +static void +identity_set_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **_textures) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; + struct pipe_texture **textures = NULL; + unsigned i; + + if (_textures) { + for (i = 0; i < num_textures; i++) + unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); + for (; i < PIPE_MAX_SAMPLERS; i++) + unwrapped_textures[i] = NULL; + + textures = unwrapped_textures; + } + + pipe->set_sampler_textures(pipe, + num_textures, + _textures); +} + +static void +identity_set_vertex_buffers(struct pipe_context *_pipe, + unsigned num_buffers, + const struct pipe_vertex_buffer *_buffers) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS]; + struct pipe_vertex_buffer *buffers = NULL; + unsigned i; + + if (num_buffers) { + memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); + for (i = 0; i < num_buffers; i++) + unwrapped_buffers[i].buffer = identity_buffer_unwrap(_buffers[i].buffer); + buffers = unwrapped_buffers; + } + + pipe->set_vertex_buffers(pipe, + num_buffers, + buffers); +} + +static void +identity_set_vertex_elements(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *vertex_elements) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_vertex_elements(pipe, + num_elements, + vertex_elements); +} + +static void +identity_surface_copy(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + struct pipe_surface *_src, + unsigned srcx, + unsigned srcy, + unsigned width, + unsigned height) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_surface *id_surface_dst = identity_surface(_dst); + struct identity_surface *id_surface_src = identity_surface(_src); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_surface *dst = id_surface_dst->surface; + struct pipe_surface *src = id_surface_src->surface; + + pipe->surface_copy(pipe, + dst, + dstx, + dsty, + src, + srcx, + srcy, + width, + height); +} + +static void +identity_surface_fill(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + unsigned width, + unsigned height, + unsigned value) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_surface *id_surface_dst = identity_surface(_dst); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_surface *dst = id_surface_dst->surface; + + pipe->surface_fill(pipe, + dst, + dstx, + dsty, + width, + height, + value); +} + +static void +identity_clear(struct pipe_context *_pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->clear(pipe, + buffers, + rgba, + depth, + stencil); +} + +static void +identity_flush(struct pipe_context *_pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->flush(pipe, + flags, + fence); +} + +static unsigned int +identity_is_texture_referenced(struct pipe_context *_pipe, + struct pipe_texture *_texture, + unsigned face, + unsigned level) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_texture *id_texture = identity_texture(_texture); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_texture *texture = id_texture->texture; + + return pipe->is_texture_referenced(pipe, + texture, + face, + level); +} + +static unsigned int +identity_is_buffer_referenced(struct pipe_context *_pipe, + struct pipe_buffer *_buffer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_buffer *buffer = id_buffer->buffer; + + return pipe->is_buffer_referenced(pipe, + buffer); +} + +struct pipe_context * +identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) +{ + struct identity_context *id_pipe; + (void)identity_screen(_screen); + + id_pipe = CALLOC_STRUCT(identity_context); + if (!id_pipe) { + return NULL; + } + + id_pipe->base.winsys = NULL; + id_pipe->base.screen = _screen; + id_pipe->base.priv = pipe->priv; + id_pipe->base.draw = NULL; + + id_pipe->base.destroy = identity_destroy; + id_pipe->base.set_edgeflags = identity_set_edgeflags; + id_pipe->base.draw_arrays = identity_draw_arrays; + id_pipe->base.draw_elements = identity_draw_elements; + id_pipe->base.draw_range_elements = identity_draw_range_elements; + id_pipe->base.create_query = identity_create_query; + id_pipe->base.destroy_query = identity_destroy_query; + id_pipe->base.begin_query = identity_begin_query; + id_pipe->base.end_query = identity_end_query; + id_pipe->base.get_query_result = identity_get_query_result; + id_pipe->base.create_blend_state = identity_create_blend_state; + id_pipe->base.bind_blend_state = identity_bind_blend_state; + id_pipe->base.delete_blend_state = identity_delete_blend_state; + id_pipe->base.create_sampler_state = identity_create_sampler_state; + id_pipe->base.bind_sampler_states = identity_bind_sampler_states; + id_pipe->base.delete_sampler_state = identity_delete_sampler_state; + id_pipe->base.create_rasterizer_state = identity_create_rasterizer_state; + id_pipe->base.bind_rasterizer_state = identity_bind_rasterizer_state; + id_pipe->base.delete_rasterizer_state = identity_delete_rasterizer_state; + id_pipe->base.create_depth_stencil_alpha_state = identity_create_depth_stencil_alpha_state; + id_pipe->base.bind_depth_stencil_alpha_state = identity_bind_depth_stencil_alpha_state; + id_pipe->base.delete_depth_stencil_alpha_state = identity_delete_depth_stencil_alpha_state; + id_pipe->base.create_fs_state = identity_create_fs_state; + id_pipe->base.bind_fs_state = identity_bind_fs_state; + id_pipe->base.delete_fs_state = identity_delete_fs_state; + id_pipe->base.create_vs_state = identity_create_vs_state; + id_pipe->base.bind_vs_state = identity_bind_vs_state; + id_pipe->base.delete_vs_state = identity_delete_vs_state; + id_pipe->base.set_blend_color = identity_set_blend_color; + id_pipe->base.set_clip_state = identity_set_clip_state; + id_pipe->base.set_constant_buffer = identity_set_constant_buffer; + id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state; + id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple; + id_pipe->base.set_scissor_state = identity_set_scissor_state; + id_pipe->base.set_viewport_state = identity_set_viewport_state; + id_pipe->base.set_sampler_textures = identity_set_sampler_textures; + id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; + id_pipe->base.set_vertex_elements = identity_set_vertex_elements; + id_pipe->base.surface_copy = identity_surface_copy; + id_pipe->base.surface_fill = identity_surface_fill; + id_pipe->base.clear = identity_clear; + id_pipe->base.flush = identity_flush; + id_pipe->base.is_texture_referenced = identity_is_texture_referenced; + id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced; + + id_pipe->pipe = pipe; + + return &id_pipe->base; +} diff --git a/src/gallium/drivers/identity/id_context.h b/src/gallium/drivers/identity/id_context.h new file mode 100644 index 00000000000..75b73fc7df6 --- /dev/null +++ b/src/gallium/drivers/identity/id_context.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef ID_CONTEXT_H +#define ID_CONTEXT_H + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + + +struct identity_context { + struct pipe_context base; /**< base class */ + + struct pipe_context *pipe; +}; + + +static INLINE struct identity_context * +identity_context(struct pipe_context *pipe) +{ + return (struct identity_context *)pipe; +} + +#endif /* ID_CONTEXT_H */ diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c new file mode 100644 index 00000000000..e893e599408 --- /dev/null +++ b/src/gallium/drivers/identity/id_objects.c @@ -0,0 +1,182 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_screen.h" +#include "id_objects.h" + +struct pipe_buffer * +identity_buffer_create(struct identity_screen *id_screen, + struct pipe_buffer *buffer) +{ + struct identity_buffer *id_buffer; + + if(!buffer) + goto error; + + assert(buffer->screen == id_screen->screen); + + id_buffer = CALLOC_STRUCT(identity_buffer); + if(!id_buffer) + goto error; + + memcpy(&id_buffer->base, buffer, sizeof(struct pipe_buffer)); + + pipe_reference_init(&id_buffer->base.reference, 1); + id_buffer->base.screen = &id_screen->base; + id_buffer->buffer = buffer; + + return &id_buffer->base; + +error: + pipe_buffer_reference(&buffer, NULL); + return NULL; +} + +void +identity_buffer_destroy(struct identity_buffer *id_buffer) +{ + pipe_buffer_reference(&id_buffer->buffer, NULL); + FREE(id_buffer); +} + + +struct pipe_texture * +identity_texture_create(struct identity_screen *id_screen, + struct pipe_texture *texture) +{ + struct identity_texture *id_texture; + + if(!texture) + goto error; + + assert(texture->screen == id_screen->screen); + + id_texture = CALLOC_STRUCT(identity_texture); + if(!id_texture) + goto error; + + memcpy(&id_texture->base, texture, sizeof(struct pipe_texture)); + + pipe_reference_init(&id_texture->base.reference, 1); + id_texture->base.screen = &id_screen->base; + id_texture->texture = texture; + + return &id_texture->base; + +error: + pipe_texture_reference(&texture, NULL); + return NULL; +} + +void +identity_texture_destroy(struct identity_texture *id_texture) +{ + pipe_texture_reference(&id_texture->texture, NULL); + FREE(id_texture); +} + + +struct pipe_surface * +identity_surface_create(struct identity_texture *id_texture, + struct pipe_surface *surface) +{ + struct identity_surface *id_surface; + + if(!surface) + goto error; + + assert(surface->texture == id_texture->texture); + + id_surface = CALLOC_STRUCT(identity_surface); + if(!id_surface) + goto error; + + memcpy(&id_surface->base, surface, sizeof(struct pipe_surface)); + + pipe_reference_init(&id_surface->base.reference, 1); + id_surface->base.texture = NULL; + pipe_texture_reference(&id_surface->base.texture, &id_texture->base); + id_surface->surface = surface; + + return &id_surface->base; + +error: + pipe_surface_reference(&surface, NULL); + return NULL; +} + +void +identity_surface_destroy(struct identity_surface *id_surface) +{ + pipe_texture_reference(&id_surface->base.texture, NULL); + pipe_surface_reference(&id_surface->surface, NULL); + FREE(id_surface); +} + + +struct pipe_transfer * +identity_transfer_create(struct identity_texture *id_texture, + struct pipe_transfer *transfer) +{ + struct identity_transfer *id_transfer; + + if(!transfer) + goto error; + + assert(transfer->texture == id_texture->texture); + + id_transfer = CALLOC_STRUCT(identity_transfer); + if(!id_transfer) + goto error; + + memcpy(&id_transfer->base, transfer, sizeof(struct pipe_transfer)); + + id_transfer->base.texture = NULL; + pipe_texture_reference(&id_transfer->base.texture, &id_texture->base); + id_transfer->transfer = transfer; + assert(id_transfer->base.texture == &id_texture->base); + + return &id_transfer->base; + +error: + transfer->texture->screen->tex_transfer_destroy(transfer); + return NULL; +} + +void +identity_transfer_destroy(struct identity_transfer *id_transfer) +{ + struct identity_screen *id_screen = identity_screen(id_transfer->base.texture->screen); + struct pipe_screen *screen = id_screen->screen; + + pipe_texture_reference(&id_transfer->base.texture, NULL); + screen->tex_transfer_destroy(id_transfer->transfer); + FREE(id_transfer); +} diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h new file mode 100644 index 00000000000..ce58faa3c7c --- /dev/null +++ b/src/gallium/drivers/identity/id_objects.h @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef ID_OBJECTS_H +#define ID_OBJECTS_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "id_screen.h" + + +struct identity_buffer +{ + struct pipe_buffer base; + + struct pipe_buffer *buffer; +}; + + +struct identity_texture +{ + struct pipe_texture base; + + struct pipe_texture *texture; +}; + + +struct identity_surface +{ + struct pipe_surface base; + + struct pipe_surface *surface; +}; + + +struct identity_transfer +{ + struct pipe_transfer base; + + struct pipe_transfer *transfer; +}; + + +static INLINE struct identity_buffer * +identity_buffer(struct pipe_buffer *_buffer) +{ + if(!_buffer) + return NULL; + (void)identity_screen(_buffer->screen); + return (struct identity_buffer *)_buffer; +} + +static INLINE struct identity_texture * +identity_texture(struct pipe_texture *_texture) +{ + if(!_texture) + return NULL; + (void)identity_screen(_texture->screen); + return (struct identity_texture *)_texture; +} + +static INLINE struct identity_surface * +identity_surface(struct pipe_surface *_surface) +{ + if(!_surface) + return NULL; + (void)identity_texture(_surface->texture); + return (struct identity_surface *)_surface; +} + +static INLINE struct identity_transfer * +identity_transfer(struct pipe_transfer *_transfer) +{ + if(!_transfer) + return NULL; + (void)identity_texture(_transfer->texture); + return (struct identity_transfer *)_transfer; +} + + +static INLINE struct pipe_buffer * +identity_buffer_unwrap(struct pipe_buffer *_buffer) +{ + if(!_buffer) + return NULL; + return identity_buffer(_buffer)->buffer; +} + +static INLINE struct pipe_texture * +identity_texture_unwrap(struct pipe_texture *_texture) +{ + if(!_texture) + return NULL; + return identity_texture(_texture)->texture; +} + +static INLINE struct pipe_surface * +identity_surface_unwrap(struct pipe_surface *_surface) +{ + if(!_surface) + return NULL; + return identity_surface(_surface)->surface; +} + +static INLINE struct pipe_transfer * +identity_transfer_unwrap(struct pipe_transfer *_transfer) +{ + if(!_transfer) + return NULL; + return identity_transfer(_transfer)->transfer; +} + + +struct pipe_buffer * +identity_buffer_create(struct identity_screen *id_screen, + struct pipe_buffer *buffer); + +void +identity_buffer_destroy(struct identity_buffer *id_buffer); + +struct pipe_texture * +identity_texture_create(struct identity_screen *id_screen, + struct pipe_texture *texture); + +void +identity_texture_destroy(struct identity_texture *id_texture); + +struct pipe_surface * +identity_surface_create(struct identity_texture *id_texture, + struct pipe_surface *surface); + +void +identity_surface_destroy(struct identity_surface *id_surface); + +struct pipe_transfer * +identity_transfer_create(struct identity_texture *id_texture, + struct pipe_transfer *transfer); + +void +identity_transfer_destroy(struct identity_transfer *id_transfer); + + +#endif /* ID_OBJECTS_H */ diff --git a/src/gallium/drivers/identity/id_public.h b/src/gallium/drivers/identity/id_public.h new file mode 100644 index 00000000000..cac14cfd604 --- /dev/null +++ b/src/gallium/drivers/identity/id_public.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef ID_PUBLIC_H +#define ID_PUBLIC_H + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +identity_screen_create(struct pipe_screen *screen); + +struct pipe_context * +identity_context_create(struct pipe_screen *screen, struct pipe_context *pipe); + +#endif /* PT_PUBLIC_H */ diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c new file mode 100644 index 00000000000..259f1be36e7 --- /dev/null +++ b/src/gallium/drivers/identity/id_screen.c @@ -0,0 +1,481 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_screen.h" +#include "pipe/p_state.h" +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_screen.h" +#include "id_objects.h" + + +static void +identity_screen_destroy(struct pipe_screen *_screen) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + screen->destroy(screen); + + FREE(id_screen); +} + +static const char * +identity_screen_get_name(struct pipe_screen *_screen) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_name(screen); +} + +static const char * +identity_screen_get_vendor(struct pipe_screen *_screen) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_vendor(screen); +} + +static int +identity_screen_get_param(struct pipe_screen *_screen, + int param) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_param(screen, + param); +} + +static float +identity_screen_get_paramf(struct pipe_screen *_screen, + int param) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_paramf(screen, + param); +} + +static boolean +identity_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->is_format_supported(screen, + format, + target, + tex_usage, + geom_flags); +} + +static struct pipe_texture * +identity_screen_texture_create(struct pipe_screen *_screen, + const struct pipe_texture *templat) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_texture *result; + + result = screen->texture_create(screen, + templat); + + if (result) + return identity_texture_create(id_screen, result); + return NULL; +} + +static struct pipe_texture * +identity_screen_texture_blanket(struct pipe_screen *_screen, + const struct pipe_texture *templat, + const unsigned *stride, + struct pipe_buffer *_buffer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + struct pipe_texture *result; + + result = screen->texture_blanket(screen, + templat, + stride, + buffer); + + if (result) + return identity_texture_create(id_screen, result); + return NULL; +} + +static void +identity_screen_texture_destroy(struct pipe_texture *_texture) +{ + identity_texture_destroy(identity_texture(_texture)); +} + +static struct pipe_surface * +identity_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_texture *_texture, + unsigned face, + unsigned level, + unsigned zslice, + unsigned usage) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_texture *id_texture = identity_texture(_texture); + struct pipe_screen *screen = id_screen->screen; + struct pipe_texture *texture = id_texture->texture; + struct pipe_surface *result; + + result = screen->get_tex_surface(screen, + texture, + face, + level, + zslice, + usage); + + if (result) + return identity_surface_create(id_texture, result); + return NULL; +} + +static void +identity_screen_tex_surface_destroy(struct pipe_surface *_surface) +{ + identity_surface_destroy(identity_surface(_surface)); +} + +static struct pipe_transfer * +identity_screen_get_tex_transfer(struct pipe_screen *_screen, + struct pipe_texture *_texture, + unsigned face, + unsigned level, + unsigned zslice, + enum pipe_transfer_usage usage, + unsigned x, + unsigned y, + unsigned w, + unsigned h) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_texture *id_texture = identity_texture(_texture); + struct pipe_screen *screen = id_screen->screen; + struct pipe_texture *texture = id_texture->texture; + struct pipe_transfer *result; + + result = screen->get_tex_transfer(screen, + texture, + face, + level, + zslice, + usage, + x, + y, + w, + h); + + if (result) + return identity_transfer_create(id_texture, result); + return NULL; +} + +static void +identity_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) +{ + identity_transfer_destroy(identity_transfer(_transfer)); +} + +static void * +identity_screen_transfer_map(struct pipe_screen *_screen, + struct pipe_transfer *_transfer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_transfer *id_transfer = identity_transfer(_transfer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_transfer *transfer = id_transfer->transfer; + + return screen->transfer_map(screen, + transfer); +} + +static void +identity_screen_transfer_unmap(struct pipe_screen *_screen, + struct pipe_transfer *_transfer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_transfer *id_transfer = identity_transfer(_transfer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_transfer *transfer = id_transfer->transfer; + + screen->transfer_unmap(screen, + transfer); +} + +static struct pipe_buffer * +identity_screen_buffer_create(struct pipe_screen *_screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *result; + + result = screen->buffer_create(screen, + alignment, + usage, + size); + + if (result) + return identity_buffer_create(id_screen, result); + return NULL; +} + +static struct pipe_buffer * +identity_screen_user_buffer_create(struct pipe_screen *_screen, + void *ptr, + unsigned bytes) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *result; + + result = screen->user_buffer_create(screen, + ptr, + bytes); + + if (result) + return identity_buffer_create(id_screen, result); + return NULL; +} + +static struct pipe_buffer * +identity_screen_surface_buffer_create(struct pipe_screen *_screen, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned usage, + unsigned *stride) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *result; + + result = screen->surface_buffer_create(screen, + width, + height, + format, + usage, + stride); + + if (result) + return identity_buffer_create(id_screen, result); + return NULL; +} + +static void * +identity_screen_buffer_map(struct pipe_screen *_screen, + struct pipe_buffer *_buffer, + unsigned usage) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + return screen->buffer_map(screen, + buffer, + usage); +} + +static void * +identity_screen_buffer_map_range(struct pipe_screen *_screen, + struct pipe_buffer *_buffer, + unsigned offset, + unsigned length, + unsigned usage) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + return screen->buffer_map_range(screen, + buffer, + offset, + length, + usage); +} + +static void +identity_screen_buffer_flush_mapped_range(struct pipe_screen *_screen, + struct pipe_buffer *_buffer, + unsigned offset, + unsigned length) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + screen->buffer_flush_mapped_range(screen, + buffer, + offset, + length); +} + +static void +identity_screen_buffer_unmap(struct pipe_screen *_screen, + struct pipe_buffer *_buffer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + screen->buffer_unmap(screen, + buffer); +} + +static void +identity_screen_buffer_destroy(struct pipe_buffer *_buffer) +{ + identity_buffer_destroy(identity_buffer(_buffer)); +} + +static void +identity_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *_surface, + void *context_private) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_surface *id_surface = identity_surface(_surface); + struct pipe_screen *screen = id_screen->screen; + struct pipe_surface *surface = id_surface->surface; + + screen->flush_frontbuffer(screen, + surface, + context_private); +} + +static void +identity_screen_fence_reference(struct pipe_screen *_screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + screen->fence_reference(screen, + ptr, + fence); +} + +static int +identity_screen_fence_signalled(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->fence_signalled(screen, + fence, + flags); +} + +static int +identity_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->fence_finish(screen, + fence, + flags); +} + +struct pipe_screen * +identity_screen_create(struct pipe_screen *screen) +{ + struct identity_screen *id_screen; + + id_screen = CALLOC_STRUCT(identity_screen); + if (!id_screen) { + return NULL; + } + + id_screen->base.winsys = NULL; + + id_screen->base.destroy = identity_screen_destroy; + id_screen->base.get_name = identity_screen_get_name; + id_screen->base.get_vendor = identity_screen_get_vendor; + id_screen->base.get_param = identity_screen_get_param; + id_screen->base.get_paramf = identity_screen_get_paramf; + id_screen->base.is_format_supported = identity_screen_is_format_supported; + id_screen->base.texture_create = identity_screen_texture_create; + id_screen->base.texture_blanket = identity_screen_texture_blanket; + id_screen->base.texture_destroy = identity_screen_texture_destroy; + id_screen->base.get_tex_surface = identity_screen_get_tex_surface; + id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy; + id_screen->base.get_tex_transfer = identity_screen_get_tex_transfer; + id_screen->base.tex_transfer_destroy = identity_screen_tex_transfer_destroy; + id_screen->base.transfer_map = identity_screen_transfer_map; + id_screen->base.transfer_unmap = identity_screen_transfer_unmap; + id_screen->base.buffer_create = identity_screen_buffer_create; + id_screen->base.user_buffer_create = identity_screen_user_buffer_create; + id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create; + if (screen->buffer_map) + id_screen->base.buffer_map = identity_screen_buffer_map; + if (screen->buffer_map_range) + id_screen->base.buffer_map_range = identity_screen_buffer_map_range; + if (screen->buffer_flush_mapped_range) + id_screen->base.buffer_flush_mapped_range = identity_screen_buffer_flush_mapped_range; + if (screen->buffer_unmap) + id_screen->base.buffer_unmap = identity_screen_buffer_unmap; + id_screen->base.buffer_destroy = identity_screen_buffer_destroy; + id_screen->base.flush_frontbuffer = identity_screen_flush_frontbuffer; + id_screen->base.fence_reference = identity_screen_fence_reference; + id_screen->base.fence_signalled = identity_screen_fence_signalled; + id_screen->base.fence_finish = identity_screen_fence_finish; + + id_screen->screen = screen; + + return &id_screen->base; +} diff --git a/src/gallium/drivers/identity/id_screen.h b/src/gallium/drivers/identity/id_screen.h new file mode 100644 index 00000000000..2c4f1290894 --- /dev/null +++ b/src/gallium/drivers/identity/id_screen.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef ID_SCREEN_H +#define ID_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + +struct identity_screen { + struct pipe_screen base; + + struct pipe_screen *screen; +}; + + +static INLINE struct identity_screen * +identity_screen(struct pipe_screen *screen) +{ + return (struct identity_screen *)screen; +} + +#endif /* ID_SCREEN_H */ diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index e44f9b9dfc5..faceec9842f 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -4,20 +4,22 @@ include $(TOP)/configs/current LIBNAME = r300 C_SOURCES = \ + r3xx_fs.c \ + r5xx_fs.c \ r300_chipset.c \ r300_clear.c \ r300_context.c \ r300_debug.c \ r300_emit.c \ r300_flush.c \ + r300_fs.c \ r300_query.c \ r300_render.c \ r300_screen.c \ r300_state.c \ r300_state_derived.c \ r300_state_invariant.c \ - r300_state_shader.c \ - r300_state_tcl.c \ + r300_vs.c \ r300_surface.c \ r300_texture.c diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 182ed2d459a..493d7b28bc3 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -5,20 +5,22 @@ env = env.Clone() r300 = env.ConvenienceLibrary( target = 'r300', source = [ + 'r3xx_fs.c', + 'r5xx_fs.c', 'r300_chipset.c', 'r300_clear.c', 'r300_context.c', 'r300_debug.c', 'r300_emit.c', 'r300_flush.c', + 'r300_fs.c', 'r300_query.c', 'r300_render.c', 'r300_screen.c', 'r300_state.c', 'r300_state_derived.c', 'r300_state_invariant.c', - 'r300_state_shader.c', - 'r300_state_tcl.c', + 'r300_vs.c', 'r300_surface.c', 'r300_texture.c', ]) diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 27bc7fd1a93..ae7857498fc 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -149,7 +149,7 @@ struct r300_constant_buffer { unsigned count; }; -struct r3xx_fragment_shader { +struct r300_fragment_shader { /* Parent class */ struct pipe_shader_state state; struct tgsi_shader_info info; @@ -165,9 +165,9 @@ struct r3xx_fragment_shader { boolean uses_imms; }; -struct r300_fragment_shader { +struct r3xx_fragment_shader { /* Parent class */ - struct r3xx_fragment_shader shader; + struct r300_fragment_shader shader; /* Number of ALU instructions */ int alu_instruction_count; @@ -190,9 +190,9 @@ struct r300_fragment_shader { } instructions[64]; /* XXX magic num */ }; -struct r500_fragment_shader { +struct r5xx_fragment_shader { /* Parent class */ - struct r3xx_fragment_shader shader; + struct r300_fragment_shader shader; /* Number of used instructions */ int instruction_count; @@ -300,7 +300,7 @@ struct r300_context { /* Depth, stencil, and alpha state. */ struct r300_dsa_state* dsa_state; /* Fragment shader. */ - struct r3xx_fragment_shader* fs; + struct r300_fragment_shader* fs; /* Framebuffer state. We currently don't need our own version of this. */ struct pipe_framebuffer_state framebuffer_state; /* Rasterizer state. */ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 678cd2b8121..c83e8526cf7 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -22,7 +22,7 @@ #include "r300_debug.h" -static void r300_dump_fs(struct r300_fragment_shader* fs) +void r3xx_dump_fs(struct r3xx_fragment_shader* fs) { int i; @@ -30,7 +30,7 @@ static void r300_dump_fs(struct r300_fragment_shader* fs) } } -void r500_fs_dump(struct r500_fragment_shader* fs) +void r5xx_fs_dump(struct r5xx_fragment_shader* fs) { int i; uint32_t inst; @@ -58,8 +58,8 @@ void r500_fs_dump(struct r500_fragment_shader* fs) inst & R500_INST_NOP ? "NOP" : "", inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : ""); debug_printf("wmask: %s omask: %s\n", - r500_fs_mask[(inst >> 11) & 0xf], - r500_fs_mask[(inst >> 15) & 0xf]); + r5xx_fs_mask[(inst >> 11) & 0xf], + r5xx_fs_mask[(inst >> 15) & 0xf]); switch (inst & 0x3) { case R500_INST_TYPE_ALU: case R500_INST_TYPE_OUT: @@ -85,36 +85,36 @@ void r500_fs_dump(struct r500_fragment_shader* fs) debug_printf(" 3: RGB_INST 0x%08x:", inst); debug_printf("rgb_A_src:%d %s/%s/%s %d " "rgb_B_src:%d %s/%s/%s %d\n", - inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7], - r500_fs_swiz[(inst >> 5) & 0x7], - r500_fs_swiz[(inst >> 8) & 0x7], + inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7], + r5xx_fs_swiz[(inst >> 5) & 0x7], + r5xx_fs_swiz[(inst >> 8) & 0x7], (inst >> 11) & 0x3, (inst >> 13) & 0x3, - r500_fs_swiz[(inst >> 15) & 0x7], - r500_fs_swiz[(inst >> 18) & 0x7], - r500_fs_swiz[(inst >> 21) & 0x7], + r5xx_fs_swiz[(inst >> 15) & 0x7], + r5xx_fs_swiz[(inst >> 18) & 0x7], + r5xx_fs_swiz[(inst >> 21) & 0x7], (inst >> 24) & 0x3); inst = fs->instructions[i].inst4; debug_printf(" 4: ALPHA_INST 0x%08x:", inst); debug_printf("%s dest:%d%s alp_A_src:%d %s %d " "alp_B_src:%d %s %d w:%d\n", - r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, + r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3, - r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, - (inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7], + r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, + (inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7], (inst >> 24) & 0x3, (inst >> 31) & 0x1); inst = fs->instructions[i].inst5; debug_printf(" 5: RGBA_INST 0x%08x:", inst); debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d " "alp_C_src:%d %s %d\n", - r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, + r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3, - r500_fs_swiz[(inst >> 14) & 0x7], - r500_fs_swiz[(inst >> 17) & 0x7], - r500_fs_swiz[(inst >> 20) & 0x7], + r5xx_fs_swiz[(inst >> 14) & 0x7], + r5xx_fs_swiz[(inst >> 17) & 0x7], + r5xx_fs_swiz[(inst >> 20) & 0x7], (inst >> 23) & 0x3, (inst >> 25) & 0x3, - r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); + r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); break; case R500_INST_TYPE_FC: /* XXX don't even bother yet */ @@ -124,7 +124,7 @@ void r500_fs_dump(struct r500_fragment_shader* fs) debug_printf(" 1: TEX_INST 0x%08x: id: %d " "op:%s, %s, %s %s\n", inst, (inst >> 16) & 0xf, - r500_fs_tex[(inst >> 22) & 0x7], + r5xx_fs_tex[(inst >> 22) & 0x7], (inst & (1 << 25)) ? "ACQ" : "", (inst & (1 << 26)) ? "IGNUNC" : "", (inst & (1 << 27)) ? "UNSCALED" : "SCALED"); @@ -133,15 +133,15 @@ void r500_fs_dump(struct r500_fragment_shader* fs) debug_printf(" 2: TEX_ADDR 0x%08x: " "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "", - r500_fs_swiz[(inst >> 8) & 0x3], - r500_fs_swiz[(inst >> 10) & 0x3], - r500_fs_swiz[(inst >> 12) & 0x3], - r500_fs_swiz[(inst >> 14) & 0x3], + r5xx_fs_swiz[(inst >> 8) & 0x3], + r5xx_fs_swiz[(inst >> 10) & 0x3], + r5xx_fs_swiz[(inst >> 12) & 0x3], + r5xx_fs_swiz[(inst >> 14) & 0x3], (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "", - r500_fs_swiz[(inst >> 24) & 0x3], - r500_fs_swiz[(inst >> 26) & 0x3], - r500_fs_swiz[(inst >> 28) & 0x3], - r500_fs_swiz[(inst >> 30) & 0x3]); + r5xx_fs_swiz[(inst >> 24) & 0x3], + r5xx_fs_swiz[(inst >> 26) & 0x3], + r5xx_fs_swiz[(inst >> 28) & 0x3], + r5xx_fs_swiz[(inst >> 30) & 0x3]); inst = fs->instructions[i].inst3; debug_printf(" 3: TEX_DXDY 0x%08x\n", inst); diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h index c86410ec0a9..6b58c1e2501 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r300_debug.h @@ -24,10 +24,10 @@ #define R300_DEBUG_H #include "r300_reg.h" -#include "r300_state_shader.h" -#include "r300_state_tcl.h" +#include "r300_fs.h" +#include "r300_vs.h" -static char* r500_fs_swiz[] = { +static char* r5xx_fs_swiz[] = { " R", " G", " B", @@ -38,7 +38,7 @@ static char* r500_fs_swiz[] = { " U", }; -static char* r500_fs_op_rgb[] = { +static char* r5xx_fs_op_rgb[] = { "MAD", "DP3", "DP4", @@ -54,7 +54,7 @@ static char* r500_fs_op_rgb[] = { "MDV", }; -static char* r500_fs_op_alpha[] = { +static char* r5xx_fs_op_alpha[] = { "MAD", " DP", "MIN", @@ -73,7 +73,7 @@ static char* r500_fs_op_alpha[] = { "MDV", }; -static char* r500_fs_mask[] = { +static char* r5xx_fs_mask[] = { "NONE", "R ", " G ", @@ -92,7 +92,7 @@ static char* r500_fs_mask[] = { "RGBA", }; -static char* r500_fs_tex[] = { +static char* r5xx_fs_tex[] = { " NOP", " LD", "TEXKILL", @@ -203,7 +203,8 @@ static char* r300_vs_swiz_debug[] = { "U", }; -void r500_fs_dump(struct r500_fragment_shader* fs); +void r5xx_fs_dump(struct r5xx_fragment_shader* fs); +void r3xx_dump_fs(struct r3xx_fragment_shader* fs); void r300_vs_dump(struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 93cf6909a33..1d297e85930 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -110,7 +110,7 @@ void r300_emit_dsa_state(struct r300_context* r300, } void r300_emit_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs) + struct r3xx_fragment_shader* fs) { int i; CS_LOCALS(r300); @@ -142,7 +142,7 @@ void r300_emit_fragment_shader(struct r300_context* r300, } void r500_emit_fragment_shader(struct r300_context* r300, - struct r500_fragment_shader* fs) + struct r5xx_fragment_shader* fs) { int i; struct r300_constant_buffer* constants = @@ -570,10 +570,10 @@ validate: if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) { if (r300screen->caps->is_r500) { r500_emit_fragment_shader(r300, - (struct r500_fragment_shader*)r300->fs); + (struct r5xx_fragment_shader*)r300->fs); } else { r300_emit_fragment_shader(r300, - (struct r300_fragment_shader*)r300->fs); + (struct r3xx_fragment_shader*)r300->fs); } r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 946f625bd89..196b6c58d3c 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -43,10 +43,10 @@ void r300_emit_dsa_state(struct r300_context* r300, struct r300_dsa_state* dsa); void r300_emit_fragment_shader(struct r300_context* r300, - struct r300_fragment_shader* fs); + struct r3xx_fragment_shader* fs); void r500_emit_fragment_shader(struct r300_context* r300, - struct r500_fragment_shader* fs); + struct r5xx_fragment_shader* fs); void r300_emit_fb_state(struct r300_context* r300, struct pipe_framebuffer_state* fb); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c new file mode 100644 index 00000000000..4b304306d0f --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.c @@ -0,0 +1,109 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_fs.h" + +void r300_translate_fragment_shader(struct r300_context* r300, + struct r300_fragment_shader* fs) +{ + struct tgsi_parse_context parser; + int i; + boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; + struct r300_constant_buffer* consts = + &r300->shader_constants[PIPE_SHADER_FRAGMENT]; + + struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm); + if (assembler == NULL) { + return; + } + /* Setup starting offset for immediates. */ + assembler->imm_offset = consts->user_count; + /* Enable depth writes, if needed. */ + assembler->writes_depth = fs->info.writes_z; + + /* Make sure we start at the beginning of the shader. */ + if (is_r500) { + ((struct r5xx_fragment_shader*)fs)->instruction_count = 0; + } + + tgsi_parse_init(&parser, fs->state.tokens); + + while (!tgsi_parse_end_of_tokens(&parser)) { + tgsi_parse_token(&parser); + + /* This is seriously the lamest way to create fragment programs ever. + * I blame TGSI. */ + switch (parser.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* Allocated registers sitting at the beginning + * of the program. */ + r300_fs_declare(assembler, &parser.FullToken.FullDeclaration); + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + debug_printf("r300: Emitting immediate to constant buffer, " + "position %d\n", + assembler->imm_offset + assembler->imm_count); + /* I am not amused by the length of these. */ + for (i = 0; i < 4; i++) { + consts->constants[assembler->imm_offset + + assembler->imm_count][i] = + parser.FullToken.FullImmediate.u.ImmediateFloat32[i] + .Float; + } + assembler->imm_count++; + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + if (is_r500) { + r5xx_fs_instruction((struct r5xx_fragment_shader*)fs, + assembler, &parser.FullToken.FullInstruction); + } else { + r3xx_fs_instruction((struct r3xx_fragment_shader*)fs, + assembler, &parser.FullToken.FullInstruction); + } + break; + } + } + + debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", + assembler->tex_count, assembler->color_count, + assembler->tex_count + assembler->color_count); + + consts->count = consts->user_count + assembler->imm_count; + fs->uses_imms = assembler->imm_count; + debug_printf("r300: fs: %d total constants, " + "%d from user and %d from immediates\n", consts->count, + consts->user_count, assembler->imm_count); + r3xx_fs_finalize(fs, assembler); + if (is_r500) { + r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler); + } + + tgsi_dump(fs->state.tokens, 0); + /* XXX finish r300 dumper too */ + if (is_r500) { + r5xx_fs_dump((struct r5xx_fragment_shader*)fs); + } + + tgsi_parse_free(&parser); + FREE(assembler); +} diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h new file mode 100644 index 00000000000..18deb7a05e4 --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.h @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_FS_H +#define R300_FS_H + +#include "tgsi/tgsi_dump.h" + +#include "r300_context.h" +#include "r3xx_fs.h" +#include "r5xx_fs.h" + +void r300_translate_fragment_shader(struct r300_context* r300, + struct r300_fragment_shader* fs); + + #endif /* R300_FS_H */ diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h new file mode 100644 index 00000000000..be4be9465e6 --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs_inlines.h @@ -0,0 +1,158 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_FS_INLINES_H +#define R300_FS_INLINES_H + +#include "tgsi/tgsi_parse.h" + +#include "r300_context.h" +#include "r300_debug.h" +#include "r300_reg.h" +#include "r300_screen.h" +#include "r300_shader_inlines.h" + +/* Temporary struct used to hold assembly state while putting together + * fragment programs. */ +struct r300_fs_asm { + /* Pipe context. */ + struct r300_context* r300; + /* Number of colors. */ + unsigned color_count; + /* Number of texcoords. */ + unsigned tex_count; + /* Offset for temporary registers. Inputs and temporaries have no + * distinguishing markings, so inputs start at 0 and the first usable + * temporary register is after all inputs. */ + unsigned temp_offset; + /* Number of requested temporary registers. */ + unsigned temp_count; + /* Offset for immediate constants. Neither R300 nor R500 can do four + * inline constants per source, so instead we copy immediates into the + * constant buffer. */ + unsigned imm_offset; + /* Number of immediate constants. */ + unsigned imm_count; + /* Are depth writes enabled? */ + boolean writes_depth; + /* Depth write offset. This is the TGSI output that corresponds to + * depth writes. */ + unsigned depth_output; +}; + +static INLINE void r300_fs_declare(struct r300_fs_asm* assembler, + struct tgsi_full_declaration* decl) +{ + switch (decl->Declaration.File) { + case TGSI_FILE_INPUT: + switch (decl->Semantic.SemanticName) { + case TGSI_SEMANTIC_COLOR: + assembler->color_count++; + break; + case TGSI_SEMANTIC_FOG: + case TGSI_SEMANTIC_GENERIC: + assembler->tex_count++; + break; + default: + debug_printf("r300: fs: Bad semantic declaration %d\n", + decl->Semantic.SemanticName); + break; + } + break; + case TGSI_FILE_OUTPUT: + /* Depth write. Mark the position of the output so we can + * identify it later. */ + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { + assembler->depth_output = decl->DeclarationRange.First; + } + break; + case TGSI_FILE_CONSTANT: + break; + case TGSI_FILE_TEMPORARY: + assembler->temp_count++; + break; + default: + debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); + break; + } + + assembler->temp_offset = assembler->color_count + assembler->tex_count; +} + +static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, + struct tgsi_src_register* src) +{ + switch (src->File) { + case TGSI_FILE_NULL: + return 0; + case TGSI_FILE_INPUT: + /* XXX may be wrong */ + return src->Index; + break; + case TGSI_FILE_TEMPORARY: + return src->Index + assembler->temp_offset; + break; + case TGSI_FILE_IMMEDIATE: + return (src->Index + assembler->imm_offset) | (1 << 8); + break; + case TGSI_FILE_CONSTANT: + /* XXX magic */ + return src->Index | (1 << 8); + break; + default: + debug_printf("r300: fs: Unimplemented src %d\n", src->File); + break; + } + return 0; +} + +static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, + struct tgsi_dst_register* dst) +{ + switch (dst->File) { + case TGSI_FILE_NULL: + /* This happens during KIL instructions. */ + return 0; + break; + case TGSI_FILE_OUTPUT: + return 0; + break; + case TGSI_FILE_TEMPORARY: + return dst->Index + assembler->temp_offset; + break; + default: + debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); + break; + } + return 0; +} + +static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, + struct tgsi_dst_register* dst) +{ + return (assembler->writes_depth && + (dst->File == TGSI_FILE_OUTPUT) && + (dst->Index == assembler->depth_output)); +} + +#endif /* R300_FS_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_shader_inlines.h b/src/gallium/drivers/r300/r300_shader_inlines.h new file mode 100644 index 00000000000..a04f45b03e2 --- /dev/null +++ b/src/gallium/drivers/r300/r300_shader_inlines.h @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_SHADER_INLINES_H +#define R300_SHADER_INLINES_H + +/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're + * not using enough of it. */ +static const struct tgsi_full_src_register r300_constant_zero = { + .SrcRegister.Extended = TRUE, + .SrcRegister.File = TGSI_FILE_NULL, + .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, + .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, +}; + +static const struct tgsi_full_src_register r300_constant_one = { + .SrcRegister.Extended = TRUE, + .SrcRegister.File = TGSI_FILE_NULL, + .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE, + .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE, + .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE, + .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE, +}; + +#endif /* R300_SHADER_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 01e2b511534..d70ef6ba28f 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -29,7 +29,7 @@ #include "r300_context.h" #include "r300_reg.h" #include "r300_state_inlines.h" -#include "r300_state_shader.h" +#include "r300_fs.h" /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ @@ -283,14 +283,12 @@ static void* r300_create_fs_state(struct pipe_context* pipe, const struct pipe_shader_state* shader) { struct r300_context* r300 = r300_context(pipe); - struct r3xx_fragment_shader* fs = NULL; + struct r300_fragment_shader* fs = NULL; if (r300_screen(r300->context.screen)->caps->is_r500) { - fs = - (struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader); + fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader); } else { - fs = - (struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader); + fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader); } /* Copy state directly into shader. */ @@ -306,7 +304,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe, static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); - struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; + struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; if (fs == NULL) { r300->fs = NULL; @@ -324,7 +322,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) /* Delete fragment shader state. */ static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) { - struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; + struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; FREE(fs->state.tokens); FREE(shader); } diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index c9e2dff14ed..75b50969190 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -151,11 +151,11 @@ validate: /* Fragment shader setup */ if (caps->is_r500) { - r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader); - r300_emit_rs_block_state(r300, &r500_rs_block_clear_state); + r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader); + r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state); } else { - r300_emit_fragment_shader(r300, &r300_passthrough_fragment_shader); - r300_emit_rs_block_state(r300, &r300_rs_block_clear_state); + r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader); + r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state); } BEGIN_CS(26); @@ -291,11 +291,11 @@ validate: /* Fragment shader setup */ if (caps->is_r500) { - r500_emit_fragment_shader(r300, &r500_texture_fragment_shader); - r300_emit_rs_block_state(r300, &r500_rs_block_copy_state); + r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state); } else { - r300_emit_fragment_shader(r300, &r300_texture_fragment_shader); - r300_emit_rs_block_state(r300, &r300_rs_block_copy_state); + r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state); } BEGIN_CS(30); diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h index 9a4c39f58bd..d01f0b143f5 100644 --- a/src/gallium/drivers/r300/r300_surface.h +++ b/src/gallium/drivers/r300/r300_surface.h @@ -31,8 +31,8 @@ #include "r300_context.h" #include "r300_cs.h" #include "r300_emit.h" -#include "r300_state_shader.h" -#include "r300_state_tcl.h" +#include "r300_fs.h" +#include "r300_vs.h" #include "r300_state_inlines.h" static struct r300_blend_state blend_clear_state = { @@ -72,7 +72,7 @@ static struct r300_rs_state rs_clear_state = { .color_control = R300_SHADE_MODEL_FLAT, }; -static struct r300_rs_block r300_rs_block_clear_state = { +static struct r300_rs_block r3xx_rs_block_clear_state = { .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | R500_RS_SEL_T(R300_RS_SEL_K0) | R500_RS_SEL_R(R300_RS_SEL_K0) | @@ -82,7 +82,7 @@ static struct r300_rs_block r300_rs_block_clear_state = { .inst_count = 0, }; -static struct r300_rs_block r500_rs_block_clear_state = { +static struct r300_rs_block r5xx_rs_block_clear_state = { .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) | R500_RS_SEL_T(R500_RS_IP_PTR_K0) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | @@ -94,7 +94,7 @@ static struct r300_rs_block r500_rs_block_clear_state = { /* The following state is used for surface_copy only. */ -static struct r300_rs_block r300_rs_block_copy_state = { +static struct r300_rs_block r3xx_rs_block_copy_state = { .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | R500_RS_SEL_T(R300_RS_SEL_K0) | R500_RS_SEL_R(R300_RS_SEL_K0) | @@ -104,7 +104,7 @@ static struct r300_rs_block r300_rs_block_copy_state = { .inst_count = R300_RS_TX_OFFSET(0), }; -static struct r300_rs_block r500_rs_block_copy_state = { +static struct r300_rs_block r5xx_rs_block_copy_state = { .ip[0] = R500_RS_SEL_S(0) | R500_RS_SEL_T(1) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_vs.c index 8cf8250425e..f87435f9f07 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -20,7 +20,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "r300_state_tcl.h" +#include "r300_vs.h" static void r300_vs_declare(struct r300_vs_asm* assembler, struct tgsi_full_declaration* decl) @@ -403,7 +403,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0], assembler->tab[1], assembler->tab[2], assembler->tab[3]); - tgsi_dump(vs->state.tokens); + tgsi_dump(vs->state.tokens, 0); /* XXX finish r300 vertex shader dumper */ r300_vs_dump(vs); diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_vs.h index 2c8b586c2f5..165d7178122 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -20,15 +20,17 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef R300_STATE_TCL_H -#define R300_STATE_TCL_H +#ifndef R300_VS_H +#define R300_VS_H #include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.h" #include "r300_context.h" #include "r300_debug.h" #include "r300_reg.h" #include "r300_screen.h" +#include "r300_shader_inlines.h" /* XXX get these to r300_reg */ #define R300_PVS_DST_OPCODE(x) ((x) << 0) @@ -84,15 +86,6 @@ (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \ R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W) -static const struct tgsi_full_src_register r300_constant_zero = { - .SrcRegister.Extended = TRUE, - .SrcRegister.File = TGSI_FILE_NULL, - .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, - .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, - .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, - .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, -}; - /* Temporary struct used to hold assembly state while putting together * fragment programs. */ struct r300_vs_asm { @@ -161,4 +154,4 @@ static struct r300_vertex_shader r300_texture_vertex_shader = { void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs); -#endif /* R300_STATE_TCL_H */ +#endif /* R300_VS_H */ diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c new file mode 100644 index 00000000000..6e05d769773 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.c @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r3xx_fs.h" + +static INLINE uint32_t r3xx_rgb_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MOV: + return R300_ALU_OUTC_CMP; + default: + return 0; + } +} + +static INLINE uint32_t r3xx_alpha_op(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_MOV: + return R300_ALU_OUTA_CMP; + default: + return 0; + } +} + +static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_src_register* src, + struct tgsi_full_dst_register* dst, + unsigned op, + unsigned count) +{ + int i = fs->alu_instruction_count; + + fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + r3xx_rgb_op(op); + fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; + fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + r3xx_alpha_op(op); + fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; + + fs->alu_instruction_count++; +} + +void r3xx_fs_finalize(struct r300_fragment_shader* fs, + struct r300_fs_asm* assembler) +{ + fs->stack_size = assembler->temp_count + assembler->temp_offset + 1; +} + +void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_instruction* inst) +{ + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_MOV: + /* src0 -> src1 and src2 forced to zero */ + inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; + inst->FullSrcRegisters[2] = r300_constant_zero; + r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); + break; + case TGSI_OPCODE_END: + break; + default: + debug_printf("r300: fs: Bad opcode %d\n", + inst->Instruction.Opcode); + break; + } +} diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h new file mode 100644 index 00000000000..3da39ec2526 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.h @@ -0,0 +1,76 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R3XX_FS_H +#define R3XX_FS_H + +#include "r300_fs_inlines.h" + +static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = { + .alu_instruction_count = 1, + .tex_instruction_count = 0, + .indirections = 0, + .shader.stack_size = 1, + + .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + R300_ALU_OUTC_CMP, + .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, + .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + R300_ALU_OUTA_CMP, + .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +static struct r3xx_fragment_shader r3xx_texture_fragment_shader = { + .alu_instruction_count = 1, + .tex_instruction_count = 0, + .indirections = 0, + .shader.stack_size = 1, + + .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | + R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | + R300_ALU_OUTC_CMP, + .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | + R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, + .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | + R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | + R300_ALU_OUTA_CMP, + .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | + R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +void r3xx_fs_finalize(struct r300_fragment_shader* fs, + struct r300_fs_asm* assembler); + +void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_instruction* inst); + +#endif /* R3XX_FS_H */ diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r5xx_fs.c index cc7f6a7c4b0..99d826278ce 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r5xx_fs.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -20,104 +21,9 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "r300_state_shader.h" +#include "r5xx_fs.h" -static void r300_fs_declare(struct r300_fs_asm* assembler, - struct tgsi_full_declaration* decl) -{ - switch (decl->Declaration.File) { - case TGSI_FILE_INPUT: - switch (decl->Semantic.SemanticName) { - case TGSI_SEMANTIC_COLOR: - assembler->color_count++; - break; - case TGSI_SEMANTIC_FOG: - case TGSI_SEMANTIC_GENERIC: - assembler->tex_count++; - break; - default: - debug_printf("r300: fs: Bad semantic declaration %d\n", - decl->Semantic.SemanticName); - break; - } - break; - case TGSI_FILE_OUTPUT: - /* Depth write. Mark the position of the output so we can - * identify it later. */ - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { - assembler->depth_output = decl->DeclarationRange.First; - } - break; - case TGSI_FILE_CONSTANT: - break; - case TGSI_FILE_TEMPORARY: - assembler->temp_count++; - break; - default: - debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); - break; - } - - assembler->temp_offset = assembler->color_count + assembler->tex_count; -} - -static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, - struct tgsi_src_register* src) -{ - switch (src->File) { - case TGSI_FILE_NULL: - return 0; - case TGSI_FILE_INPUT: - /* XXX may be wrong */ - return src->Index; - break; - case TGSI_FILE_TEMPORARY: - return src->Index + assembler->temp_offset; - break; - case TGSI_FILE_IMMEDIATE: - return (src->Index + assembler->imm_offset) | (1 << 8); - break; - case TGSI_FILE_CONSTANT: - /* XXX magic */ - return src->Index | (1 << 8); - break; - default: - debug_printf("r300: fs: Unimplemented src %d\n", src->File); - break; - } - return 0; -} - -static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, - struct tgsi_dst_register* dst) -{ - switch (dst->File) { - case TGSI_FILE_NULL: - /* This happens during KIL instructions. */ - return 0; - break; - case TGSI_FILE_OUTPUT: - return 0; - break; - case TGSI_FILE_TEMPORARY: - return dst->Index + assembler->temp_offset; - break; - default: - debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); - break; - } - return 0; -} - -static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, - struct tgsi_dst_register* dst) -{ - return (assembler->writes_depth && - (dst->File == TGSI_FILE_OUTPUT) && - (dst->Index == assembler->depth_output)); -} - -static INLINE unsigned r500_fix_swiz(unsigned s) +static INLINE unsigned r5xx_fix_swiz(unsigned s) { /* For historical reasons, the swizzle values x, y, z, w, and 0 are * equivalent to the actual machine code, but 1 is not. Thus, we just @@ -129,13 +35,13 @@ static INLINE unsigned r500_fix_swiz(unsigned s) } } -static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg) +static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg) { if (reg->SrcRegister.Extended) { - return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | - (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | - (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | - (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9); + return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | + (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | + (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | + (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9); } else { return reg->SrcRegister.SwizzleX | (reg->SrcRegister.SwizzleY << 3) | @@ -144,7 +50,7 @@ static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg) } } -static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg) +static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg) { return reg->SrcRegister.SwizzleX | (reg->SrcRegister.SwizzleY << 2) | @@ -152,43 +58,23 @@ static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg) (reg->SrcRegister.SwizzleW << 6); } -static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg) +static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg) { /* Only the first 9 bits... */ - return (r500_rgba_swiz(reg) & 0x1ff) | + return (r5xx_rgba_swiz(reg) & 0x1ff) | (reg->SrcRegister.Negate ? (1 << 9) : 0) | (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); } -static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg) +static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg) { /* Only the last 3 bits... */ - return (r500_rgba_swiz(reg) >> 9) | + return (r5xx_rgba_swiz(reg) >> 9) | (reg->SrcRegister.Negate ? (1 << 9) : 0) | (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); } -static INLINE uint32_t r300_rgb_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_MOV: - return R300_ALU_OUTC_CMP; - default: - return 0; - } -} - -static INLINE uint32_t r300_alpha_op(unsigned op) -{ - switch (op) { - case TGSI_OPCODE_MOV: - return R300_ALU_OUTA_CMP; - default: - return 0; - } -} - -static INLINE uint32_t r500_rgba_op(unsigned op) +static INLINE uint32_t r5xx_rgba_op(unsigned op) { switch (op) { case TGSI_OPCODE_COS: @@ -224,7 +110,7 @@ static INLINE uint32_t r500_rgba_op(unsigned op) } } -static INLINE uint32_t r500_alpha_op(unsigned op) +static INLINE uint32_t r5xx_alpha_op(unsigned op) { switch (op) { case TGSI_OPCODE_COS: @@ -264,7 +150,7 @@ static INLINE uint32_t r500_alpha_op(unsigned op) } } -static INLINE uint32_t r500_tex_op(unsigned op) +static INLINE uint32_t r5xx_tex_op(unsigned op) { switch (op) { case TGSI_OPCODE_KIL: @@ -280,33 +166,8 @@ static INLINE uint32_t r500_tex_op(unsigned op) } } -static INLINE void r300_emit_maths(struct r300_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_src_register* src, - struct tgsi_full_dst_register* dst, - unsigned op, - unsigned count) -{ - int i = fs->alu_instruction_count; - - fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - r300_rgb_op(op); - fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | - R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; - fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - r300_alpha_op(op); - fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | - R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; - - fs->alu_instruction_count++; -} - /* Setup an ALU operation. */ -static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, +static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs, struct r300_fs_asm* assembler, struct tgsi_full_src_register* src, struct tgsi_full_dst_register* dst, @@ -343,9 +204,9 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister)); fs->instructions[i].inst5 |= R500_ALU_RGBA_SEL_C_SRC2 | - R500_SWIZ_RGBA_C(r500_rgb_swiz(&src[2])) | + R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) | R500_ALU_RGBA_ALPHA_SEL_C_SRC2 | - R500_SWIZ_ALPHA_C(r500_alpha_swiz(&src[2])); + R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2])); case 2: fs->instructions[i].inst1 |= R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); @@ -353,10 +214,10 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); fs->instructions[i].inst3 = R500_ALU_RGB_SEL_B_SRC1 | - R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1])); + R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1])); fs->instructions[i].inst4 |= R500_ALPHA_SEL_B_SRC1 | - R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])); + R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1])); case 1: case 0: default: @@ -366,20 +227,20 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister)); fs->instructions[i].inst3 |= R500_ALU_RGB_SEL_A_SRC0 | - R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0])); + R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0])); fs->instructions[i].inst4 |= R500_ALPHA_SEL_A_SRC0 | - R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])); + R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0])); break; } - fs->instructions[i].inst4 |= r500_alpha_op(op); - fs->instructions[i].inst5 |= r500_rgba_op(op); + fs->instructions[i].inst4 |= r5xx_alpha_op(op); + fs->instructions[i].inst5 |= r5xx_rgba_op(op); fs->instruction_count++; } -static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, +static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs, struct r300_fs_asm* assembler, struct tgsi_full_src_register* src, struct tgsi_full_dst_register* dst, @@ -392,10 +253,10 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, R500_INST_TEX_SEM_WAIT; fs->instructions[i].inst1 = R500_TEX_ID(0) | R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED | - r500_tex_op(op); + r5xx_tex_op(op); fs->instructions[i].inst2 = R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) | - R500_SWIZ_TEX_STRQ(r500_strq_swiz(src)) | + R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) | R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) | R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; @@ -412,37 +273,24 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, src[0].SrcRegister.File = TGSI_FILE_TEMPORARY; src[1] = src[0]; - src[2] = r500_constant_zero; - r500_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3); + src[2] = r300_constant_zero; + r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3); } else { fs->instruction_count++; } } -static void r300_fs_instruction(struct r300_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_instruction* inst) +void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, + struct r300_fs_asm* assembler) { - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_MOV: - /* src0 -> src1 and src2 forced to zero */ - inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[2] = r500_constant_zero; - r300_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - break; - case TGSI_OPCODE_END: - break; - default: - debug_printf("r300: fs: Bad opcode %d\n", - inst->Instruction.Opcode); - break; - } + /* XXX should this just go with OPCODE_END? */ + fs->instructions[fs->instruction_count - 1].inst0 |= + R500_INST_LAST; } -static void r500_fs_instruction(struct r500_fragment_shader* fs, - struct r300_fs_asm* assembler, - struct tgsi_full_instruction* inst) +void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_instruction* inst) { /* Switch between opcodes. When possible, prefer using the official * AMD/ATI names for opcodes, please, as it facilitates using the @@ -465,7 +313,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, case TGSI_OPCODE_DDX: case TGSI_OPCODE_DDY: case TGSI_OPCODE_FRC: - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1); break; @@ -486,7 +334,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, /* Fall through */ case TGSI_OPCODE_DP3: case TGSI_OPCODE_DP4: - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2); break; @@ -496,7 +344,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2]; inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0]; inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3]; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); break; @@ -510,18 +358,18 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, /* Force src0 to one, move all registers over */ inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1]; inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[0] = r500_constant_one; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + inst->FullSrcRegisters[0] = r300_constant_one; + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); break; case TGSI_OPCODE_MUL: /* Force our src2 to zero */ - inst->FullSrcRegisters[2] = r500_constant_zero; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + inst->FullSrcRegisters[2] = r300_constant_zero; + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); break; case TGSI_OPCODE_MAD: - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); break; @@ -534,8 +382,8 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, case TGSI_OPCODE_SWZ: /* src0 -> src1 and src2 forced to zero */ inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; - inst->FullSrcRegisters[2] = r500_constant_zero; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + inst->FullSrcRegisters[2] = r300_constant_zero; + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); break; @@ -550,7 +398,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, inst->FullDstRegisters[0].DstRegister.Index = assembler->temp_count; inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); inst->FullSrcRegisters[2].SrcRegister.Index = assembler->temp_count; @@ -563,7 +411,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, inst->FullSrcRegisters[0].SrcRegister.Negate = !(inst->FullSrcRegisters[0].SrcRegister.Negate); inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); break; case TGSI_OPCODE_POW: @@ -576,7 +424,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, inst->FullDstRegisters[0].DstRegister.Index = assembler->temp_count; inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1); inst->FullSrcRegisters[0].SrcRegister.Index = assembler->temp_count; @@ -585,11 +433,11 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - inst->FullSrcRegisters[2] = r500_constant_zero; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + inst->FullSrcRegisters[2] = r300_constant_zero; + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3); inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, + r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1); break; @@ -598,7 +446,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, case TGSI_OPCODE_TEX: case TGSI_OPCODE_TXB: case TGSI_OPCODE_TXP: - r500_emit_tex(fs, assembler, &inst->FullSrcRegisters[0], + r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0], &inst->FullDstRegisters[0], inst->Instruction.Opcode); break; @@ -617,102 +465,3 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP; } } - -static void r300_fs_finalize(struct r3xx_fragment_shader* fs, - struct r300_fs_asm* assembler) -{ - fs->stack_size = assembler->temp_count + assembler->temp_offset + 1; -} - -static void r500_fs_finalize(struct r500_fragment_shader* fs, - struct r300_fs_asm* assembler) -{ - /* XXX should this just go with OPCODE_END? */ - fs->instructions[fs->instruction_count - 1].inst0 |= - R500_INST_LAST; -} - -void r300_translate_fragment_shader(struct r300_context* r300, - struct r3xx_fragment_shader* fs) -{ - struct tgsi_parse_context parser; - int i; - boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; - struct r300_constant_buffer* consts = - &r300->shader_constants[PIPE_SHADER_FRAGMENT]; - - struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm); - if (assembler == NULL) { - return; - } - /* Setup starting offset for immediates. */ - assembler->imm_offset = consts->user_count; - /* Enable depth writes, if needed. */ - assembler->writes_depth = fs->info.writes_z; - - /* Make sure we start at the beginning of the shader. */ - if (is_r500) { - ((struct r500_fragment_shader*)fs)->instruction_count = 0; - } - - tgsi_parse_init(&parser, fs->state.tokens); - - while (!tgsi_parse_end_of_tokens(&parser)) { - tgsi_parse_token(&parser); - - /* This is seriously the lamest way to create fragment programs ever. - * I blame TGSI. */ - switch (parser.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - /* Allocated registers sitting at the beginning - * of the program. */ - r300_fs_declare(assembler, &parser.FullToken.FullDeclaration); - break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - debug_printf("r300: Emitting immediate to constant buffer, " - "position %d\n", - assembler->imm_offset + assembler->imm_count); - /* I am not amused by the length of these. */ - for (i = 0; i < 4; i++) { - consts->constants[assembler->imm_offset + - assembler->imm_count][i] = - parser.FullToken.FullImmediate.u.ImmediateFloat32[i] - .Float; - } - assembler->imm_count++; - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - if (is_r500) { - r500_fs_instruction((struct r500_fragment_shader*)fs, - assembler, &parser.FullToken.FullInstruction); - } else { - r300_fs_instruction((struct r300_fragment_shader*)fs, - assembler, &parser.FullToken.FullInstruction); - } - break; - } - } - - debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", - assembler->tex_count, assembler->color_count, - assembler->tex_count + assembler->color_count); - - consts->count = consts->user_count + assembler->imm_count; - fs->uses_imms = assembler->imm_count; - debug_printf("r300: fs: %d total constants, " - "%d from user and %d from immediates\n", consts->count, - consts->user_count, assembler->imm_count); - r300_fs_finalize(fs, assembler); - if (is_r500) { - r500_fs_finalize((struct r500_fragment_shader*)fs, assembler); - } - - tgsi_dump(fs->state.tokens); - /* XXX finish r300 dumper too */ - if (is_r500) { - r500_fs_dump((struct r500_fragment_shader*)fs); - } - - tgsi_parse_free(&parser); - FREE(assembler); -} diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r5xx_fs.h index b6087404cef..629e587be4d 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r5xx_fs.h @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -20,15 +21,10 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef R300_STATE_SHADER_H -#define R300_STATE_SHADER_H +#ifndef R5XX_FS_H +#define R5XX_FS_H -#include "tgsi/tgsi_parse.h" - -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" +#include "r300_fs_inlines.h" /* XXX this all should find its way back to r300_reg */ /* Swizzle tools */ @@ -59,78 +55,7 @@ #define R500_ALU_OMASK(x) ((x) << 15) #define R500_W_OMASK (1 << 31) -/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're - * not using enough of it. */ -static const struct tgsi_full_src_register r500_constant_zero = { - .SrcRegister.Extended = TRUE, - .SrcRegister.File = TGSI_FILE_NULL, - .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, - .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, - .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, - .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, -}; - -static const struct tgsi_full_src_register r500_constant_one = { - .SrcRegister.Extended = TRUE, - .SrcRegister.File = TGSI_FILE_NULL, - .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE, - .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE, - .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE, - .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE, -}; - -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_fs_asm { - /* Pipe context. */ - struct r300_context* r300; - /* Number of colors. */ - unsigned color_count; - /* Number of texcoords. */ - unsigned tex_count; - /* Offset for temporary registers. Inputs and temporaries have no - * distinguishing markings, so inputs start at 0 and the first usable - * temporary register is after all inputs. */ - unsigned temp_offset; - /* Number of requested temporary registers. */ - unsigned temp_count; - /* Offset for immediate constants. Neither R300 nor R500 can do four - * inline constants per source, so instead we copy immediates into the - * constant buffer. */ - unsigned imm_offset; - /* Number of immediate constants. */ - unsigned imm_count; - /* Are depth writes enabled? */ - boolean writes_depth; - /* Depth write offset. This is the TGSI output that corresponds to - * depth writes. */ - unsigned depth_output; -}; - -void r300_translate_fragment_shader(struct r300_context* r300, - struct r3xx_fragment_shader* fs); - -static struct r300_fragment_shader r300_passthrough_fragment_shader = { - .alu_instruction_count = 1, - .tex_instruction_count = 0, - .indirections = 0, - .shader.stack_size = 1, - - .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - R300_ALU_OUTC_CMP, - .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | - R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, - .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - R300_ALU_OUTA_CMP, - .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | - R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r500_fragment_shader r500_passthrough_fragment_shader = { +static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = { .shader.stack_size = 0, .instruction_count = 1, .instructions[0].inst0 = R500_INST_TYPE_OUT | @@ -156,27 +81,7 @@ static struct r500_fragment_shader r500_passthrough_fragment_shader = { R500_ALU_RGBA_A_SWIZ_0, }; -static struct r300_fragment_shader r300_texture_fragment_shader = { - .alu_instruction_count = 1, - .tex_instruction_count = 0, - .indirections = 0, - .shader.stack_size = 1, - - .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | - R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | - R300_ALU_OUTC_CMP, - .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | - R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, - .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | - R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | - R300_ALU_OUTA_CMP, - .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | - R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r500_fragment_shader r500_texture_fragment_shader = { +static struct r5xx_fragment_shader r5xx_texture_fragment_shader = { .shader.stack_size = 1, .instruction_count = 2, .instructions[0].inst0 = R500_INST_TYPE_TEX | @@ -217,4 +122,11 @@ static struct r500_fragment_shader r500_texture_fragment_shader = { R500_ALU_RGBA_A_SWIZ_0, }; -#endif /* R300_STATE_SHADER_H */ +void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, + struct r300_fs_asm* assembler); + +void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, + struct r300_fs_asm* assembler, + struct tgsi_full_instruction* inst); + +#endif /* R5XX_FS_H */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 692deeb8fd3..be76f1d4135 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -87,6 +87,8 @@ softpipe_get_param(struct pipe_screen *screen, int param) return 8; /* max 128x128x128 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; /* max 4Kx4K */ + case PIPE_CAP_TGSI_CONT_SUPPORTED: + return 1; default: return 0; } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index adbd0cb7f0c..5de358dae93 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -744,7 +744,9 @@ shadow_compare(uint compare_func, break; } + /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; + rgba[3][j] = 1.0F; } diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 3a1409e95a7..643587ab427 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -451,11 +451,11 @@ void trace_dump_float(double value) } void trace_dump_bytes(const void *data, - long unsigned size) + size_t size) { static const char hex_table[16] = "0123456789ABCDEF"; const uint8_t *p = data; - long unsigned i; + size_t i; if (!dumping) return; diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 31ac70802f0..32592bab12f 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -91,7 +91,7 @@ void trace_dump_bool(int value); void trace_dump_int(long long int value); void trace_dump_uint(long long unsigned value); void trace_dump_float(double value); -void trace_dump_bytes(const void *data, long unsigned size); +void trace_dump_bytes(const void *data, size_t size); void trace_dump_string(const char *str); void trace_dump_enum(const char *value); void trace_dump_array_begin(void); @@ -130,7 +130,7 @@ void trace_dump_transfer_ptr(struct pipe_transfer *_transfer); #define trace_dump_array(_type, _obj, _size) \ do { \ - unsigned long idx; \ + size_t idx; \ trace_dump_array_begin(); \ for(idx = 0; idx < (_size); ++idx) { \ trace_dump_elem_begin(); \ @@ -142,7 +142,7 @@ void trace_dump_transfer_ptr(struct pipe_transfer *_transfer); #define trace_dump_struct_array(_type, _obj, _size) \ do { \ - unsigned long idx; \ + size_t idx; \ trace_dump_array_begin(); \ for(idx = 0; idx < (_size); ++idx) { \ trace_dump_elem_begin(); \ diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 23a2473b574..f9a24b611b5 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -36,12 +36,18 @@ void trace_dump_format(enum pipe_format format) { + if (!trace_dumping_enabled_locked()) + return; + trace_dump_enum(pf_name(format) ); } void trace_dump_block(const struct pipe_format_block *block) { + if (!trace_dumping_enabled_locked()) + return; + trace_dump_struct_begin("pipe_format_block"); trace_dump_member(uint, block, size); trace_dump_member(uint, block, width); @@ -52,6 +58,9 @@ void trace_dump_block(const struct pipe_format_block *block) static void trace_dump_reference(const struct pipe_reference *reference) { + if (!trace_dumping_enabled_locked()) + return; + trace_dump_struct_begin("pipe_reference"); trace_dump_member(int, &reference->count, count); trace_dump_struct_end(); @@ -60,6 +69,9 @@ static void trace_dump_reference(const struct pipe_reference *reference) void trace_dump_template(const struct pipe_texture *templat) { + if (!trace_dumping_enabled_locked()) + return; + if(!templat) { trace_dump_null(); return; @@ -95,6 +107,9 @@ void trace_dump_template(const struct pipe_texture *templat) void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -141,6 +156,9 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -160,6 +178,9 @@ void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) void trace_dump_viewport_state(const struct pipe_viewport_state *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -176,6 +197,9 @@ void trace_dump_viewport_state(const struct pipe_viewport_state *state) void trace_dump_scissor_state(const struct pipe_scissor_state *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -196,6 +220,9 @@ void trace_dump_clip_state(const struct pipe_clip_state *state) { unsigned i; + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -221,6 +248,9 @@ void trace_dump_clip_state(const struct pipe_clip_state *state) void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -238,6 +268,9 @@ void trace_dump_shader_state(const struct pipe_shader_state *state) { static char str[8192]; + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -259,6 +292,9 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ { unsigned i; + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -307,6 +343,9 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ void trace_dump_blend_state(const struct pipe_blend_state *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -336,6 +375,9 @@ void trace_dump_blend_state(const struct pipe_blend_state *state) void trace_dump_blend_color(const struct pipe_blend_color *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -351,6 +393,9 @@ void trace_dump_blend_color(const struct pipe_blend_color *state) void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) { + if (!trace_dumping_enabled_locked()) + return; + trace_dump_struct_begin("pipe_framebuffer_state"); trace_dump_member(uint, state, width); @@ -365,6 +410,9 @@ void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) void trace_dump_sampler_state(const struct pipe_sampler_state *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -395,6 +443,9 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state) void trace_dump_surface(const struct pipe_surface *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -423,6 +474,9 @@ void trace_dump_surface(const struct pipe_surface *state) void trace_dump_transfer(const struct pipe_transfer *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -454,6 +508,9 @@ void trace_dump_transfer(const struct pipe_transfer *state) void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; @@ -472,6 +529,9 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) void trace_dump_vertex_element(const struct pipe_vertex_element *state) { + if (!trace_dumping_enabled_locked()) + return; + if(!state) { trace_dump_null(); return; diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 63238ea46e9..c956a693a09 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -119,6 +119,10 @@ #define PIPE_OS_SOLARIS #endif +#if defined(__APPLE__) +#define PIPE_OS_APPLE +#endif + #if defined(_WIN32) || defined(WIN32) #define PIPE_OS_WINDOWS #endif diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 9924046cb2f..96030e788db 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -302,6 +302,7 @@ enum pipe_transfer_usage { #define PIPE_CAP_TEXTURE_MIRROR_CLAMP 24 #define PIPE_CAP_TEXTURE_MIRROR_REPEAT 25 #define PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS 26 +#define PIPE_CAP_TGSI_CONT_SUPPORTED 27 /** diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index c36bfe30ff8..e1e9b507a6d 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -112,7 +112,7 @@ dri_fill_in_modes(struct dri_screen *screen, stencil_bits_array[depth_buffer_factor++] = 0; screen->d_depth_bits_last = FALSE; } - if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, + if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) { depth_bits_array[depth_buffer_factor] = 24; diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/fakeglx.c index 85e7ecfb9e8..23777c76f6c 100644 --- a/src/gallium/state_trackers/glx/xlib/fakeglx.c +++ b/src/gallium/state_trackers/glx/xlib/fakeglx.c @@ -1820,7 +1820,7 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, if (!dpy || !config || !pixmap) return 0; - for (attr = attribList; *attr; attr++) { + for (attr = attribList; attr && *attr; attr++) { switch (*attr) { case GLX_TEXTURE_FORMAT_EXT: attr++; diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c index 662b5fbcd2a..9df1ab76526 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_context.c +++ b/src/gallium/state_trackers/wgl/shared/stw_context.c @@ -47,6 +47,23 @@ #include "stw_context.h" #include "stw_tls.h" + +static INLINE struct stw_context * +stw_context(GLcontext *glctx) +{ + if(!glctx) + return NULL; + assert(glctx->DriverCtx); + return (struct stw_context *)glctx->DriverCtx; +} + +static INLINE struct stw_context * +stw_current_context(void) +{ + GET_CURRENT_CONTEXT( glctx ); + return stw_context(glctx); +} + BOOL stw_copy_context( UINT_PTR hglrcSrc, @@ -99,6 +116,18 @@ stw_share_lists( return ret; } +static void +stw_viewport(GLcontext * glctx, GLint x, GLint y, + GLsizei width, GLsizei height) +{ + struct stw_context *ctx = (struct stw_context *)glctx->DriverCtx; + struct stw_framebuffer *fb; + + fb = stw_framebuffer_from_hdc( ctx->hdc ); + if(fb) + stw_framebuffer_update(fb); +} + UINT_PTR stw_create_layer_context( HDC hdc, @@ -158,6 +187,7 @@ stw_create_layer_context( goto no_st_ctx; ctx->st->ctx->DriverCtx = ctx; + ctx->st->ctx->Driver.Viewport = stw_viewport; pipe_mutex_lock( stw_dev->mutex ); ctx->hglrc = handle_table_add(stw_dev->ctx_table, ctx); @@ -194,11 +224,10 @@ stw_delete_context( pipe_mutex_unlock( stw_dev->mutex ); if (ctx) { - GLcontext *glctx = ctx->st->ctx; - GET_CURRENT_CONTEXT( glcurctx ); - + struct stw_context *curctx = stw_current_context(); + /* Unbind current if deleting current context. */ - if (glcurctx == glctx) + if (curctx == ctx) st_make_current( NULL, NULL, NULL ); st_destroy_context(ctx->st); @@ -230,13 +259,8 @@ stw_release_context( * current for this thread. We should check that and return False * if not the case. */ - { - GLcontext *glctx = ctx->st->ctx; - GET_CURRENT_CONTEXT( glcurctx ); - - if (glcurctx != glctx) - return FALSE; - } + if (ctx != stw_current_context()) + return FALSE; if (stw_make_current( NULL, 0 ) == FALSE) return FALSE; @@ -248,14 +272,9 @@ stw_release_context( UINT_PTR stw_get_current_context( void ) { - GET_CURRENT_CONTEXT( glcurctx ); struct stw_context *ctx; - if(!glcurctx) - return 0; - - ctx = (struct stw_context *)glcurctx->DriverCtx; - assert(ctx); + ctx = stw_current_context(); if(!ctx) return 0; @@ -265,14 +284,9 @@ stw_get_current_context( void ) HDC stw_get_current_dc( void ) { - GET_CURRENT_CONTEXT( glcurctx ); struct stw_context *ctx; - if(!glcurctx) - return NULL; - - ctx = (struct stw_context *)glcurctx->DriverCtx; - assert(ctx); + ctx = stw_current_context(); if(!ctx) return NULL; @@ -284,23 +298,24 @@ stw_make_current( HDC hdc, UINT_PTR hglrc ) { + struct stw_context *curctx; struct stw_context *ctx; - GET_CURRENT_CONTEXT( glcurctx ); struct stw_framebuffer *fb; if (!stw_dev) goto fail; - if (glcurctx != NULL) { - struct stw_context *curctx; - curctx = (struct stw_context *) glcurctx->DriverCtx; - + curctx = stw_current_context(); + if (curctx != NULL) { if (curctx->hglrc != hglrc) - st_flush(glcurctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + st_flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* Return if already current. */ - if (curctx->hglrc == hglrc && curctx->hdc == hdc) - return TRUE; + if (curctx->hglrc == hglrc && curctx->hdc == hdc) { + ctx = curctx; + fb = stw_framebuffer_from_hdc( hdc ); + goto success; + } } if (hdc == NULL || hglrc == 0) { @@ -344,7 +359,10 @@ stw_make_current( if(!st_make_current( ctx->st, fb->stfb, fb->stfb )) goto fail; - stw_framebuffer_resize(fb); +success: + assert(fb); + if(fb) + stw_framebuffer_update(fb); return TRUE; diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.c b/src/gallium/state_trackers/wgl/shared/stw_device.c index 1a6b29807d7..ce466241463 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_device.c +++ b/src/gallium/state_trackers/wgl/shared/stw_device.c @@ -30,6 +30,7 @@ #include "glapi/glthread.h" #include "util/u_debug.h" #include "pipe/p_screen.h" +#include "state_tracker/st_public.h" #ifdef DEBUG #include "trace/tr_screen.h" @@ -63,15 +64,39 @@ stw_flush_frontbuffer(struct pipe_screen *screen, { const struct stw_winsys *stw_winsys = stw_dev->stw_winsys; HDC hdc = (HDC)context_private; + struct stw_framebuffer *fb; + fb = stw_framebuffer_from_hdc( hdc ); + /* fb can be NULL if window was destroyed already */ + if (fb) { + pipe_mutex_lock( fb->mutex ); + +#if DEBUG + { + struct pipe_surface *surface2; + + if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_FRONT_LEFT, &surface2 )) + assert(0); + else + assert(surface2 == surface); + } +#endif + #ifdef DEBUG - if(stw_dev->trace_running) { - screen = trace_screen(screen)->screen; - surface = trace_surface(surface)->surface; - } + if(stw_dev->trace_running) { + screen = trace_screen(screen)->screen; + surface = trace_surface(surface)->surface; + } #endif + } stw_winsys->flush_frontbuffer(screen, surface, hdc); + + if(fb) { + stw_framebuffer_update(fb); + + pipe_mutex_unlock( fb->mutex ); + } } @@ -133,20 +158,13 @@ error1: boolean stw_init_thread(void) { - if (!stw_tls_init_thread()) - return FALSE; - - if (!stw_framebuffer_init_thread()) - return FALSE; - - return TRUE; + return stw_tls_init_thread(); } void stw_cleanup_thread(void) { - stw_framebuffer_cleanup_thread(); stw_tls_cleanup_thread(); } diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c index 58f18303191..7d0e8f46482 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c @@ -84,7 +84,7 @@ stw_framebuffer_destroy_locked( * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx */ -static LRESULT CALLBACK +LRESULT CALLBACK stw_call_window_proc( int nCode, WPARAM wParam, @@ -111,15 +111,10 @@ stw_call_window_proc( unsigned width = LOWORD( pParams->lParam ); unsigned height = HIWORD( pParams->lParam ); - /* FIXME: The mesa statetracker makes the assumptions that only - * one context is using the framebuffer, and that that context is the - * current one. However neither holds true, as WGL allows more than - * one context to be bound to the same drawable, and this function can - * be called from any thread. - */ pipe_mutex_lock( fb->mutex ); - if (fb->stfb) - st_resize_framebuffer( fb->stfb, width, height ); + fb->must_resize = TRUE; + fb->width = width; + fb->height = height; pipe_mutex_unlock( fb->mutex ); } } @@ -140,6 +135,31 @@ stw_call_window_proc( } +static void +stw_framebuffer_get_size( struct stw_framebuffer *fb ) +{ + unsigned width, height; + RECT rect; + + assert(fb->hWnd); + + GetClientRect( fb->hWnd, &rect ); + width = rect.right - rect.left; + height = rect.bottom - rect.top; + + if(width < 1) + width = 1; + if(height < 1) + height = 1; + + if(width != fb->width || height != fb->height) { + fb->must_resize = TRUE; + fb->width = width; + fb->height = height; + } +} + + /** * Create a new framebuffer object which will correspond to the given HDC. */ @@ -169,6 +189,8 @@ stw_framebuffer_create_locked( stw_pixelformat_visual(&fb->visual, pfi); + stw_framebuffer_get_size(fb); + pipe_mutex_init( fb->mutex ); fb->next = stw_dev->fb_head; @@ -178,32 +200,6 @@ stw_framebuffer_create_locked( } -static void -stw_framebuffer_get_size( struct stw_framebuffer *fb, GLuint *pwidth, GLuint *pheight ) -{ - GLuint width, height; - - if (fb->hWnd) { - RECT rect; - GetClientRect( fb->hWnd, &rect ); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } - else { - width = GetDeviceCaps( fb->hDC, HORZRES ); - height = GetDeviceCaps( fb->hDC, VERTRES ); - } - - if(width < 1) - width = 1; - if(height < 1) - height = 1; - - *pwidth = width; - *pheight = height; -} - - BOOL stw_framebuffer_allocate( struct stw_framebuffer *fb) @@ -213,7 +209,6 @@ stw_framebuffer_allocate( if(!fb->stfb) { const struct stw_pixelformat_info *pfi = fb->pfi; enum pipe_format colorFormat, depthFormat, stencilFormat; - GLuint width, height; colorFormat = pfi->color_format; @@ -229,16 +224,21 @@ stw_framebuffer_allocate( else stencilFormat = PIPE_FORMAT_NONE; - stw_framebuffer_get_size(fb, &width, &height); - + assert(fb->must_resize); + assert(fb->width); + assert(fb->height); + fb->stfb = st_create_framebuffer( &fb->visual, colorFormat, depthFormat, stencilFormat, - width, - height, + fb->width, + fb->height, (void *) fb ); + + // to notify the context + fb->must_resize = TRUE; } pipe_mutex_unlock( fb->mutex ); @@ -247,14 +247,29 @@ stw_framebuffer_allocate( } +/** + * Update the framebuffer's size if necessary. + */ void -stw_framebuffer_resize( +stw_framebuffer_update( struct stw_framebuffer *fb) { - GLuint width, height; assert(fb->stfb); - stw_framebuffer_get_size(fb, &width, &height); - st_resize_framebuffer(fb->stfb, width, height); + assert(fb->height); + assert(fb->width); + + /* XXX: It would be nice to avoid checking the size again -- in theory + * stw_call_window_proc would have cought the resize and stored the right + * size already, but unfortunately threads created before the DllMain is + * called don't get a DLL_THREAD_ATTACH notification, and there is no way + * to know of their existing without using the not very portable PSAPI. + */ + stw_framebuffer_get_size(fb); + + if(fb->must_resize) { + st_resize_framebuffer(fb->stfb, fb->width, fb->height); + fb->must_resize = FALSE; + } } @@ -407,6 +422,8 @@ stw_swap_buffers( stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc ); + stw_framebuffer_update(fb); + pipe_mutex_unlock( fb->mutex ); return TRUE; @@ -423,38 +440,3 @@ stw_swap_layer_buffers( return FALSE; } - - -boolean -stw_framebuffer_init_thread(void) -{ - struct stw_tls_data *tls_data; - - tls_data = stw_tls_get_data(); - if(!tls_data) - return FALSE; - - tls_data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, - stw_call_window_proc, - NULL, - GetCurrentThreadId()); - if(tls_data->hCallWndProcHook == NULL) - return FALSE; - - return TRUE; -} - -void -stw_framebuffer_cleanup_thread(void) -{ - struct stw_tls_data *tls_data; - - tls_data = stw_tls_get_data(); - if(!tls_data) - return; - - if(tls_data->hCallWndProcHook) { - UnhookWindowsHookEx(tls_data->hCallWndProcHook); - tls_data->hCallWndProcHook = NULL; - } -} diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h index e7fa51c3a81..759e06b8914 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h +++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h @@ -51,6 +51,11 @@ struct stw_framebuffer pipe_mutex mutex; struct st_framebuffer *stfb; + /* FIXME: Make this work for multiple contexts bound to the same framebuffer */ + boolean must_resize; + unsigned width; + unsigned height; + /** This is protected by stw_device::mutex, not the mutex above */ struct stw_framebuffer *next; }; @@ -65,7 +70,7 @@ stw_framebuffer_allocate( struct stw_framebuffer *fb ); void -stw_framebuffer_resize( +stw_framebuffer_update( struct stw_framebuffer *fb); void @@ -79,10 +84,4 @@ struct stw_framebuffer * stw_framebuffer_from_hdc( HDC hdc ); -boolean -stw_framebuffer_init_thread(void); - -void -stw_framebuffer_cleanup_thread(void); - #endif /* STW_FRAMEBUFFER_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.c b/src/gallium/state_trackers/wgl/shared/stw_tls.c index 0c18a52352c..4bd6a9289c9 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_tls.c +++ b/src/gallium/state_trackers/wgl/shared/stw_tls.c @@ -51,9 +51,23 @@ stw_tls_data_create() data = CALLOC_STRUCT(stw_tls_data); if (!data) - return NULL; + goto no_data; + + data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, + stw_call_window_proc, + NULL, + GetCurrentThreadId()); + if(data->hCallWndProcHook == NULL) + goto no_hook; + + TlsSetValue(tlsIndex, data); return data; + +no_hook: + FREE(data); +no_data: + return NULL; } boolean @@ -69,8 +83,6 @@ stw_tls_init_thread(void) if(!data) return FALSE; - TlsSetValue(tlsIndex, data); - return TRUE; } @@ -84,8 +96,16 @@ stw_tls_cleanup_thread(void) } data = (struct stw_tls_data *) TlsGetValue(tlsIndex); - TlsSetValue(tlsIndex, NULL); - FREE(data); + if(data) { + TlsSetValue(tlsIndex, NULL); + + if(data->hCallWndProcHook) { + UnhookWindowsHookEx(data->hCallWndProcHook); + data->hCallWndProcHook = NULL; + } + + FREE(data); + } } void @@ -110,12 +130,9 @@ stw_tls_get_data(void) if(!data) { /* DllMain is called with DLL_THREAD_ATTACH only by threads created after * the DLL is loaded by the process */ - data = stw_tls_data_create(); if(!data) return NULL; - - TlsSetValue(tlsIndex, data); } return data; diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.h b/src/gallium/state_trackers/wgl/shared/stw_tls.h index 6af8be70c9f..fbf8b1cbee4 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_tls.h +++ b/src/gallium/state_trackers/wgl/shared/stw_tls.h @@ -50,4 +50,10 @@ stw_tls_cleanup(void); struct stw_tls_data * stw_tls_get_data(void); +LRESULT CALLBACK +stw_call_window_proc( + int nCode, + WPARAM wParam, + LPARAM lParam ); + #endif /* STW_TLS_H */ diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile index a00ea3e2a4e..27a1990724d 100644 --- a/src/gallium/state_trackers/xorg/Makefile +++ b/src/gallium/state_trackers/xorg/Makefile @@ -1,29 +1,18 @@ -TARGET = libxorgtracker.a -CFILES = $(wildcard ./*.c) -OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES)) -GALLIUMDIR = ../.. -TOP = ../../../.. - +TOP = ../../../.. include $(TOP)/configs/current -CFLAGS = -DHAVE_CONFIG_H \ - -g -Wall -Wimplicit-function-declaration -fPIC \ - $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \ - -I$(GALLIUMDIR)/include \ - -I$(GALLIUMDIR)/auxiliary \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include \ - -I$(TOP)/src/egl/main - -############################################# - -.PHONY = all clean +LIBNAME = xorgtracker -all: $(TARGET) +LIBRARY_INCLUDES = \ + -DHAVE_CONFIG_H \ + $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -I$(TOP)/src/mesa/main -$(TARGET): $(OBJECTS) - ar rcs $(TARGET) $(OBJECTS) +C_SOURCES = $(wildcard ./*.c) -clean: - rm -rf $(OBJECTS) $(TARGET) +include ../../Makefile.template diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile index d9aa5d54e1d..d51cca8d213 100644 --- a/src/gallium/winsys/drm/intel/xorg/Makefile +++ b/src/gallium/winsys/drm/intel/xorg/Makefile @@ -1,36 +1,38 @@ TARGET = modesetting_drv.so CFILES = $(wildcard ./*.c) OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES)) -GALLIUMDIR = ../../../.. TOP = ../../../../../.. -include ${TOP}/configs/current +include $(TOP)/configs/current -CFLAGS = -DHAVE_CONFIG_H \ - -g -Wall -Wimplicit-function-declaration -fPIC \ - $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \ - -I../gem \ - -I${GALLIUMDIR}/include \ - -I${GALLIUMDIR}/drivers \ - -I${GALLIUMDIR}/auxiliary \ - -I${TOP}/src/mesa \ - -I$(TOP)/include \ - -I$(TOP)/src/egl/main +INCLUDES = \ + $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \ + -I../gem \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main LIBS = \ - $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \ - $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ + $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ + $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) +DRIVER_DEFINES = \ + -DHAVE_CONFIG_H + + ############################################# all default: $(TARGET) -$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS) +$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS) $(TOP)/bin/mklib -noprefix -o $@ \ $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel @@ -41,4 +43,14 @@ install: $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) + +############################################## + + +.c.o: + $(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@ + + +############################################## + .PHONY = all clean install diff --git a/src/glew/glew.c b/src/glew/glew.c index 24c6a726c38..aa2278f6c03 100644 --- a/src/glew/glew.c +++ b/src/glew/glew.c @@ -547,7 +547,7 @@ PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL; PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL; PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL; PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTURLAYERPROC __glewFramebufferTexturLayer = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = NULL; PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL; PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL; PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL; @@ -2739,7 +2739,7 @@ static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r; r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r; r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r; - r = ((glFramebufferTexturLayer = (PFNGLFRAMEBUFFERTEXTURLAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexturLayer")) == NULL) || r; + r = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == NULL) || r; r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r; r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r; r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r; diff --git a/src/glew/glewinfo.c b/src/glew/glewinfo.c index 13c6d05bd1f..da2b241deab 100644 --- a/src/glew/glewinfo.c +++ b/src/glew/glewinfo.c @@ -708,7 +708,7 @@ static void _glewInfo_GL_ARB_framebuffer_object (void) glewInfoFunc("glDeleteFramebuffers", glDeleteFramebuffers == NULL); glewInfoFunc("glDeleteRenderbuffers", glDeleteRenderbuffers == NULL); glewInfoFunc("glFramebufferRenderbuffer", glFramebufferRenderbuffer == NULL); - glewInfoFunc("glFramebufferTexturLayer", glFramebufferTexturLayer == NULL); + glewInfoFunc("glFramebufferTextureLayer", glFramebufferTextureLayer == NULL); glewInfoFunc("glFramebufferTexture1D", glFramebufferTexture1D == NULL); glewInfoFunc("glFramebufferTexture2D", glFramebufferTexture2D == NULL); glewInfoFunc("glFramebufferTexture3D", glFramebufferTexture3D == NULL); diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index fb31898db2d..f4865aecb1c 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -80,6 +80,8 @@ struct __GLXDRIdrawablePrivateRec { int have_fake_front; }; +static void dri2WaitX(__GLXDRIdrawable *pdraw); + static void dri2DestroyContext(__GLXDRIcontext *context, __GLXscreenConfigs *psc, Display *dpy) { @@ -215,6 +217,11 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region, DRI2BufferFrontLeft, DRI2BufferBackLeft); XFixesDestroyRegion(pdraw->psc->dpy, region); + + /* Refresh the fake front (if present) after we just damaged the real + * front. + */ + dri2WaitX(pdraw); } static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index ec3e69e4fe1..77471b8599c 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -869,6 +869,20 @@ PUBLIC void glXDestroyGLXPixmap(Display *dpy, GLXPixmap glxpixmap) req->glxpixmap = glxpixmap; UnlockDisplay(dpy); SyncHandle(); + +#ifdef GLX_DIRECT_RENDERING + { + int screen; + __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap, &screen); + __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; + + if (pdraw != NULL) { + (*pdraw->destroyDrawable) (pdraw); + __glxHashDelete(psc->drawHash, glxpixmap); + } + } +#endif } PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c index 56087aacd4e..cc4589f4d42 100644..120000 --- a/src/mesa/drivers/dri/i915/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -1,306 +1 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/enums.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "main/image.h" -#include "main/bufferobj.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_regions.h" -#include "intel_pixel.h" -#include "intel_buffer_objects.h" - -/* For many applications, the new ability to pull the source buffers - * back out of the GTT and then do the packing/conversion operations - * in software will be as much of an improvement as trying to get the - * blitter and/or texture engine to do the work. - * - * This step is gated on private backbuffers. - * - * Obviously the frontbuffer can't be pulled back, so that is either - * an argument for blit/texture readpixels, or for blitting to a - * temporary and then pulling that back. - * - * When the destination is a pbo, however, it's not clear if it is - * ever going to be pulled to main memory (though the access param - * will be a good hint). So it sounds like we do want to be able to - * choose between blit/texture implementation on the gpu and pullback - * and cpu-based copying. - * - * Unless you can magically turn client memory into a PBO for the - * duration of this call, there will be a cpu-based copying step in - * any case. - */ - - -static GLboolean -do_texture_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - struct intel_region *dest_region) -{ -#if 0 - struct intel_context *intel = intel_context(ctx); - intelScreenPrivate *screen = intel->intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (ctx->_ImageTransferState || - pack->SwapBytes || pack->LsbFirst || !pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); - - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: couldn't set dest %s/%s\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(format)); - return GL_FALSE; - } - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE(intel); - SET_STATE(i830, state); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); - - - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); - - - /* Set the 3d engine to draw into the destination region: - */ - - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ - - - /* Draw a single quad, no cliprects: - */ - intel->vtbl.meta_disable_cliprects(intel); - - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, x, x + width, y, y + height); - - intel->vtbl.leave_meta_state(intel); - } - UNLOCK_HARDWARE(intel); - - intel_region_wait_fence(ctx, dest_region); /* required by GL */ - return GL_TRUE; -#endif - - return GL_FALSE; -} - - - - -static GLboolean -do_blit_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, GLvoid * pixels) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *src = intel_readbuf_region(intel); - struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); - GLuint dst_offset; - GLuint rowLength; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s\n", __FUNCTION__); - - if (!src) - return GL_FALSE; - - if (dst) { - /* XXX This validation should be done by core mesa: - */ - if (!_mesa_validate_pbo_access(2, pack, width, height, 1, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); - return GL_TRUE; - } - } - else { - /* PBO only for now: - */ - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - not PBO\n", __FUNCTION__); - return GL_FALSE; - } - - - if (ctx->_ImageTransferState || - !intel_check_blit_format(src, format, type)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad format for blit\n", __FUNCTION__); - return GL_FALSE; - } - - if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: bad packing params\n", __FUNCTION__); - return GL_FALSE; - } - - if (pack->RowLength > 0) - rowLength = pack->RowLength; - else - rowLength = width; - - if (pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); - return GL_FALSE; - } - else { - rowLength = -rowLength; - } - - /* XXX 64-bit cast? */ - dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, - format, type, 0, 0, 0); - - - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects are correct. - */ - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - GLboolean all = (width * height * src->cpp == dst->Base.Size && - x == 0 && dst_offset == 0); - - dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int nbox = dPriv->numClipRects; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t src_rect; - int i; - - src_rect.x1 = dPriv->x + x; - src_rect.y1 = dPriv->y + dPriv->h - (y + height); - src_rect.x2 = src_rect.x1 + width; - src_rect.y2 = src_rect.y1 + height; - - - - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) - continue; - - intelEmitCopyBlit(intel, - src->cpp, - src->pitch, src->buffer, 0, src->tiling, - rowLength, dst_buffer, dst_offset, GL_FALSE, - rect.x1, - rect.y1, - rect.x1 - src_rect.x1, - rect.y2 - src_rect.y2, - rect.x2 - rect.x1, rect.y2 - rect.y1, - GL_COPY); - } - } - UNLOCK_HARDWARE(intel); - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - DONE\n", __FUNCTION__); - - return GL_TRUE; -} - -void -intelReadPixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, GLvoid * pixels) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - intelFlush(ctx); - - if (do_blit_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; - - if (do_texture_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - - _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); -} +../intel/intel_pixel_read.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 9712c387254..00a42111da0 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -23,6 +23,7 @@ DRIVER_SOURCES = \ intel_pixel_bitmap.c \ intel_pixel_copy.c \ intel_pixel_draw.c \ + intel_pixel_read.c \ intel_state.c \ intel_swapbuffers.c \ intel_tex.c \ diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 1b8bcc14ec0..3ef56a00683 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -635,7 +635,7 @@ static void brw_emit_indices(struct brw_context *brw) if (index_buffer == NULL) return; - ib_size = get_size(index_buffer->type) * index_buffer->count; + ib_size = get_size(index_buffer->type) * index_buffer->count - 1; /* Emit the indexbuffer packet: */ diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index bc7756ceab4..3ee56fe1b6c 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -855,12 +855,10 @@ void brw_math( struct brw_compile *p, void brw_dp_READ_16( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLuint scratch_offset ); void brw_dp_READ_4( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLboolean relAddr, GLuint location, GLuint bind_table_index ); @@ -875,7 +873,6 @@ void brw_dp_READ_4_vs( struct brw_compile *p, void brw_dp_WRITE_16( struct brw_compile *p, struct brw_reg src, - GLuint msg_reg_nr, GLuint scratch_offset ); /* If/else/endif. Works by manipulating the execution flags on each diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 60ea44f7a96..2a147fb8c38 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -865,9 +865,9 @@ void brw_math_16( struct brw_compile *p, */ void brw_dp_WRITE_16( struct brw_compile *p, struct brw_reg src, - GLuint msg_reg_nr, GLuint scratch_offset ) { + GLuint msg_reg_nr = 1; { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); @@ -877,7 +877,7 @@ void brw_dp_WRITE_16( struct brw_compile *p, brw_MOV(p, retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D), brw_imm_d(scratch_offset)); - + brw_pop_insn_state(p); } @@ -912,9 +912,9 @@ void brw_dp_WRITE_16( struct brw_compile *p, */ void brw_dp_READ_16( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLuint scratch_offset ) { + GLuint msg_reg_nr = 1; { brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); @@ -924,7 +924,7 @@ void brw_dp_READ_16( struct brw_compile *p, brw_MOV(p, retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D), brw_imm_d(scratch_offset)); - + brw_pop_insn_state(p); } @@ -958,21 +958,26 @@ void brw_dp_READ_16( struct brw_compile *p, */ void brw_dp_READ_4( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLboolean relAddr, GLuint location, GLuint bind_table_index ) { + /* XXX: relAddr not implemented */ + GLuint msg_reg_nr = 1; { + struct brw_reg b; brw_push_insn_state(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); - /* set message header global offset field (reg 0, element 2) */ - /* Note that grf[0] will be copied to mrf[1] implicitly by the SEND instr */ - brw_MOV(p, - retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_UD), - brw_imm_d(location)); + /* Setup MRF[1] with location/offset into const buffer */ + b = brw_message_reg(msg_reg_nr); + b = retype(b, BRW_REGISTER_TYPE_UD); + /* XXX I think we're setting all the dwords of MRF[1] to 'location'. + * when the docs say only dword[2] should be set. Hmmm. But it works. + */ + brw_MOV(p, b, brw_imm_ud(location)); brw_pop_insn_state(p); } @@ -988,7 +993,7 @@ void brw_dp_READ_4( struct brw_compile *p, dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW); brw_set_dest(insn, dest); - brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); + brw_set_src0(insn, brw_null_reg()); brw_set_dp_read_message(insn, bind_table_index, diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 4784254bc7d..67c39e509c5 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -244,6 +244,8 @@ static void emit_depthbuffer(struct brw_context *brw) return; } + assert(region->tiling != I915_TILING_X); + BEGIN_BATCH(len, IGNORE_CLIPRECTS); OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2)); OUT_BATCH(((region->pitch * region->cpp) - 1) | diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index ba03afd6c13..b284e623d01 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -194,7 +194,7 @@ static GLuint brw_flush_cmd( void ) struct brw_mi_flush flush; flush.opcode = CMD_MI_FLUSH; flush.pad = 0; - flush.flags = BRW_FLUSH_READ_CACHE | BRW_FLUSH_STATE_CACHE; + flush.flags = BRW_FLUSH_STATE_CACHE; return *(GLuint *)&flush; } diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index 14ab9042de7..4c3879f9faf 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -1057,7 +1057,6 @@ static void emit_spill( struct brw_wm_compile *c, */ brw_dp_WRITE_16(p, retype(vec16(brw_vec8_grf(0, 0)), BRW_REGISTER_TYPE_UW), - 1, slot); } @@ -1085,7 +1084,6 @@ static void emit_unspill( struct brw_wm_compile *c, brw_dp_READ_16(p, retype(vec16(reg), BRW_REGISTER_TYPE_UW), - 1, slot); } diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 6c071f121dd..6e6f2bac7be 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -446,7 +446,6 @@ static void fetch_constants(struct brw_wm_compile *c, /* need to fetch the constant now */ brw_dp_READ_4(p, c->current_const[i].reg, /* writeback dest */ - 1, /* msg_reg */ src->RelAddr, /* relative indexing? */ 16 * src->Index, /* byte offset */ SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */ diff --git a/src/mesa/drivers/dri/i965/intel_pixel_read.c b/src/mesa/drivers/dri/i965/intel_pixel_read.c new file mode 120000 index 00000000000..cc4589f4d42 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_pixel_read.c @@ -0,0 +1 @@ +../intel/intel_pixel_read.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 49198281316..75d315d82bd 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -108,6 +108,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; } + assert(src->tiling != I915_TILING_Y); + assert(dst->tiling != I915_TILING_Y); #ifndef I915 if (src->tiling != I915_TILING_NONE) { CMD |= XY_SRC_TILED; @@ -175,66 +177,6 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, UNLOCK_HARDWARE(intel); } - - - -void -intelEmitFillBlit(struct intel_context *intel, - GLuint cpp, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - uint32_t dst_tiling, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLuint color) -{ - GLuint BR13, CMD; - BATCH_LOCALS; - - dst_pitch *= cpp; - - switch (cpp) { - case 1: - BR13 = (0xF0 << 16); - CMD = XY_COLOR_BLT_CMD; - break; - case 2: - BR13 = (0xF0 << 16) | BR13_565; - CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = (0xF0 << 16) | BR13_8888; - CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - break; - default: - return; - } -#ifndef I915 - if (dst_tiling != I915_TILING_NONE) { - CMD |= XY_DST_TILED; - dst_pitch /= 4; - } -#endif - - DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", - __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); - - assert(w > 0); - assert(h > 0); - - BEGIN_BATCH(6, NO_LOOP_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13 | dst_pitch); - OUT_BATCH((y << 16) | x); - OUT_BATCH(((y + h) << 16) | (x + w)); - OUT_RELOC(dst_buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - dst_offset); - OUT_BATCH(color); - ADVANCE_BATCH(); -} - static GLuint translate_raster_op(GLenum logicop) { switch(logicop) { @@ -261,7 +203,7 @@ static GLuint translate_raster_op(GLenum logicop) /* Copy BitBlt */ -void +GLboolean intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, @@ -283,6 +225,19 @@ intelEmitCopyBlit(struct intel_context *intel, dri_bo *aper_array[3]; BATCH_LOCALS; + if (dst_tiling != I915_TILING_NONE) { + if (dst_offset & 4095) + return GL_FALSE; + if (dst_tiling == I915_TILING_Y) + return GL_FALSE; + } + if (src_tiling != I915_TILING_NONE) { + if (src_offset & 4095) + return GL_FALSE; + if (src_tiling == I915_TILING_Y) + return GL_FALSE; + } + /* do space/cliprects check before going any further */ do { aper_array[0] = intel->batch->buf; @@ -320,7 +275,7 @@ intelEmitCopyBlit(struct intel_context *intel, if (locked) UNLOCK_HARDWARE(intel); - return; + return GL_TRUE; } intel_batchbuffer_require_space(intel->batch, 8 * 4, NO_LOOP_CLIPRECTS); @@ -347,7 +302,7 @@ intelEmitCopyBlit(struct intel_context *intel, CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; break; default: - return; + return GL_FALSE; } #ifndef I915 @@ -362,7 +317,7 @@ intelEmitCopyBlit(struct intel_context *intel, #endif if (dst_y2 <= dst_y || dst_x2 <= dst_x) { - return; + return GL_TRUE; } assert(dst_x < dst_x2); @@ -384,6 +339,8 @@ intelEmitCopyBlit(struct intel_context *intel, ADVANCE_BATCH(); intel_batchbuffer_emit_mi_flush(intel->batch); + + return GL_TRUE; } @@ -596,7 +553,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) UNLOCK_HARDWARE(intel); } -void +GLboolean intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLuint cpp, GLubyte *src_bits, GLuint src_size, @@ -612,11 +569,18 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, int dwords = ALIGN(src_size, 8) / 4; uint32_t opcode, br13, blit_cmd; + if (dst_tiling != I915_TILING_NONE) { + if (dst_offset & 4095) + return GL_FALSE; + if (dst_tiling == I915_TILING_Y) + return GL_FALSE; + } + assert( logic_op - GL_CLEAR >= 0 ); assert( logic_op - GL_CLEAR < 0x10 ); if (w < 0 || h < 0) - return; + return GL_TRUE; dst_pitch *= cpp; @@ -673,4 +637,6 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, REFERENCES_CLIPRECTS ); intel_batchbuffer_emit_mi_flush(intel->batch); + + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h index 52065b13ed7..152fa3f17bf 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.h +++ b/src/mesa/drivers/dri/intel/intel_blit.h @@ -35,7 +35,8 @@ extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv, extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); -extern void intelEmitCopyBlit(struct intel_context *intel, +GLboolean +intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, dri_bo *src_buffer, @@ -50,16 +51,7 @@ extern void intelEmitCopyBlit(struct intel_context *intel, GLshort w, GLshort h, GLenum logicop ); -extern void intelEmitFillBlit(struct intel_context *intel, - GLuint cpp, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - uint32_t dst_tiling, - GLshort x, GLshort y, - GLshort w, GLshort h, GLuint color); - -void +GLboolean intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLuint cpp, GLubyte *src_bits, GLuint src_size, diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 1f10dec0a49..aed0e45a28f 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -300,14 +300,19 @@ intel_bufferobj_buffer(struct intel_context *intel, } if (intel_obj->buffer == NULL) { + void *sys_buffer = intel_obj->sys_buffer; + + /* only one of buffer and sys_buffer could be non-NULL */ intel_bufferobj_alloc_buffer(intel, intel_obj); + intel_obj->sys_buffer = NULL; + intel_bufferobj_subdata(&intel->ctx, GL_ARRAY_BUFFER_ARB, 0, intel_obj->Base.Size, - intel_obj->sys_buffer, + sys_buffer, &intel_obj->Base); - _mesa_free(intel_obj->sys_buffer); + _mesa_free(sys_buffer); intel_obj->sys_buffer = NULL; } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index df5c3fc1766..e7357e78c53 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -345,6 +345,23 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode) static void intelReadBuffer(GLcontext * ctx, GLenum mode) { + if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { + struct intel_context *const intel = intel_context(ctx); + const GLboolean was_front_buffer_reading = + intel->is_front_buffer_reading; + + intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + /* If we weren't front-buffer reading before but we are now, make sure + * that the front-buffer has actually been allocated. + */ + if (!was_front_buffer_reading && intel->is_front_buffer_reading) { + intel_update_renderbuffers(intel->driContext, + intel->driContext->driDrawablePriv); + } + } + if (ctx->ReadBuffer == ctx->DrawBuffer) { /* This will update FBO completeness status. * A framebuffer will be incomplete if the GL_READ_BUFFER setting diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 21f534d090b..273856fd2f0 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -264,7 +264,7 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) _mesa_Disable(GL_STENCIL_TEST); } - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); mask &= ~this_mask; } diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 41387646049..21d13b862b6 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -71,6 +71,8 @@ int INTEL_DEBUG = (0); #define DRIVER_DATE_GEM "GEM " DRIVER_DATE +static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); + static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -218,7 +220,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct intel_renderbuffer *stencil_rb; i = 0; - if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1]) + if ((intel->is_front_buffer_rendering || + intel->is_front_buffer_reading || + !intel_fb->color_rb[1]) && intel_fb->color_rb[0]) { attachments[i++] = __DRI_BUFFER_FRONT_LEFT; attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]); @@ -395,6 +399,15 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) return; if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) { + /* If we're rendering to the fake front buffer, make sure all the pending + * drawing has landed on the real front buffer. Otherwise when we + * eventually get to DRI2GetBuffersWithFormat the stale real front + * buffer contents will get copied to the new fake front buffer. + */ + if (intel->is_front_buffer_rendering) { + intel_flush(ctx, GL_FALSE); + } + intel_update_renderbuffers(driContext, driContext->driDrawablePriv); if (driContext->driDrawablePriv != driContext->driReadablePriv) intel_update_renderbuffers(driContext, driContext->driReadablePriv); @@ -729,6 +742,12 @@ intelInitContext(struct intel_context *intel, } intel->use_texture_tiling = driQueryOptionb(&intel->optionCache, "texture_tiling"); + if (intel->use_texture_tiling && + !intel->intelScreen->kernel_exec_fencing) { + fprintf(stderr, "No kernel support for execution fencing, " + "disabling texture tiling"); + intel->use_texture_tiling = GL_FALSE; + } intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z"); intel->prim.primitive = ~0; diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 7d3c80bb21c..36f33b6f31e 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -304,6 +304,14 @@ struct intel_context * easily. */ GLboolean is_front_buffer_rendering; + /** + * Track whether front-buffer is the current read target. + * + * This is closely associated with is_front_buffer_rendering, but may + * be set separately. The DRI2 fake front buffer must be referenced + * either way. + */ + GLboolean is_front_buffer_reading; GLboolean use_texture_tiling; GLboolean use_early_z; diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c index 1060fbd9e59..b00f8019dd7 100644 --- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -106,7 +106,7 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, _mesa_Enable(GL_VERTEX_ARRAY); intel_meta_set_default_texrect(intel); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index fcfed9e751d..a0d8f0c27af 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -101,6 +101,7 @@ intel_miptree_create_internal(struct intel_context *intel, struct intel_mipmap_tree * intel_miptree_create(struct intel_context *intel, GLenum target, + GLenum base_format, GLenum internal_format, GLuint first_level, GLuint last_level, @@ -115,7 +116,8 @@ intel_miptree_create(struct intel_context *intel, if (intel->use_texture_tiling && compress_byte == 0 && intel->intelScreen->kernel_exec_fencing) { if (IS_965(intel->intelScreen->deviceID) && - internal_format == GL_DEPTH_COMPONENT) + (base_format == GL_DEPTH_COMPONENT || + base_format == GL_DEPTH_STENCIL_EXT)) tiling = I915_TILING_Y; else tiling = I915_TILING_X; @@ -498,6 +500,7 @@ intel_miptree_image_copy(struct intel_context *intel, const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); GLuint i; + GLboolean success; if (dst->compressed) { GLuint alignment = intel_compressed_alignment(dst->internal_format); @@ -506,12 +509,26 @@ intel_miptree_image_copy(struct intel_context *intel, } for (i = 0; i < depth; i++) { - intel_region_copy(intel, - dst->region, dst_offset + dst_depth_offset[i], - 0, - 0, - src->region, src_offset + src_depth_offset[i], - 0, 0, width, height); + success = intel_region_copy(intel, + dst->region, dst_offset + dst_depth_offset[i], + 0, 0, + src->region, src_offset + src_depth_offset[i], + 0, 0, width, height, GL_COPY); + if (!success) { + GLubyte *src_ptr, *dst_ptr; + + src_ptr = intel_region_map(intel, src->region); + dst_ptr = intel_region_map(intel, dst->region); + + _mesa_copy_rect(dst_ptr + dst_offset + dst_depth_offset[i], + dst->cpp, + dst->pitch, + 0, 0, width, height, + src_ptr + src_offset + src_depth_offset[i], + src->pitch, + 0, 0); + intel_region_unmap(intel, src->region); + intel_region_unmap(intel, dst->region); + } } - } diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 3af9966827f..2a809cfda53 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -126,6 +126,7 @@ struct intel_mipmap_tree struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLenum target, + GLenum base_format, GLenum internal_format, GLuint first_level, GLuint last_level, diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index 36a684b3b85..da9ccb23f14 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -424,10 +424,8 @@ intelInitPixelFuncs(struct dd_function_table *functions) functions->Bitmap = intelBitmap; functions->CopyPixels = intelCopyPixels; functions->DrawPixels = intelDrawPixels; -#ifdef I915 - functions->ReadPixels = intelReadPixels; -#endif } + functions->ReadPixels = intelReadPixels; } void diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 80d3239189c..e678cd2c26f 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -194,7 +194,7 @@ do_blit_bitmap( GLcontext *ctx, struct gl_framebuffer *fb = ctx->DrawBuffer; GLfloat tmpColor[4]; GLubyte ubcolor[4]; - GLuint color8888, color565; + GLuint color; unsigned int num_cliprects; drm_clip_rect_t *cliprects; int x_off, y_off; @@ -232,8 +232,11 @@ do_blit_bitmap( GLcontext *ctx, UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]); UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]); - color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]); - color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]); + if (dst->cpp == 2) + color = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]); + else + color = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], + ubcolor[2], ubcolor[3]); if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F)) return GL_FALSE; @@ -307,21 +310,21 @@ do_blit_bitmap( GLcontext *ctx, fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) continue; - /* - */ - intelEmitImmediateColorExpandBlit( intel, - dst->cpp, - (GLubyte *)stipple, - sz, - (dst->cpp == 2) ? color565 : color8888, - dst->pitch, - dst->buffer, - 0, - dst->tiling, - box_x + px, - box_y + py, - w, h, - logic_op); + if (!intelEmitImmediateColorExpandBlit(intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color, + dst->pitch, + dst->buffer, + 0, + dst->tiling, + box_x + px, + box_y + py, + w, h, + logic_op)) { + return GL_FALSE; + } } } } @@ -495,7 +498,7 @@ intel_texture_bitmap(GLcontext * ctx, _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); intel_meta_set_default_texrect(intel); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index d50dd68092d..f523d3eead9 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -362,14 +362,16 @@ do_blit_copypixels(GLcontext * ctx, &clip_x, &clip_y, &clip_w, &clip_h)) continue; - intelEmitCopyBlit(intel, dst->cpp, - src->pitch, src->buffer, 0, src->tiling, - dst->pitch, dst->buffer, 0, dst->tiling, - clip_x + delta_x, clip_y + delta_y, /* srcx, srcy */ - clip_x, clip_y, /* dstx, dsty */ - clip_w, clip_h, - ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY); + if (!intel_region_copy(intel, + dst, 0, clip_x, clip_y, + src, 0, clip_x + delta_x, clip_y + delta_y, + clip_w, clip_h, + ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY)) { + DBG("%s: blit failure\n", __FUNCTION__); + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } } } out: diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index 46d27f1a93a..d79d625f770 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -180,7 +180,7 @@ intel_texture_drawpixels(GLcontext * ctx, _mesa_Enable(GL_VERTEX_ARRAY); intel_meta_set_default_texrect(intel); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); @@ -361,7 +361,7 @@ intel_stencil_drawpixels(GLcontext * ctx, _mesa_Enable(GL_VERTEX_ARRAY); intel_meta_set_default_texrect(intel); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c new file mode 100644 index 00000000000..8713463ace2 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -0,0 +1,324 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "main/glheader.h" +#include "main/enums.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/image.h" +#include "main/bufferobj.h" +#include "main/state.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" + +/* For many applications, the new ability to pull the source buffers + * back out of the GTT and then do the packing/conversion operations + * in software will be as much of an improvement as trying to get the + * blitter and/or texture engine to do the work. + * + * This step is gated on private backbuffers. + * + * Obviously the frontbuffer can't be pulled back, so that is either + * an argument for blit/texture readpixels, or for blitting to a + * temporary and then pulling that back. + * + * When the destination is a pbo, however, it's not clear if it is + * ever going to be pulled to main memory (though the access param + * will be a good hint). So it sounds like we do want to be able to + * choose between blit/texture implementation on the gpu and pullback + * and cpu-based copying. + * + * Unless you can magically turn client memory into a PBO for the + * duration of this call, there will be a cpu-based copying step in + * any case. + */ + + +static GLboolean +do_texture_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + struct intel_region *dest_region) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + intelScreenPrivate *screen = intel->intelScreen; + GLint pitch = pack->RowLength ? pack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + int destFormat, depthFormat, destPitch; + drm_clip_rect_t tmp; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (ctx->_ImageTransferState || + pack->SwapBytes || pack->LsbFirst || !pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + + if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: couldn't set dest %s/%s\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(type), + _mesa_lookup_enum_by_nr(format)); + return GL_FALSE; + } + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE(intel); + SET_STATE(i830, state); + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + + + intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, x, x + width, y, y + height); + + intel->vtbl.leave_meta_state(intel); + } + UNLOCK_HARDWARE(intel); + + intel_region_wait_fence(ctx, dest_region); /* required by GL */ + return GL_TRUE; +#endif + + return GL_FALSE; +} + + + + +static GLboolean +do_blit_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *src = intel_readbuf_region(intel); + struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); + GLuint dst_offset; + GLuint rowLength; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + if (!src) + return GL_FALSE; + + if (pack->BufferObj->Name) { + /* XXX This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, pack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + + if (ctx->_ImageTransferState || + !intel_check_blit_format(src, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: bad packing params\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->RowLength > 0) + rowLength = pack->RowLength; + else + rowLength = width; + + if (pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); + return GL_FALSE; + } + else { + rowLength = -rowLength; + } + + /* XXX 64-bit cast? */ + dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects are correct. + */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + GLboolean all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + + dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t src_rect; + int i; + + src_rect.x1 = dPriv->x + x; + src_rect.y1 = dPriv->y + dPriv->h - (y + height); + src_rect.x2 = src_rect.x1 + width; + src_rect.y2 = src_rect.y1 + height; + + + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) + continue; + + if (!intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, src->tiling, + rowLength, dst_buffer, dst_offset, GL_FALSE, + rect.x1, + rect.y1, + rect.x1 - src_rect.x1, + rect.y2 - src_rect.y2, + rect.x2 - rect.x1, rect.y2 - rect.y1, + GL_COPY)) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } + } + } + UNLOCK_HARDWARE(intel); + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + +void +intelReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(ctx); + +#ifdef I915 + if (do_blit_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (do_texture_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; +#else + (void)do_blit_readpixels; + (void)do_texture_readpixels; +#endif + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + /* Update Mesa state before calling down into _swrast_ReadPixels, as + * the spans code requires the computed buffer states to be up to date, + * but _swrast_ReadPixels only updates Mesa state after setting up + * the spans code. + */ + + if (ctx->NewState) + _mesa_update_state(ctx); + + _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); +} diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 7c3b4838366..4ce7f12e40d 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -116,7 +116,8 @@ intel_region_map(struct intel_context *intel, struct intel_region *region) if (region->pbo) intel_region_cow(intel, region); - if (intel->intelScreen->kernel_exec_fencing) + if (region->tiling != I915_TILING_NONE && + intel->intelScreen->kernel_exec_fencing) drm_intel_gem_bo_map_gtt(region->buffer); else dri_bo_map(region->buffer, GL_TRUE); @@ -131,7 +132,8 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region) { _DBG("%s %p\n", __FUNCTION__, region); if (!--region->map_refcount) { - if (intel->intelScreen->kernel_exec_fencing) + if (region->tiling != I915_TILING_NONE && + intel->intelScreen->kernel_exec_fencing) drm_intel_gem_bo_unmap_gtt(region->buffer); else dri_bo_unmap(region->buffer); @@ -358,19 +360,20 @@ intel_region_data(struct intel_context *intel, /* Copy rectangular sub-regions. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ -void +GLboolean intel_region_copy(struct intel_context *intel, struct intel_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, struct intel_region *src, GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) + GLuint srcx, GLuint srcy, GLuint width, GLuint height, + GLenum logicop) { _DBG("%s\n", __FUNCTION__); if (intel == NULL) - return; + return GL_FALSE; if (dst->pbo) { if (dstx == 0 && @@ -382,41 +385,12 @@ intel_region_copy(struct intel_context *intel, assert(src->cpp == dst->cpp); - intelEmitCopyBlit(intel, - dst->cpp, - src->pitch, src->buffer, src_offset, src->tiling, - dst->pitch, dst->buffer, dst_offset, dst->tiling, - srcx, srcy, dstx, dsty, width, height, - GL_COPY); -} - -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -void -intel_region_fill(struct intel_context *intel, - struct intel_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint color) -{ - _DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - if (dst->pbo) { - if (dstx == 0 && - dsty == 0 && width == dst->pitch && height == dst->height) - intel_region_release_pbo(intel, dst); - else - intel_region_cow(intel, dst); - } - - intelEmitFillBlit(intel, - dst->cpp, - dst->pitch, dst->buffer, dst_offset, dst->tiling, - dstx, dsty, width, height, color); + return intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, src_offset, src->tiling, + dst->pitch, dst->buffer, dst_offset, dst->tiling, + srcx, srcy, dstx, dsty, width, height, + logicop); } /* Attach to a pbo, discarding our data. Effectively zero-copy upload @@ -427,6 +401,8 @@ intel_region_attach_pbo(struct intel_context *intel, struct intel_region *region, struct intel_buffer_object *pbo) { + dri_bo *buffer; + if (region->pbo == pbo) return; @@ -447,10 +423,13 @@ intel_region_attach_pbo(struct intel_context *intel, region->buffer = NULL; } + /* make sure pbo has a buffer of its own */ + buffer = intel_bufferobj_buffer(intel, pbo, INTEL_WRITE_FULL); + region->pbo = pbo; region->pbo->region = region; - dri_bo_reference(pbo->buffer); - region->buffer = pbo->buffer; + dri_bo_reference(buffer); + region->buffer = buffer; } @@ -498,13 +477,13 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region) if (!was_locked) LOCK_HARDWARE(intel); - intelEmitCopyBlit(intel, - region->cpp, - region->pitch, region->buffer, 0, region->tiling, - region->pitch, pbo->buffer, 0, region->tiling, - 0, 0, 0, 0, - region->pitch, region->height, - GL_COPY); + assert(intelEmitCopyBlit(intel, + region->cpp, + region->pitch, pbo->buffer, 0, region->tiling, + region->pitch, region->buffer, 0, region->tiling, + 0, 0, 0, 0, + region->pitch, region->height, + GL_COPY)); if (!was_locked) UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index bd3c8e7325b..0d379bdc6e2 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -110,21 +110,15 @@ void intel_region_data(struct intel_context *intel, /* Copy rectangular sub-regions */ -void intel_region_copy(struct intel_context *intel, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - struct intel_region *src, - GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height); - -/* Fill a rectangular sub-region - */ -void intel_region_fill(struct intel_context *intel, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - GLuint width, GLuint height, GLuint color); +GLboolean +intel_region_copy(struct intel_context *intel, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height, + GLenum logicop); /* Helpers for zerocopy uploads, particularly texture image uploads: */ diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 70e0980ed6b..5b3fa9ead32 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -69,11 +69,7 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_DESC_END DRI_CONF_OPT_END -#ifdef I915 - DRI_CONF_TEXTURE_TILING(false) -#else - DRI_CONF_TEXTURE_TILING(true) -#endif + DRI_CONF_TEXTURE_TILING(false) DRI_CONF_OPT_BEGIN(early_z, bool, false) DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).") diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 260235b1eb1..0335c133071 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -107,6 +107,9 @@ do_copy_texsubimage(struct intel_context *intel, intelFlush(ctx); LOCK_HARDWARE(intel); { + drm_intel_bo *dst_bo = intel_region_buffer(intel, + intelImage->mt->region, + INTEL_WRITE_PART); GLuint image_offset = intel_miptree_image_offset(intelImage->mt, intelImage->face, intelImage->level); @@ -144,18 +147,21 @@ do_copy_texsubimage(struct intel_context *intel, src_pitch = src->pitch; } - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - src_pitch, - src->buffer, - 0, - src->tiling, - intelImage->mt->pitch, - intelImage->mt->region->buffer, - image_offset, - intelImage->mt->region->tiling, - x, y, dstx, dsty, width, height, - GL_COPY); + if (!intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_pitch, + src->buffer, + 0, + src->tiling, + intelImage->mt->pitch, + dst_bo, + image_offset, + intelImage->mt->region->tiling, + x, y, dstx, dsty, width, height, + GL_COPY)) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } } UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index e9a3823078a..c5f52208376 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -131,6 +131,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat); intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, + intelImage->base._BaseFormat, intelImage->base.InternalFormat, firstLevel, lastLevel, @@ -205,7 +206,7 @@ try_pbo_upload(struct intel_context *intel, GLuint src_offset, src_stride; GLuint dst_offset, dst_stride; - if (!pbo || + if (unpack->BufferObj->Name == 0 || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { DBG("%s: failure 1\n", __FUNCTION__); @@ -235,12 +236,15 @@ try_pbo_upload(struct intel_context *intel, INTEL_WRITE_FULL); - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - src_stride, src_buffer, src_offset, GL_FALSE, - dst_stride, dst_buffer, dst_offset, GL_FALSE, - 0, 0, 0, 0, width, height, - GL_COPY); + if (!intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_stride, src_buffer, src_offset, GL_FALSE, + dst_stride, dst_buffer, dst_offset, GL_FALSE, + 0, 0, 0, 0, width, height, + GL_COPY)) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } } UNLOCK_HARDWARE(intel); @@ -260,7 +264,7 @@ try_pbo_zcopy(struct intel_context *intel, GLuint src_offset, src_stride; GLuint dst_offset, dst_stride; - if (!pbo || + if (unpack->BufferObj->Name == 0 || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { DBG("%s: failure 1\n", __FUNCTION__); @@ -409,7 +413,9 @@ intelTexImage(GLcontext * ctx, * a miptree, so create one just for our level and store it in the image. * It'll get moved into the object miptree at validate time. */ - intelImage->mt = intel_miptree_create(intel, target, internalFormat, + intelImage->mt = intel_miptree_create(intel, target, + intelImage->base.TexFormat->BaseFormat, + internalFormat, level, level, width, height, depth, intelImage->base.TexFormat->TexelBytes, @@ -421,7 +427,7 @@ intelTexImage(GLcontext * ctx, */ if (dims <= 2 && intelImage->mt && - intel_buffer_object(unpack->BufferObj) && + unpack->BufferObj->Name != 0 && check_pbo_format(internalFormat, format, type, intelImage->base.TexFormat)) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index b5cb7597d16..a284d5475f4 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -199,6 +199,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) if (!intelObj->mt) { intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, + firstImage->base._BaseFormat, firstImage->base.InternalFormat, intelObj->firstLevel, intelObj->lastLevel, diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index df9dd83344c..fe173b601ad 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -213,6 +213,9 @@ void r200FlushElts(GLcontext *ctx) radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo); rmesa->radeon.tcl.elt_dma_bo = NULL; + if (R200_ELT_BUF_SZ > elt_used) + radeonReturnDmaRegion(rmesa, R200_ELT_BUF_SZ - elt_used); + if (R200_DEBUG & DEBUG_SYNC) { fprintf(stderr, "%s: Syncing\n", __FUNCTION__); radeonFinish( rmesa->radeon.glCtx ); @@ -233,21 +236,13 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, radeonEmitState(&rmesa->radeon); - rmesa->radeon.tcl.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, - 0, R200_ELT_BUF_SZ, 4, - RADEON_GEM_DOMAIN_GTT, 0); - rmesa->radeon.tcl.elt_dma_offset = 0; + radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo, + &rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4); rmesa->tcl.elt_used = min_nr * 2; - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.tcl.elt_dma_bo, - RADEON_GEM_DOMAIN_GTT, 0); - if (radeon_revalidate_bos(rmesa->radeon.glCtx) == GL_FALSE) - fprintf(stderr,"failure to revalidate BOs - badness\n"); - radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; - if (R200_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s: header prim %x \n", __FUNCTION__, primitive); diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 241390cef79..9a92a320797 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -357,6 +357,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* FIXME: When no memory manager is available we should set this * to some reasonable value based on texture memory pool size */ ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = 2048; ctx->Const.MaxTextureMaxAnisotropy = 16.0; diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 0b3398a730e..6560efdca39 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -196,7 +196,10 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) GLuint orig_mask = mask; if ( R200_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); + if (rmesa->radeon.sarea) + fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); + else + fprintf( stderr, "r200Clear %x radeon->sarea is NULL\n", mask); } { diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index f88ec877c5a..c7df4b2587e 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -585,6 +585,8 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) radeon_mipmap_level *lvl; int hastexture = 1; + if (!r200->state.texture.unit[i].unitneeded) + hastexture = 0; if (!t) hastexture = 0; else { diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 7aa8075aa70..b7d75426c57 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -270,10 +270,16 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) ctx->Const.MaxTextureMaxAnisotropy = 16.0; ctx->Const.MaxTextureLodBias = 16.0; - if (screen->chip_family >= CHIP_FAMILY_RV515) + if (screen->chip_family >= CHIP_FAMILY_RV515) { ctx->Const.MaxTextureLevels = 13; - else + ctx->Const.MaxCubeTextureLevels = 13; + ctx->Const.MaxTextureRectSize = 4096; + } + else { ctx->Const.MaxTextureLevels = 12; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = 2048; + } ctx->Const.MinPointSize = 1.0; ctx->Const.MinPointSizeAA = 1.0; @@ -412,6 +418,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 229b4387cae..46cba73e29c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -285,8 +285,10 @@ r100CreateContext( const __GLcontextModes *glVisual, /* FIXME: When no memory manager is available we should set this * to some reasonable value based on texture memory pool size */ - /* FIXME: does r100 support 2048x2048 texture ? */ ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = 2048; ctx->Const.MaxTextureMaxAnisotropy = 16.0; diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index e4ee2b99151..ac94789417e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -391,11 +391,15 @@ static int cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bo continue; /* already accounted this bo */ - if (write_domain && (write_domain == bo->space_accounted)) + if (write_domain && (write_domain == bo->space_accounted)) { + bos[i].new_accounted = bo->space_accounted; continue; + } - if (read_domains && ((read_domains << 16) == bo->space_accounted)) + if (read_domains && ((read_domains << 16) == bo->space_accounted)) { + bos[i].new_accounted = bo->space_accounted; continue; + } if (bo->space_accounted == 0) { if (write_domain == RADEON_GEM_DOMAIN_VRAM) diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 48b0d638183..0b91434b2ba 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -167,7 +167,7 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) size = MAX2(size, MAX_DMA_BUF_SZ); if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->dma.nr_released_bufs); if (rmesa->dma.flush) { rmesa->dma.flush(rmesa->glCtx); @@ -178,11 +178,7 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) rmesa->dma.nr_released_bufs = 0; } - if (rmesa->dma.current) { - radeon_bo_unmap(rmesa->dma.current); - radeon_bo_unref(rmesa->dma.current); - rmesa->dma.current = 0; - } + radeonReleaseDmaRegion(rmesa); again_alloc: rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, @@ -244,6 +240,17 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa, assert(rmesa->dma.current_used <= rmesa->dma.current->size); } +void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes) +{ + if (!rmesa->dma.current) + return; + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, return_bytes); + rmesa->dma.current_used -= return_bytes; + rmesa->dma.current_vertexptr = rmesa->dma.current_used; +} + void radeonReleaseDmaRegion(radeonContextPtr rmesa) { if (RADEON_DEBUG & DEBUG_IOCTL) diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.h b/src/mesa/drivers/dri/radeon/radeon_dma.h index 06e388fc1de..c6eabd3bc86 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.h +++ b/src/mesa/drivers/dri/radeon/radeon_dma.h @@ -39,6 +39,7 @@ void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count); void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, GLvoid * data, int size, int stride, int count); +void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes); void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); void radeonAllocDmaRegion(radeonContextPtr rmesa, struct radeon_bo **pbo, int *poffset, diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 429ad50a7d4..7dfed2c4560 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -512,7 +512,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, */ static void radeon_teximage( GLcontext *ctx, int dims, - GLint face, GLint level, + GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, GLsizei imageSize, @@ -529,6 +529,7 @@ static void radeon_teximage( GLint postConvWidth = width; GLint postConvHeight = height; GLuint texelBytes; + GLuint face = radeon_face_for_target(target); radeon_firevertices(rmesa); @@ -653,7 +654,7 @@ static void radeon_teximage( /* SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); + radeon_generate_mipmap(ctx, target, texObj); } } @@ -673,7 +674,7 @@ void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, + radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -686,9 +687,7 @@ void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -699,9 +698,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); } @@ -714,14 +711,14 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, + radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth, 0, format, type, pixels, packing, texObj, texImage, 0); } /** * Update a subregion of the given texture image. */ -static void radeon_texsubimage(GLcontext* ctx, int dims, int level, +static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, @@ -781,7 +778,7 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level, /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); + radeon_generate_mipmap(ctx, target, texObj); } } @@ -801,7 +798,7 @@ void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0, + radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -814,7 +811,7 @@ void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, + radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -827,7 +824,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, + radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); } @@ -841,7 +838,7 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0, + radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, format, type, pixels, packing, texObj, texImage, 0); } diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index 3b004a3ee25..34e0b8bc8d7 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -2218,7 +2218,7 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, if (!dpy || !config || !pixmap) return 0; - for (attr = attribList; *attr; attr++) { + for (attr = attribList; attr && *attr; attr++) { switch (*attr) { case GLX_TEXTURE_FORMAT_EXT: attr++; diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h index 93103fe878d..e79bbc2ac5f 100644 --- a/src/mesa/main/compiler.h +++ b/src/mesa/main/compiler.h @@ -468,9 +468,9 @@ do { \ #endif - +#ifndef Elements #define Elements(x) (sizeof(x)/sizeof(*(x))) - +#endif diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7a9c69ac90b..415e339cb80 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1260,6 +1260,24 @@ initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb) /** + * Check if the viewport/scissor size has not yet been initialized. + * Initialize the size if the given width and height are non-zero. + */ +void +_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height) +{ + if (!ctx->ViewportInitialized && width > 0 && height > 0) { + /* Note: set flag here, before calling _mesa_set_viewport(), to prevent + * potential infinite recursion. + */ + ctx->ViewportInitialized = GL_TRUE; + _mesa_set_viewport(ctx, 0, 0, width, height); + _mesa_set_scissor(ctx, 0, 0, width, height); + } +} + + +/** * Bind the given context to the given drawBuffer and readBuffer and * make it the current context for the calling thread. * We'll render into the drawBuffer and read pixels from the @@ -1376,25 +1394,24 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, ASSERT(drawBuffer->Height > 0); #endif - if (newCtx->FirstTimeCurrent) { - /* set initial viewport and scissor size now */ - _mesa_set_viewport(newCtx, 0, 0, - drawBuffer->Width, drawBuffer->Height); - _mesa_set_scissor(newCtx, 0, 0, - drawBuffer->Width, drawBuffer->Height ); - check_context_limits(newCtx); + if (drawBuffer) { + _mesa_check_init_viewport(newCtx, + drawBuffer->Width, drawBuffer->Height); } } - /* We can use this to help debug user's problems. Tell them to set - * the MESA_INFO env variable before running their app. Then the - * first time each context is made current we'll print some useful - * information. - */ if (newCtx->FirstTimeCurrent) { + check_context_limits(newCtx); + + /* We can use this to help debug user's problems. Tell them to set + * the MESA_INFO env variable before running their app. Then the + * first time each context is made current we'll print some useful + * information. + */ if (_mesa_getenv("MESA_INFO")) { _mesa_print_info(); } + newCtx->FirstTimeCurrent = GL_FALSE; } } diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index 6b3e1b2b973..0531ae8ee86 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -130,6 +130,9 @@ extern void _mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask); +extern void +_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height); + extern GLboolean _mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer, GLframebuffer *readBuffer ); diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index 11f9a82e7c9..7c62328fa95 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -958,8 +958,8 @@ LONGSTRING static const char enum_string_table[] = "GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV\0" "GL_MAX_VARYING_FLOATS\0" "GL_MAX_VARYING_FLOATS_ARB\0" - "GL_MAX_VERTEX_ATTRIBS\0" - "GL_MAX_VERTEX_ATTRIBS_ARB\0" + "GL_MAX_VERTEX_GENERIC_ATTRIBS\0" + "GL_MAX_VERTEX_GENERIC_ATTRIBS_ARB\0" "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS\0" "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB\0" "GL_MAX_VERTEX_UNIFORM_COMPONENTS\0" diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index 59def651a39..4ca7957ffad 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h @@ -83,28 +83,28 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */ -#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F)) +#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0)) /** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */ -#define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0F)) +#define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0)) /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */ -#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F)) +#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)) /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */ /* causes overflow: -#define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0F * (X))) - 1) / 2 ) +#define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0 * (X))) - 1) / 2 ) */ /* a close approximation: */ -#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0F * (X)) ) +#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) ) /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */ -#define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0F)) +#define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0)) /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */ -#define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0F * (X)) ) +#define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0 * (X)) ) #define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b))) diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 872982fa430..3dca09d9f28 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -1601,9 +1601,6 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, return; } - if (dstImage->ImageOffsets) - _mesa_free(dstImage->ImageOffsets); - /* Free old image data */ if (dstImage->Data) ctx->Driver.FreeTexImageData(ctx, dstImage); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 135eedbcabf..e52278a7b25 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2053,6 +2053,7 @@ struct gl_shader_state struct gl_shader_program *CurrentProgram; /**< The user-bound program */ /** Driver-selectable options: */ GLboolean EmitHighLevelInstructions; /**< IF/ELSE/ENDIF vs. BRA, etc. */ + GLboolean EmitContReturn; /**< Emit CONT/RET opcodes? */ GLboolean EmitCondCodes; /**< Use condition codes? */ GLboolean EmitComments; /**< Annotated instructions */ void *MemPool; @@ -2981,6 +2982,8 @@ struct __GLcontextRec GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ + GLboolean ViewportInitialized; /**< has viewport size been initialized? */ + GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ /** \name Derived state */ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 76b46d700b5..6e21066537b 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1250,6 +1250,8 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, * We allocate the array for 1D/2D textures too in order to avoid special- * case code in the texstore routines. */ + if (img->ImageOffsets) + _mesa_free(img->ImageOffsets); img->ImageOffsets = (GLuint *) _mesa_malloc(depth * sizeof(GLuint)); for (i = 0; i < depth; i++) { img->ImageOffsets[i] = i * width * height; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index a8390d30942..648fbc186bb 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -402,6 +402,7 @@ _mesa_init_shader_state(GLcontext * ctx) * are generated by the GLSL compiler. */ ctx->Shader.EmitHighLevelInstructions = GL_TRUE; + ctx->Shader.EmitContReturn = GL_TRUE; ctx->Shader.EmitCondCodes = GL_FALSE; ctx->Shader.EmitComments = GL_FALSE; ctx->Shader.Flags = get_shader_flags(); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6d693c9027a..24e99523869 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -75,6 +75,11 @@ const GLuint MAX_FOR_LOOP_UNROLL_COMPLEXITY = 256; static slang_ir_node * _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper); +static void +slang_substitute(slang_assemble_ctx *A, slang_operation *oper, + GLuint substCount, slang_variable **substOld, + slang_operation **substNew, GLboolean isLHS); + /** * Retrieves type information about an operation. @@ -326,6 +331,17 @@ sampler_to_texture_index(const slang_type_specifier_type type) } +/** helper to build a SLANG_OPER_IDENTIFIER node */ +static void +slang_operation_identifier(slang_operation *oper, + slang_assemble_ctx *A, + const char *name) +{ + oper->type = SLANG_OPER_IDENTIFIER; + oper->a_id = slang_atom_pool_atom(A->atoms, name); +} + + #define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) /** @@ -429,6 +445,56 @@ _slang_output_index(const char *name, GLenum target) } +/** + * Called when we begin code/IR generation for a new while/do/for loop. + */ +static void +push_loop(slang_assemble_ctx *A, slang_operation *loopOper, slang_ir_node *loopIR) +{ + A->LoopOperStack[A->LoopDepth] = loopOper; + A->LoopIRStack[A->LoopDepth] = loopIR; + A->LoopDepth++; +} + + +/** + * Called when we end code/IR generation for a new while/do/for loop. + */ +static void +pop_loop(slang_assemble_ctx *A) +{ + assert(A->LoopDepth > 0); + A->LoopDepth--; +} + + +/** + * Return pointer to slang_operation for the loop we're currently inside, + * or NULL if not in a loop. + */ +static const slang_operation * +current_loop_oper(const slang_assemble_ctx *A) +{ + if (A->LoopDepth > 0) + return A->LoopOperStack[A->LoopDepth - 1]; + else + return NULL; +} + + +/** + * Return pointer to slang_ir_node for the loop we're currently inside, + * or NULL if not in a loop. + */ +static slang_ir_node * +current_loop_ir(const slang_assemble_ctx *A) +{ + if (A->LoopDepth > 0) + return A->LoopIRStack[A->LoopDepth - 1]; + else + return NULL; +} + /**********************************************************************/ @@ -636,7 +702,7 @@ new_break(slang_ir_node *loopNode) assert(loopNode); assert(loopNode->Opcode == IR_LOOP); if (n) { - /* insert this node at head of linked list */ + /* insert this node at head of linked list of cont/break instructions */ n->List = loopNode->List; loopNode->List = n; } @@ -648,14 +714,15 @@ new_break(slang_ir_node *loopNode) * Make new IR_BREAK_IF_TRUE. */ static slang_ir_node * -new_break_if_true(slang_ir_node *loopNode, slang_ir_node *cond) +new_break_if_true(slang_assemble_ctx *A, slang_ir_node *cond) { + slang_ir_node *loopNode = current_loop_ir(A); slang_ir_node *n; assert(loopNode); assert(loopNode->Opcode == IR_LOOP); n = new_node1(IR_BREAK_IF_TRUE, cond); if (n) { - /* insert this node at head of linked list */ + /* insert this node at head of linked list of cont/break instructions */ n->List = loopNode->List; loopNode->List = n; } @@ -667,14 +734,16 @@ new_break_if_true(slang_ir_node *loopNode, slang_ir_node *cond) * Make new IR_CONT_IF_TRUE node. */ static slang_ir_node * -new_cont_if_true(slang_ir_node *loopNode, slang_ir_node *cond) +new_cont_if_true(slang_assemble_ctx *A, slang_ir_node *cond) { + slang_ir_node *loopNode = current_loop_ir(A); slang_ir_node *n; assert(loopNode); assert(loopNode->Opcode == IR_LOOP); n = new_node1(IR_CONT_IF_TRUE, cond); if (n) { - /* insert this node at head of linked list */ + n->Parent = loopNode; /* pointer to containing loop */ + /* insert this node at head of linked list of cont/break instructions */ n->List = loopNode->List; loopNode->List = n; } @@ -749,6 +818,7 @@ _slang_is_noop(const slang_operation *oper) /** * Recursively search tree for a node of the given type. */ +#if 0 static slang_operation * _slang_find_node_type(slang_operation *oper, slang_operation_type type) { @@ -762,13 +832,14 @@ _slang_find_node_type(slang_operation *oper, slang_operation_type type) } return NULL; } +#endif /** * Count the number of operations of the given time rooted at 'oper'. */ static GLuint -_slang_count_node_type(slang_operation *oper, slang_operation_type type) +_slang_count_node_type(const slang_operation *oper, slang_operation_type type) { GLuint i, count = 0; if (oper->type == type) { @@ -822,6 +893,37 @@ _slang_is_tail_return(const slang_operation *oper) } +/** + * Generate a variable declaration opeartion. + * I.e.: generate AST code for "bool flag = false;" + */ +static void +slang_generate_declaration(slang_assemble_ctx *A, + slang_variable_scope *scope, + slang_operation *decl, + slang_type_specifier_type type, + const char *name, + GLint initValue) +{ + slang_variable *var; + + assert(type == SLANG_SPEC_BOOL || + type == SLANG_SPEC_INT); + + decl->type = SLANG_OPER_VARIABLE_DECL; + + var = slang_variable_scope_grow(scope); + + slang_fully_specified_type_construct(&var->type); + + var->type.specifier.type = type; + var->a_name = slang_atom_pool_atom(A->atoms, name); + decl->a_id = var->a_name; + var->initializer = slang_operation_new(1); + slang_operation_literal_bool(var->initializer, initValue); +} + + static void slang_resolve_variable(slang_operation *oper) { @@ -832,6 +934,159 @@ slang_resolve_variable(slang_operation *oper) /** + * Rewrite AST code for "return expression;". + * + * We return values from functions by assinging the returned value to + * the hidden __retVal variable which is an extra 'out' parameter we add + * to the function signature. + * This code basically converts "return expr;" into "__retVal = expr; return;" + * + * \return the new AST code. + */ +static slang_operation * +gen_return_with_expression(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *blockOper, *assignOper; + + assert(oper->type == SLANG_OPER_RETURN); + + if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) { + slang_info_log_error(A->log, "illegal return expression"); + return NULL; + } + + blockOper = slang_operation_new(1); + blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; + blockOper->locals->outer_scope = oper->locals->outer_scope; + slang_operation_add_children(blockOper, 2); + + if (A->UseReturnFlag) { + /* Emit: + * { + * if (__notRetFlag) + * __retVal = expr; + * __notRetFlag = 0; + * } + */ + { + slang_operation *ifOper = slang_oper_child(blockOper, 0); + ifOper->type = SLANG_OPER_IF; + slang_operation_add_children(ifOper, 3); + { + slang_operation *cond = slang_oper_child(ifOper, 0); + cond->type = SLANG_OPER_IDENTIFIER; + cond->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); + } + { + slang_operation *elseOper = slang_oper_child(ifOper, 2); + elseOper->type = SLANG_OPER_VOID; + } + assignOper = slang_oper_child(ifOper, 1); + } + { + slang_operation *setOper = slang_oper_child(blockOper, 1); + setOper->type = SLANG_OPER_ASSIGN; + slang_operation_add_children(setOper, 2); + { + slang_operation *lhs = slang_oper_child(setOper, 0); + lhs->type = SLANG_OPER_IDENTIFIER; + lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); + } + { + slang_operation *rhs = slang_oper_child(setOper, 1); + slang_operation_literal_bool(rhs, GL_FALSE); + } + } + } + else { + /* Emit: + * { + * __retVal = expr; + * return_inlined; + * } + */ + assignOper = slang_oper_child(blockOper, 0); + { + slang_operation *returnOper = slang_oper_child(blockOper, 1); + returnOper->type = SLANG_OPER_RETURN_INLINED; + assert(returnOper->num_children == 0); + } + } + + /* __retVal = expression; */ + assignOper->type = SLANG_OPER_ASSIGN; + slang_operation_add_children(assignOper, 2); + { + slang_operation *lhs = slang_oper_child(assignOper, 0); + lhs->type = SLANG_OPER_IDENTIFIER; + lhs->a_id = slang_atom_pool_atom(A->atoms, "__retVal"); + } + { + slang_operation *rhs = slang_oper_child(assignOper, 1); + slang_operation_copy(rhs, &oper->children[0]); + } + + ///blockOper->locals->outer_scope = oper->locals->outer_scope; + + /*slang_print_tree(blockOper, 0);*/ + + return blockOper; +} + + +/** + * Rewrite AST code for "return;" (no expression). + */ +static slang_operation * +gen_return_without_expression(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *newRet; + + assert(oper->type == SLANG_OPER_RETURN); + + if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { + slang_info_log_error(A->log, "return statement requires an expression"); + return NULL; + } + + if (A->UseReturnFlag) { + /* Emit: + * __notRetFlag = 0; + */ + { + newRet = slang_operation_new(1); + newRet->locals->outer_scope = oper->locals->outer_scope; + newRet->type = SLANG_OPER_ASSIGN; + slang_operation_add_children(newRet, 2); + { + slang_operation *lhs = slang_oper_child(newRet, 0); + lhs->type = SLANG_OPER_IDENTIFIER; + lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); + } + { + slang_operation *rhs = slang_oper_child(newRet, 1); + slang_operation_literal_bool(rhs, GL_FALSE); + } + } + } + else { + /* Emit: + * return_inlined; + */ + newRet = slang_operation_new(1); + newRet->locals->outer_scope = oper->locals->outer_scope; + newRet->type = SLANG_OPER_RETURN_INLINED; + } + + /*slang_print_tree(newRet, 0);*/ + + return newRet; +} + + + + +/** * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions. */ static void @@ -866,7 +1121,8 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, GLuint i; v = _slang_variable_locate(oper->locals, id, GL_TRUE); if (!v) { - _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id); + if (_mesa_strcmp((char *) oper->a_id, "__notRetFlag")) + _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id); return; } @@ -896,62 +1152,24 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, break; case SLANG_OPER_RETURN: - /* do return replacement here too */ - assert(oper->num_children == 0 || oper->num_children == 1); - if (oper->num_children == 1 && !_slang_is_noop(&oper->children[0])) { - /* replace: - * return expr; - * with: - * __retVal = expr; - * return; - * then do substitutions on the assignment. - */ - slang_operation *blockOper, *assignOper, *returnOper; + { + slang_operation *newReturn; + /* generate new 'return' code' */ + if (slang_oper_child(oper, 0)->type == SLANG_OPER_VOID) + newReturn = gen_return_without_expression(A, oper); + else + newReturn = gen_return_with_expression(A, oper); - /* check if function actually has a return type */ - assert(A->CurFunction); - if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) { - slang_info_log_error(A->log, "illegal return expression"); + if (!newReturn) return; - } - - blockOper = slang_operation_new(1); - blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; - blockOper->num_children = 2; - blockOper->locals->outer_scope = oper->locals->outer_scope; - blockOper->children = slang_operation_new(2); - assignOper = blockOper->children + 0; - returnOper = blockOper->children + 1; - - assignOper->type = SLANG_OPER_ASSIGN; - assignOper->num_children = 2; - assignOper->locals->outer_scope = blockOper->locals; - assignOper->children = slang_operation_new(2); - assignOper->children[0].type = SLANG_OPER_IDENTIFIER; - assignOper->children[0].a_id = slang_atom_pool_atom(A->atoms, "__retVal"); - assignOper->children[0].locals->outer_scope = assignOper->locals; - - slang_operation_copy(&assignOper->children[1], - &oper->children[0]); - - returnOper->type = SLANG_OPER_RETURN; /* return w/ no value */ - assert(returnOper->num_children == 0); - /* do substitutions on the "__retVal = expr" sub-tree */ - slang_substitute(A, assignOper, + /* do substitutions on the new 'return' code */ + slang_substitute(A, newReturn, substCount, substOld, substNew, GL_FALSE); - /* install new code */ - slang_operation_copy(oper, blockOper); - slang_operation_destruct(blockOper); - } - else { - /* check if return value was expected */ - assert(A->CurFunction); - if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { - slang_info_log_error(A->log, "return statement requires an expression"); - return; - } + /* install new 'return' code */ + slang_operation_copy(oper, newReturn); + slang_operation_destruct(newReturn); } break; @@ -1346,12 +1564,74 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, } +/** + * Insert declaration for "bool __notRetFlag" in given block operation. + * This is used when we can't emit "early" return statements in subroutines. + */ +static void +declare_return_flag(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *decl; + + assert(oper->type == SLANG_OPER_BLOCK_NEW_SCOPE || + oper->type == SLANG_OPER_SEQUENCE); + + decl = slang_operation_insert_child(oper, 1); + + slang_generate_declaration(A, oper->locals, decl, + SLANG_SPEC_BOOL, "__notRetFlag", GL_TRUE); + + /*slang_print_tree(oper, 0);*/ +} + + +/** + * Recursively replace instances of the old node type with the new type. + */ +static void +replace_node_type(slang_operation *oper, slang_operation_type oldType, + slang_operation_type newType) +{ + GLuint i; + + if (oper->type == oldType) + oper->type = newType; + + for (i = 0; i < slang_oper_num_children(oper); i++) { + replace_node_type(slang_oper_child(oper, i), oldType, newType); + } +} + + + +/** + * Test if the given function body has an "early return". That is, there's + * a 'return' statement that's not the very last instruction in the body. + */ +static GLboolean +has_early_return(const slang_operation *funcBody) +{ + GLuint retCount = _slang_count_node_type(funcBody, SLANG_OPER_RETURN); + if (retCount == 0) + return GL_FALSE; + else if (retCount == 1 && _slang_is_tail_return(funcBody)) + return GL_FALSE; + else + return GL_TRUE; +} + + +/** + * Emit IR code for a function call. This does one of two things: + * 1. Inline the function's code + * 2. Create an IR for the function's body and create a real call to it. + */ static slang_ir_node * _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, slang_operation *oper, slang_operation *dest) { slang_ir_node *n; - slang_operation *inlined; + slang_operation *instance; slang_label *prevFuncEndLabel; char name[200]; @@ -1360,9 +1640,14 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, A->curFuncEndLabel = _slang_label_new(name); assert(A->curFuncEndLabel); + /* + * 'instance' is basically a copy of the function's body with various + * transformations. + */ + if (slang_is_asm_function(fun) && !dest) { /* assemble assembly function - tree style */ - inlined = slang_inline_asm_function(A, fun, oper); + instance = slang_inline_asm_function(A, fun, oper); } else { /* non-assembly function */ @@ -1371,65 +1656,82 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, * 1. insert the inline code * 2. Generate a call to the "inline" code as a subroutine */ + const GLboolean earlyReturn = has_early_return(fun->body); + if (earlyReturn && !A->EmitContReturn) { + A->UseReturnFlag = GL_TRUE; + } - slang_operation *ret = NULL; - - inlined = slang_inline_function_call(A, fun, oper, dest); - if (!inlined) + instance = slang_inline_function_call(A, fun, oper, dest); + if (!instance) return NULL; - ret = _slang_find_node_type(inlined, SLANG_OPER_RETURN); - if (ret) { - /* check if this is a "tail" return */ - if (_slang_count_node_type(inlined, SLANG_OPER_RETURN) == 1 && - _slang_is_tail_return(inlined)) { - /* The only RETURN is the last stmt in the function, no-op it - * and inline the function body. + if (earlyReturn) { + /* The function we're calling has one or more 'return' statements + * that prevent us from inlining the function's code. + * + * In this case, change the function's body type from + * SLANG_OPER_BLOCK_NEW_SCOPE to SLANG_OPER_NON_INLINED_CALL. + * During code emit this will result in a true subroutine call. + * + * Also, convert SLANG_OPER_RETURN_INLINED nodes to SLANG_OPER_RETURN. + */ + slang_operation *callOper; + + assert(instance->type == SLANG_OPER_BLOCK_NEW_SCOPE || + instance->type == SLANG_OPER_SEQUENCE); + + if (_slang_function_has_return_value(fun) && !dest) { + assert(instance->children[0].type == SLANG_OPER_VARIABLE_DECL); + assert(instance->children[2].type == SLANG_OPER_IDENTIFIER); + callOper = &instance->children[1]; + } + else { + callOper = instance; + } + + if (A->UseReturnFlag) { + /* Early returns not supported. Create a _returnFlag variable + * that's set upon 'return' and tested elsewhere to no-op any + * remaining instructions in the subroutine. */ - ret->type = SLANG_OPER_NONE; + assert(callOper->type == SLANG_OPER_BLOCK_NEW_SCOPE || + callOper->type == SLANG_OPER_SEQUENCE); + declare_return_flag(A, callOper); } else { - slang_operation *callOper; - /* The function we're calling has one or more 'return' statements. - * So, we can't truly inline this function because we need to - * implement 'return' with RET (and CAL). - * Nevertheless, we performed "inlining" to make a new instance - * of the function body to deal with static register allocation. - * - * XXX check if there's one 'return' and if it's the very last - * statement in the function - we can optimize that case. + /* We can emit real 'return' statements. If we generated any + * 'inline return' statements during function instantiation, + * change them back to regular 'return' statements. */ - assert(inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE || - inlined->type == SLANG_OPER_SEQUENCE); - - if (_slang_function_has_return_value(fun) && !dest) { - assert(inlined->children[0].type == SLANG_OPER_VARIABLE_DECL); - assert(inlined->children[2].type == SLANG_OPER_IDENTIFIER); - callOper = &inlined->children[1]; - } - else { - callOper = inlined; - } - callOper->type = SLANG_OPER_NON_INLINED_CALL; - callOper->fun = fun; - callOper->label = _slang_label_new_unique((char*) fun->header.a_name); + replace_node_type(instance, SLANG_OPER_RETURN_INLINED, + SLANG_OPER_RETURN); } + + callOper->type = SLANG_OPER_NON_INLINED_CALL; + callOper->fun = fun; + callOper->label = _slang_label_new_unique((char*) fun->header.a_name); + } + else { + /* If there are any 'return' statements remaining, they're at the + * very end of the function and can effectively become no-ops. + */ + replace_node_type(instance, SLANG_OPER_RETURN_INLINED, + SLANG_OPER_VOID); } } - if (!inlined) + if (!instance) return NULL; - /* Replace the function call with the inlined block (or new CALL stmt) */ + /* Replace the function call with the instance block (or new CALL stmt) */ slang_operation_destruct(oper); - *oper = *inlined; - _slang_free(inlined); + *oper = *instance; + _slang_free(instance); #if 0 - assert(inlined->locals); - printf("*** Inlined code for call to %s:\n", - (char*) fun->header.a_name); + assert(instance->locals); + printf("*** Inlined code for call to %s:\n", (char*) fun->header.a_name); slang_print_tree(oper, 10); printf("\n"); #endif @@ -1445,6 +1747,8 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, n->Comment = _slang_strdup(s); } + A->UseReturnFlag = GL_FALSE; + return n; } @@ -2337,19 +2641,252 @@ _slang_is_boolean(slang_assemble_ctx *A, slang_operation *oper) /** + * Check if a loop contains a 'continue' statement. + * Stop looking if we find a nested loop. + */ +static GLboolean +_slang_loop_contains_continue(const slang_operation *oper) +{ + switch (oper->type) { + case SLANG_OPER_CONTINUE: + return GL_TRUE; + case SLANG_OPER_FOR: + case SLANG_OPER_DO: + case SLANG_OPER_WHILE: + /* stop upon finding a nested loop */ + return GL_FALSE; + default: + /* recurse */ + { + GLuint i; + for (i = 0; i < oper->num_children; i++) { + const slang_operation *child = slang_oper_child_const(oper, i); + if (_slang_loop_contains_continue(child)) + return GL_TRUE; + } + } + return GL_FALSE; + } +} + + +/** + * Check if a loop contains a 'continue' or 'break' statement. + * Stop looking if we find a nested loop. + */ +static GLboolean +_slang_loop_contains_continue_or_break(const slang_operation *oper) +{ + switch (oper->type) { + case SLANG_OPER_CONTINUE: + case SLANG_OPER_BREAK: + return GL_TRUE; + case SLANG_OPER_FOR: + case SLANG_OPER_DO: + case SLANG_OPER_WHILE: + /* stop upon finding a nested loop */ + return GL_FALSE; + default: + /* recurse */ + { + GLuint i; + for (i = 0; i < oper->num_children; i++) { + const slang_operation *child = slang_oper_child_const(oper, i); + if (_slang_loop_contains_continue_or_break(child)) + return GL_TRUE; + } + } + return GL_FALSE; + } +} + + +/** + * Replace 'break' and 'continue' statements inside a do and while loops. + * This is a recursive helper function used by + * _slang_gen_do/while_without_continue(). + */ +static void +replace_break_and_cont(slang_assemble_ctx *A, slang_operation *oper) +{ + switch (oper->type) { + case SLANG_OPER_BREAK: + /* replace 'break' with "_notBreakFlag = false; break" */ + { + slang_operation *block = oper; + block->type = SLANG_OPER_BLOCK_NEW_SCOPE; + slang_operation_add_children(block, 2); + { + slang_operation *assign = slang_oper_child(block, 0); + assign->type = SLANG_OPER_ASSIGN; + slang_operation_add_children(assign, 2); + { + slang_operation *lhs = slang_oper_child(assign, 0); + slang_operation_identifier(lhs, A, "_notBreakFlag"); + } + { + slang_operation *rhs = slang_oper_child(assign, 1); + slang_operation_literal_bool(rhs, GL_FALSE); + } + } + { + slang_operation *brk = slang_oper_child(block, 1); + brk->type = SLANG_OPER_BREAK; + assert(!brk->children); + } + } + break; + case SLANG_OPER_CONTINUE: + /* convert continue into a break */ + oper->type = SLANG_OPER_BREAK; + break; + case SLANG_OPER_FOR: + case SLANG_OPER_DO: + case SLANG_OPER_WHILE: + /* stop upon finding a nested loop */ + break; + default: + /* recurse */ + { + GLuint i; + for (i = 0; i < oper->num_children; i++) { + replace_break_and_cont(A, slang_oper_child(oper, i)); + } + } + } +} + + +/** + * Transform a while-loop so that continue statements are converted to breaks. + * Then do normal IR code generation. + * + * Before: + * + * while (LOOPCOND) { + * A; + * if (IFCOND) + * continue; + * B; + * break; + * C; + * } + * + * After: + * + * { + * bool _notBreakFlag = 1; + * while (_notBreakFlag && LOOPCOND) { + * do { + * A; + * if (IFCOND) { + * break; // was continue + * } + * B; + * _notBreakFlag = 0; // was + * break; // break + * C; + * } while (0) + * } + * } + */ +static slang_ir_node * +_slang_gen_while_without_continue(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *top; + slang_operation *innerBody; + + assert(oper->type == SLANG_OPER_WHILE); + + top = slang_operation_new(1); + top->type = SLANG_OPER_BLOCK_NEW_SCOPE; + top->locals->outer_scope = oper->locals->outer_scope; + slang_operation_add_children(top, 2); + + /* declare: bool _notBreakFlag = true */ + { + slang_operation *condDecl = slang_oper_child(top, 0); + slang_generate_declaration(A, top->locals, condDecl, + SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE); + } + + /* build outer while-loop: while (_notBreakFlag && LOOPCOND) { ... } */ + { + slang_operation *outerWhile = slang_oper_child(top, 1); + outerWhile->type = SLANG_OPER_WHILE; + slang_operation_add_children(outerWhile, 2); + + /* _notBreakFlag && LOOPCOND */ + { + slang_operation *cond = slang_oper_child(outerWhile, 0); + cond->type = SLANG_OPER_LOGICALAND; + slang_operation_add_children(cond, 2); + { + slang_operation *notBreak = slang_oper_child(cond, 0); + slang_operation_identifier(notBreak, A, "_notBreakFlag"); + } + { + slang_operation *origCond = slang_oper_child(cond, 1); + slang_operation_copy(origCond, slang_oper_child(oper, 0)); + } + } + + /* inner loop */ + { + slang_operation *innerDo = slang_oper_child(outerWhile, 1); + innerDo->type = SLANG_OPER_DO; + slang_operation_add_children(innerDo, 2); + + /* copy original do-loop body into inner do-loop's body */ + innerBody = slang_oper_child(innerDo, 0); + slang_operation_copy(innerBody, slang_oper_child(oper, 1)); + innerBody->locals->outer_scope = innerDo->locals; + + /* inner do-loop's condition is constant/false */ + { + slang_operation *constFalse = slang_oper_child(innerDo, 1); + slang_operation_literal_bool(constFalse, GL_FALSE); + } + } + } + + /* Finally, in innerBody, + * replace "break" with "_notBreakFlag = 0; break" + * replace "continue" with "break" + */ + replace_break_and_cont(A, innerBody); + + /*slang_print_tree(top, 0);*/ + + return _slang_gen_operation(A, top); + + return NULL; +} + + +/** * Generate loop code using high-level IR_LOOP instruction */ static slang_ir_node * -_slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) +_slang_gen_while(slang_assemble_ctx * A, slang_operation *oper) { /* * LOOP: * BREAK if !expr (child[0]) * body code (child[1]) */ - slang_ir_node *prevLoop, *loop, *breakIf, *body; + slang_ir_node *loop, *breakIf, *body; GLboolean isConst, constTrue; + if (!A->EmitContReturn) { + /* We don't want to emit CONT instructions. If this while-loop has + * a continue, translate it away. + */ + if (_slang_loop_contains_continue(slang_oper_child(oper, 1))) { + return _slang_gen_while_without_continue(A, oper); + } + } + /* type-check expression */ if (!_slang_is_boolean(A, &oper->children[0])) { slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'"); @@ -2364,11 +2901,11 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) return new_node0(IR_NOP); } + /* Begin new loop */ loop = new_loop(NULL); - /* save old, push new loop */ - prevLoop = A->CurLoop; - A->CurLoop = loop; + /* save loop state */ + push_loop(A, oper, loop); if (isConst && constTrue) { /* while(nonzero constant), no conditional break */ @@ -2377,7 +2914,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) else { slang_ir_node *cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[0]))); - breakIf = new_break_if_true(A->CurLoop, cond); + breakIf = new_break_if_true(A, cond); } body = _slang_gen_operation(A, &oper->children[1]); loop->Children[0] = new_seq(breakIf, body); @@ -2386,23 +2923,128 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) /* loop->List is head of linked list of break/continue nodes */ if (!loop->List && isConst && constTrue) { /* infinite loop detected */ - A->CurLoop = prevLoop; /* clean-up */ + pop_loop(A); slang_info_log_error(A->log, "Infinite loop detected!"); return NULL; } - /* pop loop, restore prev */ - A->CurLoop = prevLoop; + /* restore loop state */ + pop_loop(A); return loop; } /** + * Transform a do-while-loop so that continue statements are converted to breaks. + * Then do normal IR code generation. + * + * Before: + * + * do { + * A; + * if (IFCOND) + * continue; + * B; + * break; + * C; + * } while (LOOPCOND); + * + * After: + * + * { + * bool _notBreakFlag = 1; + * do { + * do { + * A; + * if (IFCOND) { + * break; // was continue + * } + * B; + * _notBreakFlag = 0; // was + * break; // break + * C; + * } while (0) + * } while (_notBreakFlag && LOOPCOND); + * } + */ +static slang_ir_node * +_slang_gen_do_without_continue(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *top; + slang_operation *innerBody; + + assert(oper->type == SLANG_OPER_DO); + + top = slang_operation_new(1); + top->type = SLANG_OPER_BLOCK_NEW_SCOPE; + top->locals->outer_scope = oper->locals->outer_scope; + slang_operation_add_children(top, 2); + + /* declare: bool _notBreakFlag = true */ + { + slang_operation *condDecl = slang_oper_child(top, 0); + slang_generate_declaration(A, top->locals, condDecl, + SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE); + } + + /* build outer do-loop: do { ... } while (_notBreakFlag && LOOPCOND) */ + { + slang_operation *outerDo = slang_oper_child(top, 1); + outerDo->type = SLANG_OPER_DO; + slang_operation_add_children(outerDo, 2); + + /* inner do-loop */ + { + slang_operation *innerDo = slang_oper_child(outerDo, 0); + innerDo->type = SLANG_OPER_DO; + slang_operation_add_children(innerDo, 2); + + /* copy original do-loop body into inner do-loop's body */ + innerBody = slang_oper_child(innerDo, 0); + slang_operation_copy(innerBody, slang_oper_child(oper, 0)); + innerBody->locals->outer_scope = innerDo->locals; + + /* inner do-loop's condition is constant/false */ + { + slang_operation *constFalse = slang_oper_child(innerDo, 1); + slang_operation_literal_bool(constFalse, GL_FALSE); + } + } + + /* _notBreakFlag && LOOPCOND */ + { + slang_operation *cond = slang_oper_child(outerDo, 1); + cond->type = SLANG_OPER_LOGICALAND; + slang_operation_add_children(cond, 2); + { + slang_operation *notBreak = slang_oper_child(cond, 0); + slang_operation_identifier(notBreak, A, "_notBreakFlag"); + } + { + slang_operation *origCond = slang_oper_child(cond, 1); + slang_operation_copy(origCond, slang_oper_child(oper, 1)); + } + } + } + + /* Finally, in innerBody, + * replace "break" with "_notBreakFlag = 0; break" + * replace "continue" with "break" + */ + replace_break_and_cont(A, innerBody); + + /*slang_print_tree(top, 0);*/ + + return _slang_gen_operation(A, top); +} + + +/** * Generate IR tree for a do-while loop using high-level LOOP, IF instructions. */ static slang_ir_node * -_slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) +_slang_gen_do(slang_assemble_ctx * A, slang_operation *oper) { /* * LOOP: @@ -2410,9 +3052,18 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) * tail code: * BREAK if !expr (child[1]) */ - slang_ir_node *prevLoop, *loop; + slang_ir_node *loop; GLboolean isConst, constTrue; + if (!A->EmitContReturn) { + /* We don't want to emit CONT instructions. If this do-loop has + * a continue, translate it away. + */ + if (_slang_loop_contains_continue(slang_oper_child(oper, 0))) { + return _slang_gen_do_without_continue(A, oper); + } + } + /* type-check expression */ if (!_slang_is_boolean(A, &oper->children[1])) { slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'"); @@ -2421,9 +3072,8 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) loop = new_loop(NULL); - /* save old, push new loop */ - prevLoop = A->CurLoop; - A->CurLoop = loop; + /* save loop state */ + push_loop(A, oper, loop); /* loop body: */ loop->Children[0] = _slang_gen_operation(A, &oper->children[0]); @@ -2437,13 +3087,13 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) else { slang_ir_node *cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1]))); - loop->Children[1] = new_break_if_true(A->CurLoop, cond); + loop->Children[1] = new_break_if_true(A, cond); } /* XXX we should do infinite loop detection, as above */ - /* pop loop, restore prev */ - A->CurLoop = prevLoop; + /* restore loop state */ + pop_loop(A); return loop; } @@ -2485,9 +3135,14 @@ _slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) const char *varName; slang_atom varId; - assert(oper->type == SLANG_OPER_FOR); + if (oper->type != SLANG_OPER_FOR) + return GL_FALSE; + assert(oper->num_children == 4); + if (_slang_loop_contains_continue_or_break(slang_oper_child_const(oper, 3))) + return GL_FALSE; + /* children[0] must be either "int i=constant" or "i=constant" */ if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) { slang_variable *var; @@ -2582,20 +3237,6 @@ _slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) } -static void -_unroll_loop_inc(slang_assemble_ctx * A) -{ - A->UnrollLoop++; -} - - -static void -_unroll_loop_dec(slang_assemble_ctx * A) -{ - A->UnrollLoop--; -} - - /** * Unroll a for-loop. * First we determine the number of iterations to unroll. @@ -2612,9 +3253,6 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) slang_ir_node *n, *root = NULL; slang_atom varId; - /* Set flag so code generator knows we're unrolling loops */ - _unroll_loop_inc( A ); - if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) { /* for (int i=0; ... */ slang_variable *var; @@ -2637,15 +3275,11 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) /* make a copy of the loop body */ body = slang_operation_new(1); - if (!body) { - _unroll_loop_dec( A ); + if (!body) return NULL; - } - if (!slang_operation_copy(body, &oper->children[3])) { - _unroll_loop_dec( A ); + if (!slang_operation_copy(body, &oper->children[3])) return NULL; - } /* in body, replace instances of 'varId' with literal 'iter' */ { @@ -2656,7 +3290,6 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) if (!oldVar) { /* undeclared loop variable */ slang_operation_delete(body); - _unroll_loop_dec( A ); return NULL; } @@ -2671,36 +3304,195 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) /* do IR codegen for body */ n = _slang_gen_operation(A, body); - if (!n) { - _unroll_loop_dec( A ); + if (!n) return NULL; - } root = new_seq(root, n); slang_operation_delete(body); } - _unroll_loop_dec( A ); - return root; } /** + * Replace 'continue' statement with 'break' inside a for-loop. + * This is a recursive helper function used by _slang_gen_for_without_continue(). + */ +static void +replace_continue_with_break(slang_assemble_ctx *A, slang_operation *oper) +{ + switch (oper->type) { + case SLANG_OPER_CONTINUE: + oper->type = SLANG_OPER_BREAK; + break; + case SLANG_OPER_FOR: + case SLANG_OPER_DO: + case SLANG_OPER_WHILE: + /* stop upon finding a nested loop */ + break; + default: + /* recurse */ + { + GLuint i; + for (i = 0; i < oper->num_children; i++) { + replace_continue_with_break(A, slang_oper_child(oper, i)); + } + } + } +} + + +/** + * Transform a for-loop so that continue statements are converted to breaks. + * Then do normal IR code generation. + * + * Before: + * + * for (INIT; LOOPCOND; INCR) { + * A; + * if (IFCOND) { + * continue; + * } + * B; + * } + * + * After: + * + * { + * bool _condFlag = 1; + * for (INIT; _condFlag; ) { + * for ( ; _condFlag = LOOPCOND; INCR) { + * A; + * if (IFCOND) { + * break; + * } + * B; + * } + * if (_condFlag) + * INCR; + * } + * } + */ +static slang_ir_node * +_slang_gen_for_without_continue(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_operation *top; + slang_operation *outerFor, *innerFor, *init, *cond, *incr; + slang_operation *lhs, *rhs; + + assert(oper->type == SLANG_OPER_FOR); + + top = slang_operation_new(1); + top->type = SLANG_OPER_BLOCK_NEW_SCOPE; + top->locals->outer_scope = oper->locals->outer_scope; + slang_operation_add_children(top, 2); + + /* declare: bool _condFlag = true */ + { + slang_operation *condDecl = slang_oper_child(top, 0); + slang_generate_declaration(A, top->locals, condDecl, + SLANG_SPEC_BOOL, "_condFlag", GL_TRUE); + } + + /* build outer loop: for (INIT; _condFlag; ) { */ + outerFor = slang_oper_child(top, 1); + outerFor->type = SLANG_OPER_FOR; + slang_operation_add_children(outerFor, 4); + + init = slang_oper_child(outerFor, 0); + slang_operation_copy(init, slang_oper_child(oper, 0)); + + cond = slang_oper_child(outerFor, 1); + cond->type = SLANG_OPER_IDENTIFIER; + cond->a_id = slang_atom_pool_atom(A->atoms, "_condFlag"); + + incr = slang_oper_child(outerFor, 2); + incr->type = SLANG_OPER_VOID; + + /* body of the outer loop */ + { + slang_operation *block = slang_oper_child(outerFor, 3); + + slang_operation_add_children(block, 2); + block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; + + /* build inner loop: for ( ; _condFlag = LOOPCOND; INCR) { */ + { + innerFor = slang_oper_child(block, 0); + + /* make copy of orig loop */ + slang_operation_copy(innerFor, oper); + assert(innerFor->type == SLANG_OPER_FOR); + innerFor->locals->outer_scope = block->locals; + + init = slang_oper_child(innerFor, 0); + init->type = SLANG_OPER_VOID; /* leak? */ + + cond = slang_oper_child(innerFor, 1); + slang_operation_destruct(cond); + cond->type = SLANG_OPER_ASSIGN; + cond->locals = _slang_variable_scope_new(innerFor->locals); + slang_operation_add_children(cond, 2); + + lhs = slang_oper_child(cond, 0); + lhs->type = SLANG_OPER_IDENTIFIER; + lhs->a_id = slang_atom_pool_atom(A->atoms, "_condFlag"); + + rhs = slang_oper_child(cond, 1); + slang_operation_copy(rhs, slang_oper_child(oper, 1)); + } + + /* if (_condFlag) INCR; */ + { + slang_operation *ifop = slang_oper_child(block, 1); + ifop->type = SLANG_OPER_IF; + slang_operation_add_children(ifop, 2); + + /* re-use cond node build above */ + slang_operation_copy(slang_oper_child(ifop, 0), cond); + + /* incr node from original for-loop operation */ + slang_operation_copy(slang_oper_child(ifop, 1), + slang_oper_child(oper, 2)); + } + + /* finally, replace "continue" with "break" in the inner for-loop */ + replace_continue_with_break(A, slang_oper_child(innerFor, 3)); + } + + return _slang_gen_operation(A, top); +} + + + +/** * Generate IR for a for-loop. Unrolling will be done when possible. */ static slang_ir_node * -_slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) +_slang_gen_for(slang_assemble_ctx * A, slang_operation *oper) { - GLboolean unroll = _slang_can_unroll_for_loop(A, oper); + GLboolean unroll; + + if (!A->EmitContReturn) { + /* We don't want to emit CONT instructions. If this for-loop has + * a continue, translate it away. + */ + if (_slang_loop_contains_continue(slang_oper_child(oper, 3))) { + return _slang_gen_for_without_continue(A, oper); + } + } + unroll = _slang_can_unroll_for_loop(A, oper); if (unroll) { slang_ir_node *code = _slang_unroll_for_loop(A, oper); if (code) return code; } + assert(oper->type == SLANG_OPER_FOR); + /* conventional for-loop code generation */ { /* @@ -2711,24 +3503,23 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) * tail code: * incr code (child[2]) // XXX continue here */ - slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body, *init, *incr; + slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr; init = _slang_gen_operation(A, &oper->children[0]); loop = new_loop(NULL); - /* save old, push new loop */ - prevLoop = A->CurLoop; - A->CurLoop = loop; + /* save loop state */ + push_loop(A, oper, loop); cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1]))); - breakIf = new_break_if_true(A->CurLoop, cond); + breakIf = new_break_if_true(A, cond); body = _slang_gen_operation(A, &oper->children[3]); incr = _slang_gen_operation(A, &oper->children[2]); loop->Children[0] = new_seq(breakIf, body); loop->Children[1] = incr; /* tail code */ - /* pop loop, restore prev */ - A->CurLoop = prevLoop; + /* restore loop state */ + pop_loop(A); return new_seq(init, loop); } @@ -2738,18 +3529,22 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) static slang_ir_node * _slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper) { - slang_ir_node *n, *loopNode; + slang_ir_node *n, *cont, *incr = NULL, *loopNode; + assert(oper->type == SLANG_OPER_CONTINUE); - loopNode = A->CurLoop; + loopNode = current_loop_ir(A); assert(loopNode); assert(loopNode->Opcode == IR_LOOP); - n = new_node0(IR_CONT); - if (n) { - n->Parent = loopNode; - /* insert this node at head of linked list */ - n->List = loopNode->List; - loopNode->List = n; + + cont = new_node0(IR_CONT); + if (cont) { + cont->Parent = loopNode; + /* insert this node at head of linked list of cont/break instructions */ + cont->List = loopNode->List; + loopNode->List = cont; } + + n = new_seq(incr, cont); return n; } @@ -2819,24 +3614,20 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK) && !haveElseClause) { /* Special case: generate a conditional break */ - if (!A->CurLoop && A->UnrollLoop) /* trying to unroll */ - return NULL; - ifBody = new_break_if_true(A->CurLoop, cond); + ifBody = new_break_if_true(A, cond); return ifBody; } else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE) - && !haveElseClause) { + && !haveElseClause + && current_loop_oper(A) + && current_loop_oper(A)->type != SLANG_OPER_FOR) { /* Special case: generate a conditional continue */ - if (!A->CurLoop && A->UnrollLoop) /* trying to unroll */ - return NULL; - ifBody = new_cont_if_true(A->CurLoop, cond); + ifBody = new_cont_if_true(A, cond); return ifBody; } else { /* general case */ ifBody = _slang_gen_operation(A, &oper->children[1]); - if (!ifBody) - return NULL; if (haveElseClause) elseBody = _slang_gen_operation(A, &oper->children[2]); else @@ -3242,14 +4033,11 @@ _slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper) select = slang_operation_new(1); select->type = SLANG_OPER_SELECT; - select->num_children = 3; - select->children = slang_operation_new(3); + slang_operation_add_children(select, 3); - slang_operation_copy(&select->children[0], &oper->children[0]); - slang_operation_copy(&select->children[1], &oper->children[1]); - select->children[2].type = SLANG_OPER_LITERAL_BOOL; - ASSIGN_4V(select->children[2].literal, 0, 0, 0, 0); /* false */ - select->children[2].literal_size = 1; + slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]); + slang_operation_copy(slang_oper_child(select, 1), &oper->children[1]); + slang_operation_literal_bool(slang_oper_child(select, 2), GL_FALSE); n = _slang_gen_select(A, select); return n; @@ -3268,14 +4056,11 @@ _slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper) select = slang_operation_new(1); select->type = SLANG_OPER_SELECT; - select->num_children = 3; - select->children = slang_operation_new(3); + slang_operation_add_children(select, 3); - slang_operation_copy(&select->children[0], &oper->children[0]); - select->children[1].type = SLANG_OPER_LITERAL_BOOL; - ASSIGN_4V(select->children[1].literal, 1, 1, 1, 1); /* true */ - select->children[1].literal_size = 1; - slang_operation_copy(&select->children[2], &oper->children[1]); + slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]); + slang_operation_literal_bool(slang_oper_child(select, 1), GL_TRUE); + slang_operation_copy(slang_oper_child(select, 2), &oper->children[1]); n = _slang_gen_select(A, select); return n; @@ -3288,70 +4073,8 @@ _slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper) static slang_ir_node * _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) { - const GLboolean haveReturnValue - = (oper->num_children == 1 && oper->children[0].type != SLANG_OPER_VOID); - - /* error checking */ - assert(A->CurFunction); - if (haveReturnValue && - A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) { - slang_info_log_error(A->log, "illegal return expression"); - return NULL; - } - else if (!haveReturnValue && - A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { - slang_info_log_error(A->log, "return statement requires an expression"); - return NULL; - } - - if (!haveReturnValue) { - return new_return(A->curFuncEndLabel); - } - else { - /* - * Convert from: - * return expr; - * To: - * __retVal = expr; - * return; // goto __endOfFunction - */ - slang_operation *assign; - slang_atom a_retVal; - slang_ir_node *n; - - a_retVal = slang_atom_pool_atom(A->atoms, "__retVal"); - assert(a_retVal); - -#if 1 /* DEBUG */ - { - slang_variable *v = - _slang_variable_locate(oper->locals, a_retVal, GL_TRUE); - if (!v) { - /* trying to return a value in a void-valued function */ - return NULL; - } - } -#endif - - assign = slang_operation_new(1); - assign->type = SLANG_OPER_ASSIGN; - assign->num_children = 2; - assign->children = slang_operation_new(2); - /* lhs (__retVal) */ - assign->children[0].type = SLANG_OPER_IDENTIFIER; - assign->children[0].a_id = a_retVal; - assign->children[0].locals->outer_scope = assign->locals; - /* rhs (expr) */ - /* XXX we might be able to avoid this copy someday */ - slang_operation_copy(&assign->children[1], &oper->children[0]); - - /* assemble the new code */ - n = new_seq(_slang_gen_operation(A, assign), - new_return(A->curFuncEndLabel)); - - slang_operation_delete(assign); - return n; - } + assert(oper->type == SLANG_OPER_RETURN); + return new_return(A->curFuncEndLabel); } @@ -3457,6 +4180,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) assert(oper->type == SLANG_OPER_VARIABLE_DECL); assert(oper->num_children <= 1); + /* lookup the variable by name */ var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE); if (!var) @@ -3612,6 +4336,9 @@ root_swizzle(const slang_ir_storage *st) static slang_ir_node * _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) { + slang_operation *pred = NULL; + slang_ir_node *n = NULL; + if (oper->children[0].type == SLANG_OPER_IDENTIFIER) { /* Check that var is writeable */ slang_variable *var @@ -3632,6 +4359,17 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) (char *) oper->children[0].a_id); return NULL; } + + /* check if we need to predicate this assignment based on __notRetFlag */ + if ((var->is_global || + var->type.qualifier == SLANG_QUAL_OUT || + var->type.qualifier == SLANG_QUAL_INOUT) && A->UseReturnFlag) { + /* create predicate, used below */ + pred = slang_operation_new(1); + pred->type = SLANG_OPER_IDENTIFIER; + pred->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); + pred->locals->outer_scope = oper->locals->outer_scope; + } } if (oper->children[0].type == SLANG_OPER_IDENTIFIER && @@ -3643,14 +4381,12 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) * cases such as "v.x = f();" - would help with typical vertex * transformation. */ - slang_ir_node *n; n = _slang_gen_function_call_name(A, (const char *) oper->children[1].a_id, &oper->children[1], &oper->children[0]); - return n; } else { - slang_ir_node *n, *lhs, *rhs; + slang_ir_node *lhs, *rhs; /* lhs and rhs type checking */ if (!_slang_assignment_compatible(A, @@ -3690,12 +4426,21 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) rhs = _slang_gen_swizzle(rhs, newSwizzle); } n = new_node2(IR_COPY, lhs, rhs); - return n; } else { return NULL; } } + + if (n && pred) { + /* predicate the assignment code on __notRetFlag */ + slang_ir_node *top, *cond; + + cond = _slang_gen_operation(A, pred); + top = new_if(cond, n, NULL); + return top; + } + return n; } @@ -4048,16 +4793,14 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case SLANG_OPER_WHILE: return _slang_gen_while(A, oper); case SLANG_OPER_BREAK: - if (!A->CurLoop) { - if (!A->UnrollLoop) - slang_info_log_error(A->log, "'break' not in loop"); + if (!current_loop_oper(A)) { + slang_info_log_error(A->log, "'break' not in loop"); return NULL; } - return new_break(A->CurLoop); + return new_break(current_loop_ir(A)); case SLANG_OPER_CONTINUE: - if (!A->CurLoop) { - if (!A->UnrollLoop) - slang_info_log_error(A->log, "'continue' not in loop"); + if (!current_loop_oper(A)) { + slang_info_log_error(A->log, "'continue' not in loop"); return NULL; } return _slang_gen_continue(A, oper); @@ -4182,6 +4925,8 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return _slang_gen_method_call(A, oper); case SLANG_OPER_RETURN: return _slang_gen_return(A, oper); + case SLANG_OPER_RETURN_INLINED: + return _slang_gen_return(A, oper); case SLANG_OPER_LABEL: return new_label(oper->label); case SLANG_OPER_IDENTIFIER: @@ -4303,6 +5048,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, const GLint totalSize = _slang_array_size(size, arrayLen); GLint texIndex = sampler_to_texture_index(var->type.specifier.type); + var->is_global = GL_TRUE; + /* check for sampler2D arrays */ if (texIndex == -1 && var->type.specifier._array) texIndex = sampler_to_texture_index(var->type.specifier._array->type); @@ -4601,7 +5348,9 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) assert(A->program->Parameters ); assert(A->program->Varying); assert(A->vartable); - A->CurLoop = NULL; + + A->LoopDepth = 0; + A->UseReturnFlag = GL_FALSE; A->CurFunction = fun; /* fold constant expressions, etc. */ diff --git a/src/mesa/shader/slang/slang_codegen.h b/src/mesa/shader/slang/slang_codegen.h index d80013ad341..ee3be55a459 100644 --- a/src/mesa/shader/slang/slang_codegen.h +++ b/src/mesa/shader/slang/slang_codegen.h @@ -31,6 +31,9 @@ #include "slang_compile.h" +#define MAX_LOOP_DEPTH 30 + + typedef struct slang_assemble_ctx_ { slang_atom_pool *atoms; @@ -39,11 +42,19 @@ typedef struct slang_assemble_ctx_ struct gl_sl_pragmas *pragmas; slang_var_table *vartable; slang_info_log *log; - struct slang_label_ *curFuncEndLabel; - struct slang_ir_node_ *CurLoop; + + /* current loop stack */ + const slang_operation *LoopOperStack[MAX_LOOP_DEPTH]; + struct slang_ir_node_ *LoopIRStack[MAX_LOOP_DEPTH]; + GLuint LoopDepth; + + /* current function */ struct slang_function_ *CurFunction; - GLuint UnrollLoop; + struct slang_label_ *curFuncEndLabel; + GLboolean UseReturnFlag; + GLboolean UnresolvedRefs; + GLboolean EmitContReturn; } slang_assemble_ctx; diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index d7ad879e97a..c1b97c7cb70 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1953,6 +1953,7 @@ static int parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, const slang_fully_specified_type * type) { + GET_CURRENT_CONTEXT(ctx); /* a hack */ slang_variable *var; slang_atom a_name; @@ -2066,6 +2067,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.vartable = O->vartable; A.log = C->L; A.curFuncEndLabel = NULL; + A.EmitContReturn = ctx->Shader.EmitContReturn; if (!_slang_codegen_global_variable(&A, var, C->type)) RETURN0; } @@ -2430,6 +2432,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, A.program = o.program; A.pragmas = &shader->Pragmas; A.vartable = o.vartable; + A.EmitContReturn = ctx->Shader.EmitContReturn; A.log = C->L; /* main() takes no parameters */ diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c index e6506168808..3e2bdbc91ff 100644 --- a/src/mesa/shader/slang/slang_compile_operation.c +++ b/src/mesa/shader/slang/slang_compile_operation.c @@ -119,11 +119,13 @@ slang_operation_copy(slang_operation * x, const slang_operation * y) if (!slang_operation_construct(&z)) return GL_FALSE; z.type = y->type; - z.children = (slang_operation *) - _slang_alloc(y->num_children * sizeof(slang_operation)); - if (z.children == NULL) { - slang_operation_destruct(&z); - return GL_FALSE; + if (y->num_children > 0) { + z.children = (slang_operation *) + _slang_alloc(y->num_children * sizeof(slang_operation)); + if (z.children == NULL) { + slang_operation_destruct(&z); + return GL_FALSE; + } } for (z.num_children = 0; z.num_children < y->num_children; z.num_children++) { @@ -152,6 +154,15 @@ slang_operation_copy(slang_operation * x, const slang_operation * y) return GL_FALSE; } } + + /* update scoping for children */ + for (i = 0; i < y->num_children; i++) { + if (y->children[i].locals && + y->children[i].locals->outer_scope == y->locals) { + z.children[i].locals->outer_scope = z.locals; + } + } + #if 0 z.var = y->var; z.fun = y->fun; @@ -198,6 +209,20 @@ slang_operation_delete(slang_operation *oper) } +void +slang_operation_free_children(slang_operation *oper) +{ + GLuint i; + for (i = 0; i < slang_oper_num_children(oper); i++) { + slang_operation *child = slang_oper_child(oper, i); + slang_operation_destruct(child); + } + _slang_free(oper->children); + oper->children = NULL; + oper->num_children = 0; +} + + slang_operation * slang_operation_grow(GLuint *numChildren, slang_operation **children) { @@ -263,6 +288,26 @@ slang_operation_insert(GLuint *numElements, slang_operation **array, } +/** + * Add/insert new child into given node at given position. + * \return pointer to the new child node + */ +slang_operation * +slang_operation_insert_child(slang_operation *oper, GLuint pos) +{ + slang_operation *newOp; + + newOp = slang_operation_insert(&oper->num_children, + &oper->children, + pos); + if (newOp) { + newOp->locals->outer_scope = oper->locals; + } + + return newOp; +} + + void _slang_operation_swap(slang_operation *oper0, slang_operation *oper1) { @@ -272,3 +317,16 @@ _slang_operation_swap(slang_operation *oper0, slang_operation *oper1) } +void +slang_operation_add_children(slang_operation *oper, GLuint num_children) +{ + GLuint i; + assert(oper->num_children == 0); + assert(oper->children == NULL); + oper->num_children = num_children; + oper->children = slang_operation_new(num_children); + for (i = 0; i < num_children; i++) { + oper->children[i].locals = _slang_variable_scope_new(oper->locals); + } +} + diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index 37af5d617c9..58f1edeed85 100644 --- a/src/mesa/shader/slang/slang_compile_operation.h +++ b/src/mesa/shader/slang/slang_compile_operation.h @@ -42,6 +42,7 @@ typedef enum slang_operation_type_ SLANG_OPER_CONTINUE, /* "continue" statement */ SLANG_OPER_DISCARD, /* "discard" (kill fragment) statement */ SLANG_OPER_RETURN, /* "return" [expr] */ + SLANG_OPER_RETURN_INLINED, /* "return" [expr] from inlined function */ SLANG_OPER_LABEL, /* a jump target */ SLANG_OPER_EXPRESSION, /* [expr] */ SLANG_OPER_IF, /* "if" [0] then [1] else [2] */ @@ -150,6 +151,9 @@ slang_operation_new(GLuint count); extern void slang_operation_delete(slang_operation *oper); +extern void +slang_operation_free_children(slang_operation *oper); + extern slang_operation * slang_operation_grow(GLuint *numChildren, slang_operation **children); @@ -157,8 +161,66 @@ extern slang_operation * slang_operation_insert(GLuint *numChildren, slang_operation **children, GLuint pos); +extern slang_operation * +slang_operation_insert_child(slang_operation *oper, GLuint pos); + extern void _slang_operation_swap(slang_operation *oper0, slang_operation *oper1); +extern void +slang_operation_add_children(slang_operation *oper, GLuint num_children); + + +/** Return number of children of given node */ +static INLINE GLuint +slang_oper_num_children(const slang_operation *oper) +{ + return oper->num_children; +} + +/** Return child of given operation node */ +static INLINE slang_operation * +slang_oper_child(slang_operation *oper, GLuint child) +{ + assert(child < oper->num_children); + return &oper->children[child]; +} + + +/** Return child of given operation node, const version */ +static INLINE const slang_operation * +slang_oper_child_const(const slang_operation *oper, GLuint child) +{ + assert(child < oper->num_children); + return &oper->children[child]; +} + + +/** Init oper to a boolean literal. */ +static INLINE void +slang_operation_literal_bool(slang_operation *oper, GLboolean value) +{ + oper->type = SLANG_OPER_LITERAL_BOOL; + oper->literal[0] = + oper->literal[1] = + oper->literal[2] = + oper->literal[3] = (float) value; + oper->literal_size = 1; +} + + +/** Init oper to an int literal. */ +static INLINE void +slang_operation_literal_int(slang_operation *oper, GLint value) +{ + oper->type = SLANG_OPER_LITERAL_INT; + oper->literal[0] = + oper->literal[1] = + oper->literal[2] = + oper->literal[3] = (float) value; + oper->literal_size = 1; +} + + #endif /* SLANG_COMPILE_OPERATION_H */ diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h index a667d91b471..b4585599f24 100644 --- a/src/mesa/shader/slang/slang_compile_variable.h +++ b/src/mesa/shader/slang/slang_compile_variable.h @@ -39,6 +39,7 @@ typedef struct slang_variable_ GLuint array_len; /**< only if type == SLANG_SPEC_ARRAy */ struct slang_operation_ *initializer; /**< Optional initializer code */ GLuint size; /**< Variable's size in bytes */ + GLboolean is_global; GLboolean isTemp; /**< a named temporary (__resultTmp) */ GLboolean declared; /**< for debug */ struct slang_ir_storage_ *store; /**< Storage for this var */ diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c index bf1475f91d9..98c7877534f 100644 --- a/src/mesa/shader/slang/slang_print.c +++ b/src/mesa/shader/slang/slang_print.c @@ -261,6 +261,7 @@ slang_print_tree(const slang_operation *op, int indent) break; case SLANG_OPER_BLOCK_NEW_SCOPE: + case SLANG_OPER_NON_INLINED_CALL: spaces(indent); printf("{{ // new scope locals=%p outer=%p: ", (void *) op->locals, @@ -348,6 +349,13 @@ slang_print_tree(const slang_operation *op, int indent) slang_print_tree(&op->children[0], indent + 3); break; + case SLANG_OPER_RETURN_INLINED: + spaces(indent); + printf("RETURN_INLINED\n"); + if (op->num_children > 0) + slang_print_tree(&op->children[0], indent + 3); + break; + case SLANG_OPER_LABEL: spaces(indent); printf("LABEL %s\n", (char *) op->a_id); @@ -478,7 +486,7 @@ slang_print_tree(const slang_operation *op, int indent) (void *) scope, (void *) op->locals, (void *) op->locals->outer_scope); - assert(scope); + /*assert(scope);*/ } } break; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 92ddffc0148..8514b6b3756 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -274,20 +274,11 @@ st_make_current(struct st_context *st, _glapi_check_multithread(); if (st) { - GLboolean firstTime = st->ctx->FirstTimeCurrent; - if(!_mesa_make_current(st->ctx, &draw->Base, &read->Base)) + if (!_mesa_make_current(st->ctx, &draw->Base, &read->Base)) return GL_FALSE; - /* Need to initialize viewport here since draw->Base->Width/Height - * will still be zero at this point. - * This could be improved, but would require rather extensive work - * elsewhere (allocate rb surface storage sooner) - */ - if (firstTime) { - GLuint w = draw->InitWidth, h = draw->InitHeight; - _mesa_set_viewport(st->ctx, 0, 0, w, h); - _mesa_set_scissor(st->ctx, 0, 0, w, h); - } + _mesa_check_init_viewport(st->ctx, draw->InitWidth, draw->InitHeight); + return GL_TRUE; } else { diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 8e036223c65..914a507bef6 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -229,8 +229,10 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count, struct st_buffer_object *stobj = st_buffer_object(array->BufferObj); ubyte *map; - if (!stobj) + if (!stobj || stobj->Base.Name == 0) { + /* edge flags are not in a VBO */ return NULL; + } vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32)); if (!vec) diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index ab83543063c..a35eab03e7d 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -120,6 +120,11 @@ void st_init_limits(struct st_context *st) c->MaxDrawBuffers = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); + + /* Is TGSI_OPCODE_CONT supported? */ + /* XXX separate query for early function return? */ + st->ctx->Shader.EmitContReturn = + screen->get_param(screen, PIPE_CAP_TGSI_CONT_SUPPORTED); } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 7072cbe62c7..13589151ba6 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -134,16 +134,7 @@ void st_resize_framebuffer( struct st_framebuffer *stfb, if (stfb->Base.Width != width || stfb->Base.Height != height) { GET_CURRENT_CONTEXT(ctx); if (ctx) { - if (stfb->InitWidth == 0 && stfb->InitHeight == 0) { - /* didn't have a valid size until now */ - stfb->InitWidth = width; - stfb->InitHeight = height; - if (ctx->Viewport.Width <= 1) { - /* set context's initial viewport/scissor size */ - _mesa_set_viewport(ctx, 0, 0, width, height); - _mesa_set_scissor(ctx, 0, 0, width, height); - } - } + _mesa_check_init_viewport(ctx, width, height); _mesa_resize_framebuffer(ctx, &stfb->Base, width, height); diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index dc6d77825f5..58f69336523 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -198,9 +198,6 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, return; } - if (dstImage->ImageOffsets) - _mesa_free(dstImage->ImageOffsets); - /* Free old image data */ if (dstImage->Data) ctx->Driver.FreeTexImageData(ctx, dstImage); diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 868226075ac..3c4c8acc638 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -1139,21 +1139,21 @@ static void vbo_print_vertex_list( GLcontext *ctx, void *data ) GLuint i; (void) ctx; - _mesa_debug(NULL, "VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); + _mesa_printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", + node->count, + node->prim_count, + node->vertex_size); for (i = 0 ; i < node->prim_count ; i++) { struct _mesa_prim *prim = &node->prim[i]; - _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - (prim->begin) ? "BEGIN" : "(wrap)", - (prim->end) ? "END" : "(wrap)"); + _mesa_printf(" prim %d: %s%s %d..%d %s %s\n", + i, + _mesa_lookup_enum_by_nr(prim->mode), + prim->weak ? " (weak)" : "", + prim->start, + prim->start + prim->count, + (prim->begin) ? "BEGIN" : "(wrap)", + (prim->end) ? "END" : "(wrap)"); } } |