diff options
author | Michal Krol <[email protected]> | 2009-09-17 12:44:24 +0200 |
---|---|---|
committer | Michal Krol <[email protected]> | 2009-09-17 12:44:24 +0200 |
commit | 2a661c383fee65bc4413541e706925fa3e9b9cf5 (patch) | |
tree | dbea0c9d65d17b81720fe2f161604dfc91eb0546 | |
parent | 90daefd1c474a6e0502df5053b581987c12b8673 (diff) | |
parent | 21caa29fbd332a2ee05a58df91e1664fbbc4e61f (diff) |
Merge commit 'origin/master' into glsl-pp-rework-2
Conflicts:
src/gallium/winsys/gdi/SConscript
144 files changed, 5755 insertions, 2905 deletions
diff --git a/configs/default b/configs/default index 9e4bb08ea9e..cb3ca1046f4 100644 --- a/configs/default +++ b/configs/default @@ -23,6 +23,7 @@ HOST_CC = $(CC) CFLAGS = -O CXXFLAGS = -O LDFLAGS = +HOST_CFLAGS = $(CFLAGS) GLU_CFLAGS = # Compiler for building demos/tests/etc diff --git a/configure.ac b/configure.ac index c5ef676e2e5..75189761ee7 100644 --- a/configure.ac +++ b/configure.ac @@ -1202,7 +1202,7 @@ if test "x$enable_gallium_radeon" = xyes; then fi dnl -dnl Gallium Radeon configuration +dnl Gallium Nouveau configuration dnl AC_ARG_ENABLE([gallium-nouveau], [AS_HELP_STRING([--enable-gallium-nouveau], diff --git a/docs/relnotes-7.5.2.html b/docs/relnotes-7.5.2.html index 32100142c0c..b638c0517dd 100644 --- a/docs/relnotes-7.5.2.html +++ b/docs/relnotes-7.5.2.html @@ -45,6 +45,10 @@ tbd <ul> <li>Assorted bug fixes for i965/i945 drivers <li>Fixed Gallium glDrawPixels(GL_STENCIL_INDEX) failure. +<li>Fixed GLSL linker/preprocessor version directive issue seen in Wine + (such as bug 23946) +<li>glUseProgram() is now compiled into display lists (bug 23746). +<li>glUniform functions are now compiled into display lists </ul> diff --git a/docs/relnotes-7.6.html b/docs/relnotes-7.6.html index 8a476378e8a..9cd3417e7ea 100644 --- a/docs/relnotes-7.6.html +++ b/docs/relnotes-7.6.html @@ -57,6 +57,10 @@ This was written by Zack Rusin at Tungsten Graphics. GL_ARB_fragment_program.</li> <li>Added configure --with-max-width=W, --with-max-height=H options to specify max framebuffer, viewport size. +<li>Initial version of Gallium llvmpipe driver. This is a new driver based + on LLVM which makes exensive use of run-time code generation. This is + an "alpha" stage driver. See the src/gallium/drivers/llvmpipe/README + file for more information. </ul> diff --git a/docs/relnotes-7.7.html b/docs/relnotes-7.7.html index 755e8ac5208..ca6ec55b601 100644 --- a/docs/relnotes-7.7.html +++ b/docs/relnotes-7.7.html @@ -37,6 +37,7 @@ tbd <li>GL_ARB_draw_elements_base_vertex (supported in Intel i965 and software drivers)</li> <li>GL_ARB_depth_clamp (supported in Intel i965 DRI and software drivers)</li> <li>GL_NV_depth_clamp (supported in Intel i965 DRI and software drivers)</li> +<li>GL_ARB_provoking_vertex (same as GL_EXT_provoking_vertex)</li> </ul> diff --git a/include/GL/gl.h b/include/GL/gl.h index 05362b97762..5f8bc2b708c 100644 --- a/include/GL/gl.h +++ b/include/GL/gl.h @@ -1740,6 +1740,9 @@ GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target, GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ); +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); + /* @@ -1945,6 +1948,18 @@ GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] ); GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert ); +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); + + + /* * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) */ diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c index 0df5ff09c33..015d50d86be 100644 --- a/progs/demos/cubemap.c +++ b/progs/demos/cubemap.c @@ -58,6 +58,7 @@ static GLint ClampIndex = 0; static GLboolean supportFBO = GL_FALSE; static GLboolean supportSeamless = GL_FALSE; static GLboolean seamless = GL_FALSE; +static GLuint TexObj = 0; static struct { @@ -543,6 +544,10 @@ static void init( GLboolean useImageFiles ) printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); + + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, TexObj); + if (useImageFiles) { load_envmaps(); } diff --git a/progs/demos/lodbias.c b/progs/demos/lodbias.c index 30b1ed13d5f..8d39bd605a7 100644 --- a/progs/demos/lodbias.c +++ b/progs/demos/lodbias.c @@ -43,6 +43,7 @@ static GLboolean Anim = GL_TRUE; static GLint Bias = 0, BiasStepSign = +1; /* ints avoid fp precision problem */ static GLint BiasMin = -400, BiasMax = 400; static int win = 0; +static GLuint TexObj = 0; static void @@ -214,6 +215,9 @@ static void Init( void ) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_2D, TexObj); + if (glutExtensionSupported("GL_SGIS_generate_mipmap")) { /* test auto mipmap generation */ GLint width, height, i; diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 8103a5cbca0..a8e4cf3e661 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -10,16 +10,15 @@ LIB_DEP = \ $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) \ $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) -LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) - -INCLUDE_DIRS = -I$(TOP)/progs/util +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) \ + -l$(GL_LIB) $(APP_LIB_DEPS) # using : to avoid APP_CC pointing to CC loop -CC:=$(APP_CC) +CC := $(APP_CC) CFLAGS += -I$(INCDIR) -LDLIBS=$(LIBS) +LDLIBS = $(LIBS) -DEMO_SOURCES = \ +PROG_SOURCES = \ array.c \ bitmap.c \ brick.c \ @@ -59,8 +58,8 @@ UTIL_SOURCES = \ readtex.c UTIL_OBJS = $(UTIL_SOURCES:.c=.o) -PROG_OBJS = $(DEMO_SOURCES:.c=.o) -PROGS = $(DEMO_SOURCES:%.c=%) +PROG_OBJS = $(PROG_SOURCES:.c=.o) +PROGS = $(PROG_SOURCES:%.c=%) ##### TARGETS ##### diff --git a/progs/perf/Makefile b/progs/perf/Makefile new file mode 100644 index 00000000000..219667439fd --- /dev/null +++ b/progs/perf/Makefile @@ -0,0 +1,49 @@ +# progs/demos/Makefile + +TOP = ../.. +include $(TOP)/configs/current + +INCDIR = $(TOP)/include + +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) \ + -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) + +# using : to avoid APP_CC pointing to CC loop +CC := $(APP_CC) +CFLAGS += -I$(INCDIR) +LDLIBS = $(LIBS) + +PROG_SOURCES = \ + drawoverhead.c \ + teximage.c \ + vbo.c \ + vertexrate.c \ + +PROG_OBJS = $(PROG_SOURCES:.c=.o) + +PROGS = $(PROG_SOURCES:%.c=%) + + +UTIL_SOURCES = \ + common.c \ + glmain.c + +UTIL_HEADERS = \ + common.h \ + glmain.h + +UTIL_OBJS = $(UTIL_SOURCES:.c=.o) + + + +default: $(PROGS) + +$(PROG_OBJS): $(UTIL_HEADERS) + +$(PROGS): $(UTIL_OBJS) + + + +clean: + -rm -f $(PROGS) + -rm -f *.o *~ diff --git a/progs/perf/common.c b/progs/perf/common.c new file mode 100644 index 00000000000..a50fc11cca5 --- /dev/null +++ b/progs/perf/common.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 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, 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 + * VMWARE 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. + */ + +/** + * Common perf code. This should be re-usable with other APIs. + */ + +#include "common.h" +#include "glmain.h" + + +/** + * Run function 'f' for enough iterations to reach a steady state. + * Return the rate (iterations/second). + */ +double +PerfMeasureRate(PerfRateFunc f) +{ + const double minDuration = 1.0; + double rate = 0.0, prevRate = 0.0; + unsigned subiters; + + /* Compute initial number of iterations to try. + * If the test function is pretty slow this helps to avoid + * extraordarily long run times. + */ + subiters = 2; + { + const double t0 = PerfGetTime(); + double t1; + do { + f(subiters); /* call the rendering function */ + t1 = PerfGetTime(); + subiters *= 2; + } while (t1 - t0 < 0.1 * minDuration); + } + /*printf("initial subIters = %u\n", subiters);*/ + + while (1) { + const double t0 = PerfGetTime(); + unsigned iters = 0; + double t1; + + do { + f(subiters); /* call the rendering function */ + t1 = PerfGetTime(); + iters += subiters; + } while (t1 - t0 < minDuration); + + rate = iters / (t1 - t0); + + if (0) + printf("prevRate %f rate %f ratio %f iters %u\n", + prevRate, rate, rate/prevRate, iters); + + /* Try and speed the search up by skipping a few steps: + */ + if (rate > prevRate * 1.6) + subiters *= 8; + else if (rate > prevRate * 1.2) + subiters *= 4; + else if (rate > prevRate * 1.05) + subiters *= 2; + else + break; + + prevRate = rate; + } + + if (0) + printf("%s returning iters %u rate %f\n", __FUNCTION__, subiters, rate); + return rate; +} + + diff --git a/progs/perf/common.h b/progs/perf/common.h new file mode 100644 index 00000000000..8b6091530d0 --- /dev/null +++ b/progs/perf/common.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 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, 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 + * VMWARE 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 COMMON_H +#define COMMON_H + + +typedef void (*PerfRateFunc)(unsigned count); + + +extern double +PerfMeasureRate(PerfRateFunc f); + + +#endif /* COMMON_H */ + diff --git a/progs/perf/drawoverhead.c b/progs/perf/drawoverhead.c new file mode 100644 index 00000000000..8c99804d342 --- /dev/null +++ b/progs/perf/drawoverhead.c @@ -0,0 +1,133 @@ +/*
+ * Copyright (C) 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, 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
+ * VMWARE 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.
+ */
+
+/**
+ * Measure drawing overhead
+ *
+ * This is the first in a series of simple performance benchmarks.
+ * The code in this file should be as simple as possible to make it
+ * easily portable to other APIs.
+ *
+ * All the window-system stuff should be contained in glmain.c (or TBDmain.c).
+ * All the re-usable, generic code should be in common.c (XXX not done yet).
+ *
+ * Brian Paul
+ * 15 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+
+struct vertex
+{
+ GLfloat x, y;
+};
+
+static const struct vertex vertices[4] = {
+ { -1.0, -1.0 },
+ { 1.0, -1.0 },
+ { 1.0, 1.0 },
+ { -1.0, 1.0 }
+};
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), (void *) 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* misc GL state */
+ glAlphaFunc(GL_ALWAYS, 0.0);
+}
+
+
+static void
+DrawNoStateChange(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, 4);
+ }
+ glFinish();
+}
+
+
+static void
+DrawNopStateChange(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glDisable(GL_ALPHA_TEST);
+ glDrawArrays(GL_POINTS, 0, 4);
+ }
+ glFinish();
+}
+
+
+static void
+DrawStateChange(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ if (i & 1)
+ glEnable(GL_TEXTURE_GEN_S);
+ else
+ glDisable(GL_TEXTURE_GEN_S);
+ glDrawArrays(GL_POINTS, 0, 4);
+ }
+ glFinish();
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate0, rate1, rate2, overhead;
+
+ rate0 = PerfMeasureRate(DrawNoStateChange);
+ printf(" Draw only: %.1f draws/second\n", rate0);
+
+ rate1 = PerfMeasureRate(DrawNopStateChange);
+ overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0);
+ printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n",
+ rate1, overhead);
+
+ rate2 = PerfMeasureRate(DrawStateChange);
+ overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0);
+ printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n",
+ rate2, overhead);
+
+ exit(0);
+}
+
diff --git a/progs/perf/glmain.c b/progs/perf/glmain.c new file mode 100644 index 00000000000..62d14259f8b --- /dev/null +++ b/progs/perf/glmain.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 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, 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 + * VMWARE 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. + */ + +/** + * OpenGL/GLUT common code for perf programs. + * Brian Paul + * 15 Sep 2009 + */ + + +#include "glmain.h" +#include <GL/glut.h> + + +static int Win; +static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; +static GLboolean Anim = GL_FALSE; + + +/** Return time in seconds */ +double +PerfGetTime(void) +{ + return glutGet(GLUT_ELAPSED_TIME) * 0.001; +} + + +void +PerfSwapBuffers(void) +{ + glutSwapBuffers(); +} + + +static void +Idle(void) +{ + Xrot += 3.0; + Yrot += 4.0; + Zrot += 2.0; + glutPostRedisplay(); +} + + +static void +Draw(void) +{ + PerfDraw(); + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'z': + Zrot -= step; + break; + case 'Z': + Zrot += step; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Xrot -= step; + break; + case GLUT_KEY_DOWN: + Xrot += step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + glutPostRedisplay(); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Draw); + if (Anim) + glutIdleFunc(Idle); + PerfInit(); + glutMainLoop(); + return 0; +} diff --git a/progs/perf/glmain.h b/progs/perf/glmain.h new file mode 100644 index 00000000000..50480a80c0c --- /dev/null +++ b/progs/perf/glmain.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 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, 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 + * VMWARE 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 GLMAIN_H +#define GLMAIN_H + + +#define GL_GLEXT_PROTOTYPES +#include <GL/glew.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + + +/** Test programs can use these vars/functions */ + +extern int WinWidth, WinHeight; + +extern double +PerfGetTime(void); + +extern void +PerfSwapBuffers(void); + + +/** Test programs must implement these functions **/ + +extern void +PerfInit(void); + +extern void +PerfDraw(void); + + +#endif /* GLMAIN_H */ diff --git a/progs/perf/teximage.c b/progs/perf/teximage.c new file mode 100644 index 00000000000..b6d4f644dec --- /dev/null +++ b/progs/perf/teximage.c @@ -0,0 +1,210 @@ +/*
+ * Copyright (C) 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, 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
+ * VMWARE 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.
+ */
+
+/**
+ * Measure glTexSubImage2D rate
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+static GLuint TexObj = 0;
+static GLubyte *TexImage = NULL;
+static GLsizei TexSize;
+static GLenum TexSrcFormat, TexSrcType;
+
+static const GLboolean DrawPoint = GL_TRUE;
+static const GLboolean TexSubImage4 = GL_TRUE;
+
+struct vertex
+{
+ GLfloat x, y, s, t;
+};
+
+static const struct vertex vertices[1] = {
+ { 0.0, 0.0, 0.5, 0.5 },
+};
+
+
+#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ /* texture */
+ glGenTextures(1, &TexObj);
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+}
+
+
+static void
+UploadTexImage2D(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ /* XXX is this equivalent to a glTexSubImage call since we're
+ * always specifying the same image size? That case isn't optimized
+ * in Mesa but may be optimized in other drivers. Note sure how
+ * much difference that might make.
+ */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ TexSize, TexSize, 0,
+ TexSrcFormat, TexSrcType, TexImage);
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+static void
+UploadTexSubImage2D(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ if (TexSubImage4) {
+ GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2;
+ GLsizei halfPos = TexSize - halfSize;
+ /* do glTexSubImage2D in four pieces */
+ /* lower-left */
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* lower-right */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ halfPos, 0, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* upper-left */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, halfPos, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* upper-right */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ halfPos, halfPos, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* reset the unpacking state */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ }
+ else {
+ /* replace whole texture image at once */
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, TexSize, TexSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ }
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+/* XXX any other formats to measure? */
+static const struct {
+ GLenum format, type;
+ const char *name;
+} SrcFormats[] = {
+ { GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" },
+ { GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" },
+ { 0, 0, NULL }
+};
+
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ GLint maxSize;
+ double rate;
+ GLint fmt, subImage;
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
+
+ /* loop over source data formats */
+ for (fmt = 0; SrcFormats[fmt].format; fmt++) {
+ TexSrcFormat = SrcFormats[fmt].format;
+ TexSrcType = SrcFormats[fmt].type;
+
+ /* loop over glTexImage, glTexSubImage */
+ for (subImage = 0; subImage < 2; subImage++) {
+
+ /* loop over texture sizes */
+ for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) {
+ GLint bytesPerImage;
+ double mbPerSec;
+
+ bytesPerImage = TexSize * TexSize * 4;
+ TexImage = malloc(bytesPerImage);
+
+ if (subImage) {
+ /* create initial, empty texture */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ TexSize, TexSize, 0,
+ TexSrcFormat, TexSrcType, NULL);
+ rate = PerfMeasureRate(UploadTexSubImage2D);
+ }
+ else {
+ rate = PerfMeasureRate(UploadTexImage2D);
+ }
+
+ mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
+
+ printf(" glTex%sImage2D(%s %d x %d): "
+ "%.1f images/sec, %.1f MB/sec\n",
+ (subImage ? "Sub" : ""),
+ SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec);
+
+ free(TexImage);
+ }
+ }
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c new file mode 100644 index 00000000000..8545a33b7e3 --- /dev/null +++ b/progs/perf/vbo.c @@ -0,0 +1,138 @@ +/*
+ * Copyright (C) 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, 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
+ * VMWARE 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.
+ */
+
+/**
+ * Measure VBO upload speed.
+ * That is, measure glBufferDataARB() and glBufferSubDataARB().
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+
+static GLsizei VBOSize = 0;
+static GLubyte *VBOData = NULL;
+
+static const GLboolean DrawPoint = GL_TRUE;
+static const GLboolean BufferSubDataInHalves = GL_TRUE;
+
+static const GLfloat Vertex0[2] = { 0.0, 0.0 };
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+}
+
+
+static void
+UploadVBO(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
+
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+static void
+UploadSubVBO(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ if (BufferSubDataInHalves) {
+ GLsizei half = VBOSize / 2;
+ glBufferSubDataARB(GL_ARRAY_BUFFER, 0, half, VBOData);
+ glBufferSubDataARB(GL_ARRAY_BUFFER, half, half, VBOData + half);
+ }
+ else {
+ glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData);
+ }
+
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+static const GLsizei Sizes[] = {
+ 64,
+ 1024,
+ 16*1024,
+ 256*1024,
+ 1024*1024,
+ 16*1024*1024,
+ 0 /* end of list */
+};
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate, mbPerSec;
+ int sub, sz;
+
+ /* loop over whole/sub buffer upload */
+ for (sub = 0; sub < 2; sub++) {
+
+ /* loop over VBO sizes */
+ for (sz = 0; Sizes[sz]; sz++) {
+ VBOSize = Sizes[sz];
+
+ VBOData = malloc(VBOSize);
+ memcpy(VBOData, Vertex0, sizeof(Vertex0));
+
+ if (sub)
+ rate = PerfMeasureRate(UploadSubVBO);
+ else
+ rate = PerfMeasureRate(UploadVBO);
+
+ mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
+
+ printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n",
+ (sub ? "Sub" : ""), VBOSize, mbPerSec);
+
+ free(VBOData);
+ }
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c new file mode 100644 index 00000000000..f7e02624cc9 --- /dev/null +++ b/progs/perf/vertexrate.c @@ -0,0 +1,271 @@ +/*
+ * Copyright (C) 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, 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
+ * VMWARE 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.
+ */
+
+/**
+ * Measure simple vertex processing rate via:
+ * - immediate mode
+ * - vertex arrays
+ * - VBO vertex arrays
+ * - glDrawElements
+ * - VBO glDrawElements
+ * - glDrawRangeElements
+ * - VBO glDrawRangeElements
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+
+#define MAX_VERTS (100 * 100)
+
+/** glVertex2/3/4 size */
+#define VERT_SIZE 4
+
+int WinWidth = 500, WinHeight = 500;
+
+static GLuint VertexBO, ElementBO;
+
+static unsigned NumVerts = MAX_VERTS;
+static unsigned VertBytes = VERT_SIZE * sizeof(float);
+static float *VertexData = NULL;
+
+static unsigned NumElements = MAX_VERTS;
+static GLuint *Elements = NULL;
+
+
+/**
+ * Load VertexData buffer with a 2-D grid of points in the range [-1,1]^2.
+ */
+static void
+InitializeVertexData(void)
+{
+ unsigned i;
+ float x = -1.0, y = -1.0;
+ float dx = 2.0 / 100;
+ float dy = 2.0 / 100;
+
+ VertexData = (float *) malloc(NumVerts * VertBytes);
+
+ for (i = 0; i < NumVerts; i++) {
+ VertexData[i * VERT_SIZE + 0] = x;
+ VertexData[i * VERT_SIZE + 1] = y;
+ VertexData[i * VERT_SIZE + 2] = 0.0;
+ VertexData[i * VERT_SIZE + 3] = 1.0;
+ x += dx;
+ if (x > 1.0) {
+ x = -1.0;
+ y += dy;
+ }
+ }
+
+ Elements = (GLuint *) malloc(NumVerts * sizeof(GLuint));
+
+ for (i = 0; i < NumVerts; i++) {
+ Elements[i] = NumVerts - i - 1;
+ }
+}
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ InitializeVertexData();
+
+ /* setup VertexBO */
+ glGenBuffersARB(1, &VertexBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ NumVerts * VertBytes, VertexData, GL_STATIC_DRAW_ARB);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* setup ElementBO */
+ glGenBuffersARB(1, &ElementBO);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ElementBO);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ NumElements * sizeof(GLuint), Elements, GL_STATIC_DRAW_ARB);
+}
+
+
+static void
+DrawImmediate(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ for (i = 0; i < count; i++) {
+ unsigned j;
+ glBegin(GL_POINTS);
+ for (j = 0; j < NumVerts; j++) {
+#if VERT_SIZE == 4
+ glVertex4fv(VertexData + j * 4);
+#elif VERT_SIZE == 3
+ glVertex3fv(VertexData + j * 3);
+#elif VERT_SIZE == 2
+ glVertex2fv(VertexData + j * 2);
+#else
+ abort();
+#endif
+ }
+ glEnd();
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawArraysMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, NumVerts);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawArraysVBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, NumVerts);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawElementsMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, Elements);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawElementsBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, (void *) 0);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawRangeElementsMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
+ NumVerts, GL_UNSIGNED_INT, Elements);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawRangeElementsBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
+ NumVerts, GL_UNSIGNED_INT, (void *) 0);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE);
+
+ rate = PerfMeasureRate(DrawImmediate);
+ rate *= NumVerts;
+ printf(" Immediate mode: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawArraysMem);
+ rate *= NumVerts;
+ printf(" glDrawArrays: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawArraysVBO);
+ rate *= NumVerts;
+ printf(" VBO glDrawArrays: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawElementsMem);
+ rate *= NumVerts;
+ printf(" glDrawElements: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawElementsBO);
+ rate *= NumVerts;
+ printf(" VBO glDrawElements: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawRangeElementsMem);
+ rate *= NumVerts;
+ printf(" glDrawRangeElements: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawRangeElementsBO);
+ rate *= NumVerts;
+ printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate);
+
+ exit(0);
+}
diff --git a/progs/tests/zreaddraw.c b/progs/tests/zreaddraw.c index 0821d5fb357..7dfed20cfb9 100644 --- a/progs/tests/zreaddraw.c +++ b/progs/tests/zreaddraw.c @@ -13,14 +13,16 @@ static GLint WinWidth = 500, WinHeight = 500; static GLboolean Invert = GL_FALSE; +static GLboolean TestPacking = GL_FALSE; +static GLboolean TestList = GL_FALSE; static void Display(void) { - GLfloat depth[100 * 100]; - GLfloat depth2[400 * 400]; - GLfloat min, max; - int i; + GLfloat depth[100 * 100 * 2]; + GLfloat depth2[400 * 400]; /* *2 to test pixelstore stuff */ + GLuint list; + GLenum depthType = GL_FLOAT; glClearColor(0.5, 0.5, 0.5, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -36,16 +38,32 @@ static void Display(void) glLoadIdentity(); glutSolidSphere(1.0, 20, 10); + if (TestPacking) { + glPixelStorei(GL_PACK_ROW_LENGTH, 120); + glPixelStorei(GL_PACK_SKIP_PIXELS, 5); + } + /* read the depth image */ - glReadPixels(0, 0, 100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth); - min = max = depth[0]; - for (i = 1; i < 100 * 100; i++) { - if (depth[i] < min) - min = depth[i]; - if (depth[i] > max) - max = depth[i]; + glReadPixels(0, 0, 100, 100, GL_DEPTH_COMPONENT, depthType, depth); + if (depthType == GL_FLOAT) { + GLfloat min, max; + int i; + min = max = depth[0]; + for (i = 1; i < 100 * 100; i++) { + if (depth[i] < min) + min = depth[i]; + if (depth[i] > max) + max = depth[i]; + } + printf("Depth value range: [%f, %f]\n", min, max); + } + + if (TestPacking) { + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 120); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 5); } - printf("Depth value range: [%f, %f]\n", min, max); /* draw depth image with scaling (into z buffer) */ glPixelZoom(4.0, 4.0); @@ -55,12 +73,27 @@ static void Display(void) glPixelTransferf(GL_DEPTH_SCALE, -1.0); glPixelTransferf(GL_DEPTH_BIAS, 1.0); } - glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth); + if (TestList) { + list = glGenLists(1); + glNewList(list, GL_COMPILE); + glDrawPixels(100, 100, GL_DEPTH_COMPONENT, depthType, depth); + glEndList(); + glCallList(list); + glDeleteLists(list, 1); + } + else { + glDrawPixels(100, 100, GL_DEPTH_COMPONENT, depthType, depth); + } if (Invert) { glPixelTransferf(GL_DEPTH_SCALE, 1.0); glPixelTransferf(GL_DEPTH_BIAS, 0.0); } + if (TestPacking) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + } + glDisable(GL_DEPTH_TEST); /* read back scaled depth image */ @@ -89,6 +122,14 @@ static void Key(unsigned char key, int x, int y) case 'i': Invert = !Invert; break; + case 'p': + TestPacking = !TestPacking; + printf("Test pixel pack/unpack: %d\n", TestPacking); + break; + case 'l': + TestList = !TestList; + printf("Test dlist: %d\n", TestList); + break; case 27: exit(0); break; diff --git a/progs/vp/vp-tris.c b/progs/vp/vp-tris.c index 97995accdd1..1356242d971 100644 --- a/progs/vp/vp-tris.c +++ b/progs/vp/vp-tris.c @@ -119,6 +119,12 @@ static void Init( void ) glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum); glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, sz, (const GLubyte *) buf); + if (glGetError()) { + printf("Program failed to compile:\n%s\n", buf); + printf("Error: %s\n", + (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + exit(1); + } assert(glIsProgramARB(prognum)); } diff --git a/scons/dxsdk.py b/scons/dxsdk.py index de090e4f991..920cc2f689d 100644 --- a/scons/dxsdk.py +++ b/scons/dxsdk.py @@ -52,11 +52,20 @@ def generate(env): target_cpu = 'x64' else: raise SCons.Errors.InternalError, "Unsupported target machine" - include_dir = 'Include' + + include_dir = os.path.join(dxsdk_root, 'Include') + lib_dir = os.path.join(dxsdk_root, 'Lib', target_cpu) 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)]) + + gcc = 'gcc' in os.path.basename(env['CC']).split('-') + if gcc: + # Make GCC more forgiving towards Microsoft's headers + env.Prepend(CPPFLAGS = ['-isystem', include_dir]) + else: + env.Prepend(CPPPATH = [include_dir]) + + env.Prepend(LIBPATH = [lib_dir]) def exists(env): return get_dxsdk_root(env) is not None diff --git a/scons/llvm.py b/scons/llvm.py index 46a8d829ca4..d3293bb404f 100644 --- a/scons/llvm.py +++ b/scons/llvm.py @@ -51,7 +51,9 @@ def generate(env): llvm_bin_dir = os.path.join(llvm_dir, llvm_subdir, 'bin') if not os.path.isdir(llvm_bin_dir): - raise SCons.Errors.InternalError, "LLVM build directory not found" + llvm_bin_dir = os.path.join(llvm_dir, 'bin') + if not os.path.isdir(llvm_bin_dir): + raise SCons.Errors.InternalError, "LLVM binary directory not found" env.PrependENVPath('PATH', llvm_bin_dir) @@ -65,6 +67,8 @@ def generate(env): except OSError: print 'llvm-config version %s failed' % version else: + if env['platform'] == 'windows': + env.Append(LIBS = ['imagehlp', 'psapi']) env['LINK'] = env['CXX'] env['LLVM_VERSION'] = version diff --git a/scons/winddk.py b/scons/winddk.py index afcea9909a6..4dac16ee66e 100644 --- a/scons/winddk.py +++ b/scons/winddk.py @@ -85,8 +85,6 @@ def get_winddk_paths(env, version, root): else: # TODO: take in consideration the host cpu bin_dir = os.path.join(root, 'bin', 'win64', 'x86', cpu_bin(target_cpu)) - - env.PrependENVPath('PATH', [bin_dir]) crt_inc_dir = os.path.join(root, 'inc', 'crt') if version_major >= 6000: @@ -98,17 +96,33 @@ def get_winddk_paths(env, version, root): sdk_inc_dir = os.path.join(root, 'inc', target_os) wdm_inc_dir = os.path.join(root, 'inc', 'ddk', 'wdm', target_os) - env.PrependENVPath('INCLUDE', [ - wdm_inc_dir, - ddk_inc_dir, - crt_inc_dir, - sdk_inc_dir, - ]) + if env['toolchain'] == 'winddk': + env.PrependENVPath('PATH', [bin_dir]) + env.PrependENVPath('INCLUDE', [ + wdm_inc_dir, + ddk_inc_dir, + crt_inc_dir, + sdk_inc_dir, + ]) + env.PrependENVPath('LIB', [ + os.path.join(root, 'lib', 'crt', target_cpu), + os.path.join(root, 'lib', target_os, target_cpu), + ]) + elif env['toolchain'] == 'crossmingw': + env.Prepend(CPPFLAGS = [ + '-isystem', ddk_inc_dir, + '-isystem', sdk_inc_dir, + ]) + else: + env.Prepend(CPPPATH = [ + wdm_inc_dir, + ddk_inc_dir, + sdk_inc_dir, + ]) + env.Prepend(LIBPATH = [ + os.path.join(root, 'lib', target_os, target_cpu), + ]) - env.PrependENVPath('LIB', [ - os.path.join(root, 'lib', 'crt', target_cpu), - os.path.join(root, 'lib', target_os, target_cpu), - ]) def generate(env): if not env.has_key('ENV'): @@ -120,9 +134,10 @@ def generate(env): get_winddk_paths(env, version, root) break - msvc_sa.generate(env) - mslib_sa.generate(env) - mslink_sa.generate(env) + if env['toolchain'] == 'winddk': + msvc_sa.generate(env) + mslib_sa.generate(env) + mslink_sa.generate(env) def exists(env): for version in versions: diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 6e82983e586..f1bf94f17dd 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -2,7 +2,7 @@ PIPE_FORMAT_A8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyxw, PIPE_FORMAT_X8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyx1, rgb PIPE_FORMAT_B8G8R8A8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb PIPE_FORMAT_B8G8R8X8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb -PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un1 , un5 , un5 , un5 , zyxw, rgb +PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb PIPE_FORMAT_A4R4G4B4_UNORM , arith , 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb PIPE_FORMAT_R5G6B5_UNORM , arith , 1, 1, un5 , un6 , un5 , , zyx1, rgb PIPE_FORMAT_A2B10G10R10_UNORM , arith , 1, 1, un10, un10, un10, un2 , xyzw, rgb diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index b12c97dfb4d..b428dc544c3 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -354,7 +354,9 @@ util_is_pot(unsigned x) * Find first bit set in word. Least significant bit is 1. * Return 0 if no bits set. */ -#if defined(_MSC_VER) && _MSC_VER >= 1300 +#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) +unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); +#pragma intrinsic(_BitScanForward) static INLINE unsigned long ffs( unsigned long u ) { diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index bd48ce70050..9161747fdbf 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -64,8 +64,6 @@ cell_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_GLSL: return 1; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 9f017a14cca..a1dd43c1bcc 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -101,8 +101,6 @@ i915_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index b22e105f106..fb68fd624b3 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -85,8 +85,6 @@ brw_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 06c586e6bb9..cd7b6356d28 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -3,6 +3,8 @@ include $(TOP)/configs/current LIBNAME = llvmpipe +CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS + C_SOURCES = \ lp_bld_alpha.c \ lp_bld_arit.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index dea4b703c45..f4a9a3b22e2 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -3,7 +3,7 @@ Import('*') env = env.Clone() env.Tool('llvm') -if env.has_key('LLVM_VERSION') is False: +if not env.has_key('LLVM_VERSION'): print 'warning: LLVM not found: not building llvmpipe' Return() diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c index 49c2f911af7..2b4bc5c819d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c @@ -45,7 +45,7 @@ void lp_build_alpha_test(LLVMBuilderRef builder, const struct pipe_alpha_state *state, - union lp_type type, + struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef alpha, LLVMValueRef ref) diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h index 9dbcdb4daab..634575670db 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h @@ -38,14 +38,14 @@ #include <llvm-c/Core.h> struct pipe_alpha_state; -union lp_type; +struct lp_type; struct lp_build_mask_context; void lp_build_alpha_test(LLVMBuilderRef builder, const struct pipe_alpha_state *state, - union lp_type type, + struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef alpha, LLVMValueRef ref); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index ce3e5f91c07..0b115fc9b07 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -65,7 +65,7 @@ lp_build_min_simple(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; const char *intrinsic = NULL; LLVMValueRef cond; @@ -113,7 +113,7 @@ lp_build_max_simple(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; const char *intrinsic = NULL; LLVMValueRef cond; @@ -159,7 +159,7 @@ LLVMValueRef lp_build_comp(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; if(a == bld->one) return bld->zero; @@ -188,7 +188,7 @@ lp_build_add(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMValueRef res; if(a == bld->zero) @@ -241,7 +241,7 @@ lp_build_sub(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMValueRef res; if(b == bld->zero) @@ -405,7 +405,7 @@ lp_build_mul(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; if(a == bld->zero) return bld->zero; @@ -477,7 +477,7 @@ lp_build_div(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; if(a == bld->zero) return bld->zero; @@ -590,7 +590,7 @@ LLVMValueRef lp_build_abs(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); if(!type.sign) @@ -627,7 +627,7 @@ LLVMValueRef lp_build_sgn(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMValueRef cond; LLVMValueRef res; @@ -678,7 +678,7 @@ lp_build_round_sse41(struct lp_build_context *bld, LLVMValueRef a, enum lp_build_round_sse41_mode mode) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); const char *intrinsic; @@ -706,7 +706,7 @@ LLVMValueRef lp_build_round(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; assert(type.floating); @@ -724,7 +724,7 @@ LLVMValueRef lp_build_floor(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; assert(type.floating); @@ -742,7 +742,7 @@ LLVMValueRef lp_build_ceil(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; assert(type.floating); @@ -760,7 +760,7 @@ LLVMValueRef lp_build_trunc(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; assert(type.floating); @@ -782,7 +782,7 @@ LLVMValueRef lp_build_int(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); assert(type.floating); @@ -805,7 +805,7 @@ LLVMValueRef lp_build_sqrt(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); char intrinsic[32]; @@ -823,7 +823,7 @@ LLVMValueRef lp_build_rcp(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; if(a == bld->zero) return bld->undef; @@ -854,7 +854,7 @@ LLVMValueRef lp_build_rsqrt(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; assert(type.floating); @@ -875,7 +875,7 @@ LLVMValueRef lp_build_cos(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); char intrinsic[32]; @@ -895,7 +895,7 @@ LLVMValueRef lp_build_sin(struct lp_build_context *bld, LLVMValueRef a) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); char intrinsic[32]; @@ -966,7 +966,7 @@ lp_build_polynomial(struct lp_build_context *bld, const double *coeffs, unsigned num_coeffs) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMValueRef res = NULL; unsigned i; @@ -1014,7 +1014,7 @@ lp_build_exp2_approx(struct lp_build_context *bld, LLVMValueRef *p_frac_part, LLVMValueRef *p_exp2) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); LLVMValueRef ipart = NULL; @@ -1107,7 +1107,7 @@ lp_build_log2_approx(struct lp_build_context *bld, LLVMValueRef *p_floor_log2, LLVMValueRef *p_log2) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.h b/src/gallium/drivers/llvmpipe/lp_bld_arit.h index 5e083b847fd..d68a97c4b87 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.h @@ -40,7 +40,7 @@ #include <llvm-c/Core.h> -union lp_type type; +struct lp_type type; struct lp_build_context; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/drivers/llvmpipe/lp_bld_blend.h index d19e18846c2..da272e549f3 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h @@ -46,7 +46,7 @@ struct pipe_blend_state; -union lp_type; +struct lp_type; struct lp_build_context; @@ -74,7 +74,7 @@ lp_build_blend_func(struct lp_build_context *bld, LLVMValueRef lp_build_blend_aos(LLVMBuilderRef builder, const struct pipe_blend_state *blend, - union lp_type type, + struct lp_type type, LLVMValueRef src, LLVMValueRef dst, LLVMValueRef const_, @@ -84,7 +84,7 @@ lp_build_blend_aos(LLVMBuilderRef builder, void lp_build_blend_soa(LLVMBuilderRef builder, const struct pipe_blend_state *blend, - union lp_type type, + struct lp_type type, LLVMValueRef src[4], LLVMValueRef dst[4], LLVMValueRef const_[4], diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c index c11a9398f87..d14f468ba93 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c @@ -303,7 +303,7 @@ lp_build_blend_func(struct lp_build_context *bld, LLVMValueRef lp_build_blend_aos(LLVMBuilderRef builder, const struct pipe_blend_state *blend, - union lp_type type, + struct lp_type type, LLVMValueRef src, LLVMValueRef dst, LLVMValueRef const_, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c index b92254a7d6f..9511299d558 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c @@ -199,7 +199,7 @@ lp_build_blend_soa_factor(struct lp_build_blend_soa_context *bld, void lp_build_blend_soa(LLVMBuilderRef builder, const struct pipe_blend_state *blend, - union lp_type type, + struct lp_type type, LLVMValueRef src[4], LLVMValueRef dst[4], LLVMValueRef con[4], diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.c b/src/gallium/drivers/llvmpipe/lp_bld_const.c index 21487365eae..c8eaa8c3940 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_const.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_const.c @@ -42,7 +42,7 @@ unsigned -lp_mantissa(union lp_type type) +lp_mantissa(struct lp_type type) { assert(type.floating); @@ -72,7 +72,7 @@ lp_mantissa(union lp_type type) * Same as lp_const_scale(), but in terms of shifts. */ unsigned -lp_const_shift(union lp_type type) +lp_const_shift(struct lp_type type) { if(type.floating) return 0; @@ -86,7 +86,7 @@ lp_const_shift(union lp_type type) unsigned -lp_const_offset(union lp_type type) +lp_const_offset(struct lp_type type) { if(type.floating || type.fixed) return 0; @@ -104,7 +104,7 @@ lp_const_offset(union lp_type type) * else for the fixed points types and normalized integers. */ double -lp_const_scale(union lp_type type) +lp_const_scale(struct lp_type type) { unsigned long long llscale; double dscale; @@ -122,7 +122,7 @@ lp_const_scale(union lp_type type) * Minimum value representable by the type. */ double -lp_const_min(union lp_type type) +lp_const_min(struct lp_type type) { unsigned bits; @@ -158,7 +158,7 @@ lp_const_min(union lp_type type) * Maximum value representable by the type. */ double -lp_const_max(union lp_type type) +lp_const_max(struct lp_type type) { unsigned bits; @@ -190,7 +190,7 @@ lp_const_max(union lp_type type) double -lp_const_eps(union lp_type type) +lp_const_eps(struct lp_type type) { if (type.floating) { switch(type.width) { @@ -211,7 +211,7 @@ lp_const_eps(union lp_type type) LLVMValueRef -lp_build_undef(union lp_type type) +lp_build_undef(struct lp_type type) { LLVMTypeRef vec_type = lp_build_vec_type(type); return LLVMGetUndef(vec_type); @@ -219,7 +219,7 @@ lp_build_undef(union lp_type type) LLVMValueRef -lp_build_zero(union lp_type type) +lp_build_zero(struct lp_type type) { LLVMTypeRef vec_type = lp_build_vec_type(type); return LLVMConstNull(vec_type); @@ -227,7 +227,7 @@ lp_build_zero(union lp_type type) LLVMValueRef -lp_build_one(union lp_type type) +lp_build_one(struct lp_type type) { LLVMTypeRef elem_type; LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; @@ -269,7 +269,7 @@ lp_build_one(union lp_type type) LLVMValueRef -lp_build_const_scalar(union lp_type type, +lp_build_const_scalar(struct lp_type type, double val) { LLVMTypeRef elem_type = lp_build_elem_type(type); @@ -295,7 +295,7 @@ lp_build_const_scalar(union lp_type type, LLVMValueRef -lp_build_int_const_scalar(union lp_type type, +lp_build_int_const_scalar(struct lp_type type, long long val) { LLVMTypeRef elem_type = lp_build_int_elem_type(type); @@ -312,7 +312,7 @@ lp_build_int_const_scalar(union lp_type type, LLVMValueRef -lp_build_const_aos(union lp_type type, +lp_build_const_aos(struct lp_type type, double r, double g, double b, double a, const unsigned char *swizzle) { @@ -352,8 +352,8 @@ lp_build_const_aos(union lp_type type, LLVMValueRef -lp_build_const_mask_aos(union lp_type type, - boolean cond[4]) +lp_build_const_mask_aos(struct lp_type type, + const boolean cond[4]) { LLVMTypeRef elem_type = LLVMIntType(type.width); LLVMValueRef masks[LP_MAX_VECTOR_LENGTH]; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.h b/src/gallium/drivers/llvmpipe/lp_bld_const.h index 1934530ea3c..ffb302f7366 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_const.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_const.h @@ -42,67 +42,67 @@ #include <pipe/p_compiler.h> -union lp_type type; +struct lp_type type; unsigned -lp_mantissa(union lp_type type); +lp_mantissa(struct lp_type type); unsigned -lp_const_shift(union lp_type type); +lp_const_shift(struct lp_type type); unsigned -lp_const_offset(union lp_type type); +lp_const_offset(struct lp_type type); double -lp_const_scale(union lp_type type); +lp_const_scale(struct lp_type type); double -lp_const_min(union lp_type type); +lp_const_min(struct lp_type type); double -lp_const_max(union lp_type type); +lp_const_max(struct lp_type type); double -lp_const_eps(union lp_type type); +lp_const_eps(struct lp_type type); LLVMValueRef -lp_build_undef(union lp_type type); +lp_build_undef(struct lp_type type); LLVMValueRef -lp_build_zero(union lp_type type); +lp_build_zero(struct lp_type type); LLVMValueRef -lp_build_one(union lp_type type); +lp_build_one(struct lp_type type); LLVMValueRef -lp_build_const_scalar(union lp_type type, +lp_build_const_scalar(struct lp_type type, double val); LLVMValueRef -lp_build_int_const_scalar(union lp_type type, +lp_build_int_const_scalar(struct lp_type type, long long val); LLVMValueRef -lp_build_const_aos(union lp_type type, +lp_build_const_aos(struct lp_type type, double r, double g, double b, double a, const unsigned char *swizzle); LLVMValueRef -lp_build_const_mask_aos(union lp_type type, - boolean cond[4]); +lp_build_const_mask_aos(struct lp_type type, + const boolean cond[4]); #endif /* !LP_BLD_CONST_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.c b/src/gallium/drivers/llvmpipe/lp_bld_conv.c index c5a71d2c726..186cac70f62 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.c @@ -86,7 +86,7 @@ */ LLVMValueRef lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, - union lp_type src_type, + struct lp_type src_type, unsigned dst_width, LLVMValueRef src) { @@ -152,7 +152,7 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, LLVMValueRef lp_build_unsigned_norm_to_float(LLVMBuilderRef builder, unsigned src_width, - union lp_type dst_type, + struct lp_type dst_type, LLVMValueRef src) { LLVMTypeRef vec_type = lp_build_vec_type(dst_type); @@ -248,8 +248,8 @@ lp_build_const_pack_shuffle(unsigned n) */ static void lp_build_expand(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, LLVMValueRef src, LLVMValueRef *dst, unsigned num_dsts) { @@ -266,7 +266,7 @@ lp_build_expand(LLVMBuilderRef builder, dst[0] = src; while(src_type.width < dst_type.width) { - union lp_type new_type = src_type; + struct lp_type new_type = src_type; LLVMTypeRef new_vec_type; new_type.width *= 2; @@ -314,8 +314,8 @@ lp_build_expand(LLVMBuilderRef builder, */ static LLVMValueRef lp_build_pack2(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, boolean clamped, LLVMValueRef lo, LLVMValueRef hi) @@ -392,8 +392,8 @@ lp_build_pack2(LLVMBuilderRef builder, */ static LLVMValueRef lp_build_pack(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, boolean clamped, const LLVMValueRef *src, unsigned num_srcs) { @@ -410,7 +410,7 @@ lp_build_pack(LLVMBuilderRef builder, tmp[i] = src[i]; while(src_type.width > dst_type.width) { - union lp_type new_type = src_type; + struct lp_type new_type = src_type; new_type.width /= 2; new_type.length *= 2; @@ -442,12 +442,12 @@ lp_build_pack(LLVMBuilderRef builder, */ void lp_build_conv(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, const LLVMValueRef *src, unsigned num_srcs, LLVMValueRef *dst, unsigned num_dsts) { - union lp_type tmp_type; + struct lp_type tmp_type; LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH]; unsigned num_tmps; unsigned i; @@ -470,7 +470,7 @@ lp_build_conv(LLVMBuilderRef builder, * Clamp if necessary */ - if(src_type.value != dst_type.value) { + if(memcmp(&src_type, &dst_type, sizeof src_type) != 0) { struct lp_build_context bld; double src_min = lp_const_min(src_type); double dst_min = lp_const_min(dst_type); @@ -656,8 +656,8 @@ lp_build_conv(LLVMBuilderRef builder, */ void lp_build_conv_mask(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, const LLVMValueRef *src, unsigned num_srcs, LLVMValueRef *dst, unsigned num_dsts) { diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.h b/src/gallium/drivers/llvmpipe/lp_bld_conv.h index 05c1ef2a100..ca378804d2a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_conv.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.h @@ -40,33 +40,33 @@ #include <llvm-c/Core.h> -union lp_type type; +struct lp_type type; LLVMValueRef lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, - union lp_type src_type, + struct lp_type src_type, unsigned dst_width, LLVMValueRef src); LLVMValueRef lp_build_unsigned_norm_to_float(LLVMBuilderRef builder, unsigned src_width, - union lp_type dst_type, + struct lp_type dst_type, LLVMValueRef src); void lp_build_conv(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, const LLVMValueRef *srcs, unsigned num_srcs, LLVMValueRef *dsts, unsigned num_dsts); void lp_build_conv_mask(LLVMBuilderRef builder, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, const LLVMValueRef *src, unsigned num_srcs, LLVMValueRef *dst, unsigned num_dsts); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index e5fe81193fc..21c665c4d4c 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -71,11 +71,11 @@ /** * Return a type appropriate for depth/stencil testing. */ -union lp_type +struct lp_type lp_depth_type(const struct util_format_description *format_desc, unsigned length) { - union lp_type type; + struct lp_type type; unsigned swizzle; assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); @@ -85,7 +85,7 @@ lp_depth_type(const struct util_format_description *format_desc, swizzle = format_desc->swizzle[0]; assert(swizzle < 4); - type.value = 0; + memset(&type, 0, sizeof type); type.width = format_desc->block.bits; if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) { @@ -114,7 +114,7 @@ lp_depth_type(const struct util_format_description *format_desc, void lp_build_depth_test(LLVMBuilderRef builder, const struct pipe_depth_state *state, - union lp_type type, + struct lp_type type, const struct util_format_description *format_desc, struct lp_build_mask_context *mask, LLVMValueRef src, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.h b/src/gallium/drivers/llvmpipe/lp_bld_depth.h index 5d2e042fcc5..79d6981bb51 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.h @@ -41,11 +41,11 @@ struct pipe_depth_state; struct util_format_description; -union lp_type; +struct lp_type; struct lp_build_mask_context; -union lp_type +struct lp_type lp_depth_type(const struct util_format_description *format_desc, unsigned length); @@ -53,7 +53,7 @@ lp_depth_type(const struct util_format_description *format_desc, void lp_build_depth_test(LLVMBuilderRef builder, const struct pipe_depth_state *state, - union lp_type type, + struct lp_type type, const struct util_format_description *format_desc, struct lp_build_mask_context *mask, LLVMValueRef src, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.c b/src/gallium/drivers/llvmpipe/lp_bld_flow.c index 69ed014ff3d..dcc25fbff86 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_flow.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.c @@ -405,7 +405,7 @@ lp_build_mask_check(struct lp_build_mask_context *mask) void lp_build_mask_begin(struct lp_build_mask_context *mask, struct lp_build_flow_context *flow, - union lp_type type, + struct lp_type type, LLVMValueRef value) { memset(mask, 0, sizeof *mask); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.h b/src/gallium/drivers/llvmpipe/lp_bld_flow.h index 9d76e3064dd..e61999ff06b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_flow.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.h @@ -38,7 +38,7 @@ #include <llvm-c/Core.h> -union lp_type; +struct lp_type; struct lp_build_flow_context; @@ -84,7 +84,7 @@ struct lp_build_mask_context void lp_build_mask_begin(struct lp_build_mask_context *mask, struct lp_build_flow_context *flow, - union lp_type type, + struct lp_type type, LLVMValueRef value); /** diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format.h b/src/gallium/drivers/llvmpipe/lp_bld_format.h index 5ee06560932..6d3f6926193 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_format.h @@ -39,7 +39,7 @@ #include "pipe/p_format.h" struct util_format_description; -union lp_type; +struct lp_type; /** @@ -103,7 +103,7 @@ lp_build_gather(LLVMBuilderRef builder, void lp_build_unpack_rgba_soa(LLVMBuilderRef builder, const struct util_format_description *format_desc, - union lp_type type, + struct lp_type type, LLVMValueRef packed, LLVMValueRef *rgba); @@ -111,7 +111,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, void lp_build_load_rgba_soa(LLVMBuilderRef builder, const struct util_format_description *format_desc, - union lp_type type, + struct lp_type type, LLVMValueRef base_ptr, LLVMValueRef offsets, LLVMValueRef *rgba); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c index 569e8d10a31..b5ff434e1ae 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c @@ -84,7 +84,7 @@ lp_build_gather(LLVMBuilderRef builder, static LLVMValueRef -lp_build_format_swizzle(union lp_type type, +lp_build_format_swizzle(struct lp_type type, const LLVMValueRef *inputs, enum util_format_swizzle swizzle) { @@ -110,7 +110,7 @@ lp_build_format_swizzle(union lp_type type, void lp_build_unpack_rgba_soa(LLVMBuilderRef builder, const struct util_format_description *format_desc, - union lp_type type, + struct lp_type type, LLVMValueRef packed, LLVMValueRef *rgba) { @@ -188,7 +188,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, void lp_build_load_rgba_soa(LLVMBuilderRef builder, const struct util_format_description *format_desc, - union lp_type type, + struct lp_type type, LLVMValueRef base_ptr, LLVMValueRef offsets, LLVMValueRef *rgba) diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c index cfe20a0d75b..338dbca6d1e 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c @@ -292,7 +292,7 @@ void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, const struct tgsi_token *tokens, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, LLVMValueRef a0_ptr, LLVMValueRef dadx_ptr, LLVMValueRef dady_ptr, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h index 9194f6233a7..9c57a10879b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h @@ -83,7 +83,7 @@ void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, const struct tgsi_token *tokens, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, LLVMValueRef a0_ptr, LLVMValueRef dadx_ptr, LLVMValueRef dady_ptr, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/drivers/llvmpipe/lp_bld_logic.c index 995a69c0f4c..6b6f8207697 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_logic.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.c @@ -45,7 +45,7 @@ lp_build_cmp(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); LLVMValueRef zeros = LLVMConstNull(int_vec_type); @@ -301,7 +301,7 @@ lp_build_select(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { - union lp_type type = bld->type; + struct lp_type type = bld->type; LLVMValueRef res; if(a == b) @@ -339,7 +339,7 @@ lp_build_select_aos(struct lp_build_context *bld, LLVMValueRef b, const boolean cond[4]) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; const unsigned n = type.length; unsigned i, j; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.h b/src/gallium/drivers/llvmpipe/lp_bld_logic.h index 9099e0fb5bf..a4ee7723b5f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_logic.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.h @@ -42,7 +42,7 @@ #include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */ -union lp_type type; +struct lp_type type; struct lp_build_context; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample.h b/src/gallium/drivers/llvmpipe/lp_bld_sample.h index 6f565af76d1..403d0e48367 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_sample.h @@ -40,7 +40,7 @@ struct pipe_texture; struct pipe_sampler_state; -union lp_type; +struct lp_type; /** @@ -123,7 +123,7 @@ void lp_build_sample_soa(LLVMBuilderRef builder, const struct lp_sampler_static_state *static_state, struct lp_sampler_dynamic_state *dynamic_state, - union lp_type fp_type, + struct lp_type fp_type, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c index 3ca25b0e76c..8ca1be6f1be 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c @@ -97,15 +97,15 @@ struct lp_build_sample_context const struct util_format_description *format_desc; /** Incoming coordinates type and build context */ - union lp_type coord_type; + struct lp_type coord_type; struct lp_build_context coord_bld; /** Integer coordinates */ - union lp_type int_coord_type; + struct lp_type int_coord_type; struct lp_build_context int_coord_bld; /** Output texels type and build context */ - union lp_type texel_type; + struct lp_type texel_type; struct lp_build_context texel_bld; }; @@ -208,6 +208,11 @@ lp_build_sample_wrap(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: /* FIXME */ + _debug_printf("warning: failed to translate texture wrap mode %u\n", wrap_mode); + coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero); + coord = lp_build_min(int_coord_bld, coord, length_minus_one); + break; + default: assert(0); } @@ -337,7 +342,7 @@ void lp_build_sample_soa(LLVMBuilderRef builder, const struct lp_sampler_static_state *static_state, struct lp_sampler_dynamic_state *dynamic_state, - union lp_type type, + struct lp_type type, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c index f35638be447..64e81f7b1fe 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c @@ -64,7 +64,7 @@ LLVMValueRef lp_build_broadcast_scalar(struct lp_build_context *bld, LLVMValueRef scalar) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; LLVMValueRef res; unsigned i; @@ -83,7 +83,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld, LLVMValueRef a, unsigned channel) { - const union lp_type type = bld->type; + const struct lp_type type = bld->type; const unsigned n = type.length; unsigned i, j; @@ -115,7 +115,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld, * YY00 YY00 .... YY00 * YYYY YYYY .... YYYY <= output */ - union lp_type type4 = type; + struct lp_type type4 = type; const char shifts[4][2] = { { 1, 2}, {-1, 2}, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h index cb0b6707ec8..1f6da804488 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h @@ -40,7 +40,7 @@ #include <llvm-c/Core.h> -union lp_type type; +struct lp_type type; struct lp_build_context; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h index 10c251c4162..eddb7a83fa2 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h @@ -39,7 +39,7 @@ struct tgsi_token; -union lp_type; +struct lp_type; struct lp_build_context; struct lp_build_mask_context; @@ -60,7 +60,7 @@ struct lp_build_sampler_soa void (*emit_fetch_texel)( struct lp_build_sampler_soa *sampler, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, @@ -72,7 +72,7 @@ struct lp_build_sampler_soa void lp_build_tgsi_soa(LLVMBuilderRef builder, const struct tgsi_token *tokens, - union lp_type type, + struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, const LLVMValueRef *pos, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c index b106ce2317f..adc81569ed5 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c @@ -1415,7 +1415,7 @@ emit_instruction( void lp_build_tgsi_soa(LLVMBuilderRef builder, const struct tgsi_token *tokens, - union lp_type type, + struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, const LLVMValueRef *pos, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.c b/src/gallium/drivers/llvmpipe/lp_bld_type.c index 577644b7ab8..606243d6c5a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_type.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_type.c @@ -33,7 +33,7 @@ LLVMTypeRef -lp_build_elem_type(union lp_type type) +lp_build_elem_type(struct lp_type type) { if (type.floating) { switch(type.width) { @@ -55,7 +55,7 @@ lp_build_elem_type(union lp_type type) LLVMTypeRef -lp_build_vec_type(union lp_type type) +lp_build_vec_type(struct lp_type type) { LLVMTypeRef elem_type = lp_build_elem_type(type); return LLVMVectorType(elem_type, type.length); @@ -69,7 +69,7 @@ lp_build_vec_type(union lp_type type) * type and check for identity. */ boolean -lp_check_elem_type(union lp_type type, LLVMTypeRef elem_type) +lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type) { LLVMTypeKind elem_kind; @@ -107,7 +107,7 @@ lp_check_elem_type(union lp_type type, LLVMTypeRef elem_type) boolean -lp_check_vec_type(union lp_type type, LLVMTypeRef vec_type) +lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type) { LLVMTypeRef elem_type; @@ -128,7 +128,7 @@ lp_check_vec_type(union lp_type type, LLVMTypeRef vec_type) boolean -lp_check_value(union lp_type type, LLVMValueRef val) +lp_check_value(struct lp_type type, LLVMValueRef val) { LLVMTypeRef vec_type; @@ -143,25 +143,26 @@ lp_check_value(union lp_type type, LLVMValueRef val) LLVMTypeRef -lp_build_int_elem_type(union lp_type type) +lp_build_int_elem_type(struct lp_type type) { return LLVMIntType(type.width); } LLVMTypeRef -lp_build_int_vec_type(union lp_type type) +lp_build_int_vec_type(struct lp_type type) { LLVMTypeRef elem_type = lp_build_int_elem_type(type); return LLVMVectorType(elem_type, type.length); } -union lp_type -lp_int_type(union lp_type type) +struct lp_type +lp_int_type(struct lp_type type) { - union lp_type int_type; - int_type.value = 0; + struct lp_type int_type; + + memset(&int_type, 0, sizeof int_type); int_type.width = type.width; int_type.length = type.length; return int_type; @@ -171,7 +172,7 @@ lp_int_type(union lp_type type) void lp_build_context_init(struct lp_build_context *bld, LLVMBuilderRef builder, - union lp_type type) + struct lp_type type) { bld->builder = builder; bld->type = type; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.h b/src/gallium/drivers/llvmpipe/lp_bld_type.h index 9933e0b45c3..ee5ca3483c1 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_type.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_type.h @@ -56,58 +56,55 @@ * on the types used for intermediate computations, such as signed vs unsigned, * normalized values, or fixed point. */ -union lp_type { - struct { - /** - * Floating-point. Cannot be used with fixed. Integer numbers are - * represented by this zero. - */ - unsigned floating:1; - - /** - * Fixed-point. Cannot be used with floating. Integer numbers are - * represented by this zero. - */ - unsigned fixed:1; - - /** - * Whether it can represent negative values or not. - * - * If this is not set for floating point, it means that all values are - * assumed to be positive. - */ - unsigned sign:1; - - /** - * Whether values are normalized to fit [0, 1] interval, or [-1, 1] - * interval for signed types. - * - * For integer types it means the representable integer range should be - * interpreted as the interval above. - * - * For floating and fixed point formats it means the values should be - * clamped to the interval above. - */ - unsigned norm:1; - - /** - * Element width. - * - * For fixed point values, the fixed point is assumed to be at half the - * width. - */ - unsigned width:14; - - /** - * Vector length. - * - * width*length should be a power of two greater or equal to eight. - * - * @sa LP_MAX_VECTOR_LENGTH - */ - unsigned length:14; - }; - uint32_t value; +struct lp_type { + /** + * Floating-point. Cannot be used with fixed. Integer numbers are + * represented by this zero. + */ + unsigned floating:1; + + /** + * Fixed-point. Cannot be used with floating. Integer numbers are + * represented by this zero. + */ + unsigned fixed:1; + + /** + * Whether it can represent negative values or not. + * + * If this is not set for floating point, it means that all values are + * assumed to be positive. + */ + unsigned sign:1; + + /** + * Whether values are normalized to fit [0, 1] interval, or [-1, 1] + * interval for signed types. + * + * For integer types it means the representable integer range should be + * interpreted as the interval above. + * + * For floating and fixed point formats it means the values should be + * clamped to the interval above. + */ + unsigned norm:1; + + /** + * Element width. + * + * For fixed point values, the fixed point is assumed to be at half the + * width. + */ + unsigned width:14; + + /** + * Vector length. + * + * width*length should be a power of two greater or equal to eight. + * + * @sa LP_MAX_VECTOR_LENGTH + */ + unsigned length:14; }; @@ -124,7 +121,7 @@ struct lp_build_context * This not only describes the input/output LLVM types, but also whether * to normalize/clamp the results. */ - union lp_type type; + struct lp_type type; /** Same as lp_build_undef(type) */ LLVMValueRef undef; @@ -138,41 +135,41 @@ struct lp_build_context LLVMTypeRef -lp_build_elem_type(union lp_type type); +lp_build_elem_type(struct lp_type type); LLVMTypeRef -lp_build_vec_type(union lp_type type); +lp_build_vec_type(struct lp_type type); boolean -lp_check_elem_type(union lp_type type, LLVMTypeRef elem_type); +lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type); boolean -lp_check_vec_type(union lp_type type, LLVMTypeRef vec_type); +lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type); boolean -lp_check_value(union lp_type type, LLVMValueRef val); +lp_check_value(struct lp_type type, LLVMValueRef val); LLVMTypeRef -lp_build_int_elem_type(union lp_type type); +lp_build_int_elem_type(struct lp_type type); LLVMTypeRef -lp_build_int_vec_type(union lp_type type); +lp_build_int_vec_type(struct lp_type type); -union lp_type -lp_int_type(union lp_type type); +struct lp_type +lp_int_type(struct lp_type type); void lp_build_context_init(struct lp_build_context *bld, LLVMBuilderRef builder, - union lp_type type); + struct lp_type type); #endif /* !LP_BLD_TYPE_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 9465f763d50..b4a22ff4a97 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -152,7 +152,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) screen->provider = LLVMCreateModuleProviderForExistingModule(screen->module); if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) { - fprintf(stderr, "%s\n", error); + _debug_printf("%s\n", error); LLVMDisposeMessage(error); abort(); } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 0ce1a37bd47..ff7ef8658a9 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -65,8 +65,6 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_GLSL: return 1; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 618cf1ffb8d..9faed5a0b18 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -133,13 +133,13 @@ generate_pos0(LLVMBuilderRef builder, static void generate_depth(LLVMBuilderRef builder, const struct lp_fragment_shader_variant_key *key, - union lp_type src_type, + struct lp_type src_type, struct lp_build_mask_context *mask, LLVMValueRef src, LLVMValueRef dst_ptr) { const struct util_format_description *format_desc; - union lp_type dst_type; + struct lp_type dst_type; if(!key->depth.enabled) return; @@ -181,7 +181,7 @@ generate_fs(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, const struct lp_fragment_shader_variant_key *key, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, LLVMValueRef context_ptr, unsigned i, const struct lp_build_interp_soa_context *interp, @@ -299,7 +299,7 @@ generate_fs(struct llvmpipe_context *lp, static void generate_blend(const struct pipe_blend_state *blend, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, LLVMValueRef context_ptr, LLVMValueRef mask, LLVMValueRef *src, @@ -364,8 +364,8 @@ generate_fragment(struct llvmpipe_context *lp, { struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen); struct lp_fragment_shader_variant *variant; - union lp_type fs_type; - union lp_type blend_type; + struct lp_type fs_type; + struct lp_type blend_type; LLVMTypeRef fs_elem_type; LLVMTypeRef fs_vec_type; LLVMTypeRef fs_int_vec_type; @@ -431,7 +431,7 @@ generate_fragment(struct llvmpipe_context *lp, /* TODO: actually pick these based on the fs and color buffer * characteristics. */ - fs_type.value = 0; + memset(&fs_type, 0, sizeof fs_type); fs_type.floating = TRUE; /* floating point values */ fs_type.sign = TRUE; /* values are signed */ fs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ @@ -439,7 +439,7 @@ generate_fragment(struct llvmpipe_context *lp, fs_type.length = 4; /* 4 element per vector */ num_fs = 4; - blend_type.value = 0; + memset(&blend_type, 0, sizeof blend_type); blend_type.floating = FALSE; /* values are integers */ blend_type.sign = FALSE; /* values are unsigned */ blend_type.norm = TRUE; /* values are in [0,1] or [-1,1] */ diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h index 69aaae26e0a..a88e110c663 100644 --- a/src/gallium/drivers/llvmpipe/lp_test.h +++ b/src/gallium/drivers/llvmpipe/lp_test.h @@ -86,43 +86,43 @@ random_float(void); void -dump_type(FILE *fp, union lp_type type); +dump_type(FILE *fp, struct lp_type type); double -read_elem(union lp_type type, const void *src, unsigned index); +read_elem(struct lp_type type, const void *src, unsigned index); void -write_elem(union lp_type type, void *dst, unsigned index, double src); +write_elem(struct lp_type type, void *dst, unsigned index, double src); void -random_elem(union lp_type type, void *dst, unsigned index); +random_elem(struct lp_type type, void *dst, unsigned index); void -read_vec(union lp_type type, const void *src, double *dst); +read_vec(struct lp_type type, const void *src, double *dst); void -write_vec(union lp_type type, void *dst, const double *src); +write_vec(struct lp_type type, void *dst, const double *src); void -random_vec(union lp_type type, void *dst); +random_vec(struct lp_type type, void *dst); boolean -compare_vec_with_eps(union lp_type type, const void *res, const void *ref, double eps); +compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps); boolean -compare_vec(union lp_type type, const void *res, const void *ref); +compare_vec(struct lp_type type, const void *res, const void *ref); void -dump_vec(FILE *fp, union lp_type type, const void *src); +dump_vec(FILE *fp, struct lp_type type, const void *src); #endif /* !LP_TEST_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index 8dfad468e3c..94b661dcba4 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -80,7 +80,7 @@ static void write_tsv_row(FILE *fp, const struct pipe_blend_state *blend, enum vector_mode mode, - union lp_type type, + struct lp_type type, double cycles, boolean success) { @@ -125,7 +125,7 @@ static void dump_blend_type(FILE *fp, const struct pipe_blend_state *blend, enum vector_mode mode, - union lp_type type) + struct lp_type type) { fprintf(fp, "%s", mode ? "soa" : "aos"); @@ -153,7 +153,7 @@ static LLVMValueRef add_blend_test(LLVMModuleRef module, const struct pipe_blend_state *blend, enum vector_mode mode, - union lp_type type) + struct lp_type type) { LLVMTypeRef ret_type; LLVMTypeRef vec_type; @@ -467,7 +467,7 @@ test_one(unsigned verbose, FILE *fp, const struct pipe_blend_state *blend, enum vector_mode mode, - union lp_type type) + struct lp_type type) { LLVMModuleRef module = NULL; LLVMValueRef func = NULL; @@ -765,10 +765,10 @@ blend_funcs[] = { }; -const union lp_type blend_types[] = { +const struct lp_type blend_types[] = { /* float, fixed, sign, norm, width, len */ - {{ TRUE, FALSE, FALSE, TRUE, 32, 4 }}, /* f32 x 4 */ - {{ FALSE, FALSE, FALSE, TRUE, 8, 16 }}, /* u8n x 16 */ + { TRUE, FALSE, FALSE, TRUE, 32, 4 }, /* f32 x 4 */ + { FALSE, FALSE, FALSE, TRUE, 8, 16 }, /* u8n x 16 */ }; @@ -788,7 +788,7 @@ test_all(unsigned verbose, FILE *fp) const unsigned *alpha_dst_factor; struct pipe_blend_state blend; enum vector_mode mode; - const union lp_type *type; + const struct lp_type *type; bool success = TRUE; for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) { @@ -841,27 +841,27 @@ test_some(unsigned verbose, FILE *fp, unsigned long n) const unsigned *alpha_dst_factor; struct pipe_blend_state blend; enum vector_mode mode; - const union lp_type *type; + const struct lp_type *type; unsigned long i; bool success = TRUE; for(i = 0; i < n; ++i) { - rgb_func = &blend_funcs[random() % num_funcs]; - alpha_func = &blend_funcs[random() % num_funcs]; - rgb_src_factor = &blend_factors[random() % num_factors]; - alpha_src_factor = &blend_factors[random() % num_factors]; + rgb_func = &blend_funcs[rand() % num_funcs]; + alpha_func = &blend_funcs[rand() % num_funcs]; + rgb_src_factor = &blend_factors[rand() % num_factors]; + alpha_src_factor = &blend_factors[rand() % num_factors]; do { - rgb_dst_factor = &blend_factors[random() % num_factors]; + rgb_dst_factor = &blend_factors[rand() % num_factors]; } while(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE); do { - alpha_dst_factor = &blend_factors[random() % num_factors]; + alpha_dst_factor = &blend_factors[rand() % num_factors]; } while(*alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE); - mode = random() & 1; + mode = rand() & 1; - type = &blend_types[random() % num_types]; + type = &blend_types[rand() % num_types]; memset(&blend, 0, sizeof blend); blend.blend_enable = 1; diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c index e6489834af5..9dcf58e5dcd 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c @@ -59,8 +59,8 @@ write_tsv_header(FILE *fp) static void write_tsv_row(FILE *fp, - union lp_type src_type, - union lp_type dst_type, + struct lp_type src_type, + struct lp_type dst_type, double cycles, boolean success) { @@ -80,8 +80,8 @@ write_tsv_row(FILE *fp, static void dump_conv_types(FILE *fp, - union lp_type src_type, - union lp_type dst_type) + struct lp_type src_type, + struct lp_type dst_type) { fprintf(fp, "src_type="); dump_type(fp, src_type); @@ -96,8 +96,8 @@ dump_conv_types(FILE *fp, static LLVMValueRef add_conv_test(LLVMModuleRef module, - union lp_type src_type, unsigned num_srcs, - union lp_type dst_type, unsigned num_dsts) + struct lp_type src_type, unsigned num_srcs, + struct lp_type dst_type, unsigned num_dsts) { LLVMTypeRef args[2]; LLVMValueRef func; @@ -145,8 +145,8 @@ add_conv_test(LLVMModuleRef module, static boolean test_one(unsigned verbose, FILE *fp, - union lp_type src_type, - union lp_type dst_type) + struct lp_type src_type, + struct lp_type dst_type) { LLVMModuleRef module = NULL; LLVMValueRef func = NULL; @@ -343,35 +343,35 @@ test_one(unsigned verbose, } -const union lp_type conv_types[] = { +const struct lp_type conv_types[] = { /* float, fixed, sign, norm, width, len */ - {{ TRUE, FALSE, TRUE, TRUE, 32, 4 }}, - {{ TRUE, FALSE, TRUE, FALSE, 32, 4 }}, - {{ TRUE, FALSE, FALSE, TRUE, 32, 4 }}, - {{ TRUE, FALSE, FALSE, FALSE, 32, 4 }}, + { TRUE, FALSE, TRUE, TRUE, 32, 4 }, + { TRUE, FALSE, TRUE, FALSE, 32, 4 }, + { TRUE, FALSE, FALSE, TRUE, 32, 4 }, + { TRUE, FALSE, FALSE, FALSE, 32, 4 }, /* TODO: test fixed formats too */ - {{ FALSE, FALSE, TRUE, TRUE, 16, 8 }}, - {{ FALSE, FALSE, TRUE, FALSE, 16, 8 }}, - {{ FALSE, FALSE, FALSE, TRUE, 16, 8 }}, - {{ FALSE, FALSE, FALSE, FALSE, 16, 8 }}, - - {{ FALSE, FALSE, TRUE, TRUE, 32, 4 }}, - {{ FALSE, FALSE, TRUE, FALSE, 32, 4 }}, - {{ FALSE, FALSE, FALSE, TRUE, 32, 4 }}, - {{ FALSE, FALSE, FALSE, FALSE, 32, 4 }}, - - {{ FALSE, FALSE, TRUE, TRUE, 16, 8 }}, - {{ FALSE, FALSE, TRUE, FALSE, 16, 8 }}, - {{ FALSE, FALSE, FALSE, TRUE, 16, 8 }}, - {{ FALSE, FALSE, FALSE, FALSE, 16, 8 }}, - - {{ FALSE, FALSE, TRUE, TRUE, 8, 16 }}, - {{ FALSE, FALSE, TRUE, FALSE, 8, 16 }}, - {{ FALSE, FALSE, FALSE, TRUE, 8, 16 }}, - {{ FALSE, FALSE, FALSE, FALSE, 8, 16 }}, + { FALSE, FALSE, TRUE, TRUE, 16, 8 }, + { FALSE, FALSE, TRUE, FALSE, 16, 8 }, + { FALSE, FALSE, FALSE, TRUE, 16, 8 }, + { FALSE, FALSE, FALSE, FALSE, 16, 8 }, + + { FALSE, FALSE, TRUE, TRUE, 32, 4 }, + { FALSE, FALSE, TRUE, FALSE, 32, 4 }, + { FALSE, FALSE, FALSE, TRUE, 32, 4 }, + { FALSE, FALSE, FALSE, FALSE, 32, 4 }, + + { FALSE, FALSE, TRUE, TRUE, 16, 8 }, + { FALSE, FALSE, TRUE, FALSE, 16, 8 }, + { FALSE, FALSE, FALSE, TRUE, 16, 8 }, + { FALSE, FALSE, FALSE, FALSE, 16, 8 }, + + { FALSE, FALSE, TRUE, TRUE, 8, 16 }, + { FALSE, FALSE, TRUE, FALSE, 8, 16 }, + { FALSE, FALSE, FALSE, TRUE, 8, 16 }, + { FALSE, FALSE, FALSE, FALSE, 8, 16 }, }; @@ -381,8 +381,8 @@ const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]); boolean test_all(unsigned verbose, FILE *fp) { - const union lp_type *src_type; - const union lp_type *dst_type; + const struct lp_type *src_type; + const struct lp_type *dst_type; bool success = TRUE; for(src_type = conv_types; src_type < &conv_types[num_types]; ++src_type) { @@ -407,16 +407,16 @@ test_all(unsigned verbose, FILE *fp) boolean test_some(unsigned verbose, FILE *fp, unsigned long n) { - const union lp_type *src_type; - const union lp_type *dst_type; + const struct lp_type *src_type; + const struct lp_type *dst_type; unsigned long i; bool success = TRUE; for(i = 0; i < n; ++i) { - src_type = &conv_types[random() % num_types]; + src_type = &conv_types[rand() % num_types]; do { - dst_type = &conv_types[random() % num_types]; + dst_type = &conv_types[rand() % num_types]; } while (src_type == dst_type || src_type->norm != dst_type->norm); if(!test_one(verbose, fp, *src_type, *dst_type)) diff --git a/src/gallium/drivers/llvmpipe/lp_test_main.c b/src/gallium/drivers/llvmpipe/lp_test_main.c index 49213fb4f0b..4592dc0b2d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_main.c +++ b/src/gallium/drivers/llvmpipe/lp_test_main.c @@ -40,7 +40,7 @@ void dump_type(FILE *fp, - union lp_type type) + struct lp_type type) { fprintf(fp, "%s%s%u%sx%u", type.sign ? (type.floating || type.fixed ? "" : "s") : "u", @@ -52,7 +52,7 @@ dump_type(FILE *fp, double -read_elem(union lp_type type, const void *src, unsigned index) +read_elem(struct lp_type type, const void *src, unsigned index) { double scale = lp_const_scale(type); double value; @@ -115,7 +115,7 @@ read_elem(union lp_type type, const void *src, unsigned index) void -write_elem(union lp_type type, void *dst, unsigned index, double value) +write_elem(struct lp_type type, void *dst, unsigned index, double value) { assert(index < type.length); if(!type.sign && value < 0.0) @@ -184,11 +184,11 @@ write_elem(union lp_type type, void *dst, unsigned index, double value) void -random_elem(union lp_type type, void *dst, unsigned index) +random_elem(struct lp_type type, void *dst, unsigned index) { double value; assert(index < type.length); - value = (double)random()/(double)RAND_MAX; + value = (double)rand()/(double)RAND_MAX; if(!type.norm) { unsigned long long mask; if (type.floating) @@ -199,17 +199,17 @@ random_elem(union lp_type type, void *dst, unsigned index) mask = ((unsigned long long)1 << (type.width - 1)) - 1; else mask = ((unsigned long long)1 << type.width) - 1; - value += (double)(mask & random()); + value += (double)(mask & rand()); } if(!type.sign) - if(random() & 1) + if(rand() & 1) value = -value; write_elem(type, dst, index, value); } void -read_vec(union lp_type type, const void *src, double *dst) +read_vec(struct lp_type type, const void *src, double *dst) { unsigned i; for (i = 0; i < type.length; ++i) @@ -218,7 +218,7 @@ read_vec(union lp_type type, const void *src, double *dst) void -write_vec(union lp_type type, void *dst, const double *src) +write_vec(struct lp_type type, void *dst, const double *src) { unsigned i; for (i = 0; i < type.length; ++i) @@ -229,12 +229,12 @@ write_vec(union lp_type type, void *dst, const double *src) float random_float(void) { - return (float)((double)random()/(double)RAND_MAX); + return (float)((double)rand()/(double)RAND_MAX); } void -random_vec(union lp_type type, void *dst) +random_vec(struct lp_type type, void *dst) { unsigned i; for (i = 0; i < type.length; ++i) @@ -243,7 +243,7 @@ random_vec(union lp_type type, void *dst) boolean -compare_vec_with_eps(union lp_type type, const void *res, const void *ref, double eps) +compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps) { unsigned i; for (i = 0; i < type.length; ++i) { @@ -259,7 +259,7 @@ compare_vec_with_eps(union lp_type type, const void *res, const void *ref, doubl boolean -compare_vec(union lp_type type, const void *res, const void *ref) +compare_vec(struct lp_type type, const void *res, const void *ref) { double eps = lp_const_eps(type); return compare_vec_with_eps(type, res, ref, eps); @@ -267,7 +267,7 @@ compare_vec(union lp_type type, const void *res, const void *ref) void -dump_vec(FILE *fp, union lp_type type, const void *src) +dump_vec(FILE *fp, struct lp_type type, const void *src) { unsigned i; for (i = 0; i < type.length; ++i) { diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c index 9a876f404df..a1365a045f1 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c @@ -1654,7 +1654,7 @@ lp_c_sampler_soa_destroy(struct lp_build_sampler_soa *sampler) static void lp_c_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *_sampler, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c index 7d31705d014..d2a6ae21f57 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c @@ -149,7 +149,7 @@ lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler) static void lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, LLVMBuilderRef builder, - union lp_type type, + struct lp_type type, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c index ff2febb668e..170ce3eb7e5 100644 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -16,8 +16,6 @@ nv04_screen_get_param(struct pipe_screen *screen, int param) return 0; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 4469b22d91a..ee5901e743e 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -15,8 +15,6 @@ nv10_screen_get_param(struct pipe_screen *screen, int param) return 0; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c index e6924ad71eb..4eeacd1afd5 100644 --- a/src/gallium/drivers/nv20/nv20_screen.c +++ b/src/gallium/drivers/nv20/nv20_screen.c @@ -15,8 +15,6 @@ nv20_screen_get_param(struct pipe_screen *screen, int param) return 0; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index f8285e4455f..41af38450b5 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -22,8 +22,6 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 5d2a4216c5a..bd13dfddd1c 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -21,8 +21,6 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 1; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 6e8f4f9750d..fca078b174a 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -37,11 +37,12 @@ nv50_flush(struct pipe_context *pipe, unsigned flags, /* We need this in the ddx for reliable composite, not sure what we're * actually flushing. We generate all our own flushes with flags = 0. */ - WAIT_RING(chan, 3); + WAIT_RING(chan, 2); BEGIN_RING(chan, eng2d, 0x0110, 1); OUT_RING (chan, 0); - FIRE_RING(chan); + if (flags & PIPE_FLUSH_FRAME) + FIRE_RING(chan); } static void @@ -110,6 +111,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) nv50->pipe.is_texture_referenced = nv50_is_texture_referenced; nv50->pipe.is_buffer_referenced = nv50_is_buffer_referenced; + screen->base.channel->user_private = nv50; + screen->base.channel->flush_notify = nv50_state_flush_notify; + nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); nv50_init_query_functions(nv50); diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 1e9e8e49bfb..4608854d711 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -116,6 +116,7 @@ struct nv50_state { unsigned miptree_nr; struct nouveau_stateobj *vertprog; struct nouveau_stateobj *fragprog; + struct nouveau_stateobj *programs; struct nouveau_stateobj *vtxfmt; struct nouveau_stateobj *vtxbuf; struct nouveau_stateobj *vtxattr; @@ -190,10 +191,12 @@ extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, /* nv50_program.c */ extern void nv50_vertprog_validate(struct nv50_context *nv50); extern void nv50_fragprog_validate(struct nv50_context *nv50); +extern void nv50_linkage_validate(struct nv50_context *nv50); extern void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p); /* nv50_state_validate.c */ extern boolean nv50_state_validate(struct nv50_context *nv50); +extern void nv50_state_flush_notify(struct nouveau_channel *chan); /* nv50_tex.c */ extern void nv50_tex_validate(struct nv50_context *); diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 4a838529de7..eb90d5e66f9 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -112,6 +112,10 @@ struct nv50_pc { struct nv50_reg *temp_temp[16]; unsigned temp_temp_nr; + /* broadcast and destination replacement regs */ + struct nv50_reg *r_brdc; + struct nv50_reg *r_dst[4]; + unsigned interp_mode[32]; /* perspective interpolation registers */ struct nv50_reg *iv_p; @@ -124,6 +128,25 @@ struct nv50_pc { boolean allow32; }; +static INLINE void +ctor_reg(struct nv50_reg *reg, unsigned type, int index, int hw) +{ + reg->type = type; + reg->index = index; + reg->hw = hw; + reg->neg = 0; + reg->rhw = -1; + reg->acc = 0; +} + +static INLINE unsigned +popcnt4(uint32_t val) +{ + static const unsigned cnt[16] + = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return cnt[val & 0xf]; +} + static void alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg) { @@ -184,11 +207,8 @@ alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst) for (i = 0; i < NV50_SU_MAX_TEMP; i++) { if (!pc->r_temp[i]) { - r = CALLOC_STRUCT(nv50_reg); - r->type = P_TEMP; - r->index = -1; - r->hw = i; - r->rhw = -1; + r = MALLOC_STRUCT(nv50_reg); + ctor_reg(r, P_TEMP, -1, i); pc->r_temp[i] = r; return r; } @@ -254,10 +274,8 @@ alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx) return alloc_temp4(pc, dst, idx + 4); for (i = 0; i < 4; i++) { - dst[i] = CALLOC_STRUCT(nv50_reg); - dst[i]->type = P_TEMP; - dst[i]->index = -1; - dst[i]->hw = idx + i; + dst[i] = MALLOC_STRUCT(nv50_reg); + ctor_reg(dst[i], P_TEMP, -1, idx + i); pc->r_temp[idx + i] = dst[i]; } @@ -309,7 +327,7 @@ ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w) static struct nv50_reg * alloc_immd(struct nv50_pc *pc, float f) { - struct nv50_reg *r = CALLOC_STRUCT(nv50_reg); + struct nv50_reg *r = MALLOC_STRUCT(nv50_reg); unsigned hw; for (hw = 0; hw < pc->immd_nr * 4; hw++) @@ -319,9 +337,7 @@ alloc_immd(struct nv50_pc *pc, float f) if (hw == pc->immd_nr * 4) hw = ctor_immd(pc, f, -f, 0.5 * f, 0) * 4; - r->type = P_IMMD; - r->hw = hw; - r->index = -1; + ctor_reg(r, P_IMMD, -1, hw); return r; } @@ -786,6 +802,9 @@ emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) #define CVTOP_SAT 0x08 #define CVTOP_ABS 0x10 +/* 0x04 == 32 bit */ +/* 0x40 == dst is float */ +/* 0x80 == src is float */ #define CVT_F32_F32 0xc4 #define CVT_F32_S32 0x44 #define CVT_F32_U32 0x64 @@ -795,7 +814,7 @@ emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) static void emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, - int wp, unsigned cop, unsigned fmt) + int wp, unsigned cvn, unsigned fmt) { struct nv50_program_exec *e; @@ -804,7 +823,7 @@ emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, e->inst[0] |= 0xa0000000; e->inst[1] |= 0x00004000; - e->inst[1] |= (cop << 16); + e->inst[1] |= (cvn << 16); e->inst[1] |= (fmt << 24); set_src_0(pc, src, e); @@ -821,49 +840,80 @@ emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, emit(pc, e); } +/* nv50 Condition codes: + * 0x1 = LT + * 0x2 = EQ + * 0x3 = LE + * 0x4 = GT + * 0x5 = NE + * 0x6 = GE + * 0x7 = set condition code ? (used before bra.lt/le/gt/ge) + * 0x8 = unordered bit (allows NaN) + */ static void -emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, +emit_set(struct nv50_pc *pc, unsigned ccode, struct nv50_reg *dst, int wp, struct nv50_reg *src0, struct nv50_reg *src1) { + static const unsigned cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + struct nv50_program_exec *e = exec(pc); - unsigned inv_cop[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; struct nv50_reg *rdst; - assert(c_op <= 7); + assert(ccode < 16); if (check_swap_src_0_1(pc, &src0, &src1)) - c_op = inv_cop[c_op]; + ccode = cc_swapped[ccode & 7] | (ccode & 8); rdst = dst; - if (dst->type != P_TEMP) + if (dst && dst->type != P_TEMP) dst = alloc_temp(pc, NULL); /* set.u32 */ set_long(pc, e); e->inst[0] |= 0xb0000000; - e->inst[1] |= (3 << 29); - e->inst[1] |= (c_op << 14); - /*XXX: breaks things, .u32 by default? - * decuda will disasm as .u16 and use .lo/.hi regs, but this - * doesn't seem to match what the hw actually does. - inst[1] |= 0x04000000; << breaks things.. .u32 by default? + e->inst[1] |= 0x60000000 | (ccode << 14); + + /* XXX: decuda will disasm as .u16 and use .lo/.hi regs, but + * that doesn't seem to match what the hw actually does + e->inst[1] |= 0x04000000; << breaks things, u32 by default ? */ - set_dst(pc, dst, e); + + if (wp >= 0) + set_pred_wr(pc, 1, wp, e); + if (dst) + set_dst(pc, dst, e); + else { + e->inst[0] |= 0x000001fc; + e->inst[1] |= 0x00000008; + } + set_src_0(pc, src0, e); set_src_1(pc, src1, e); - emit(pc, e); - /* cvt.f32.u32 */ - e = exec(pc); - e->inst[0] = 0xa0000001; - e->inst[1] = 0x64014780; - set_dst(pc, rdst, e); - set_src_0(pc, dst, e); emit(pc, e); - if (dst != rdst) + /* cvt.f32.u32/s32 (?) if we didn't only write the predicate */ + if (rdst) + emit_cvt(pc, rdst, dst, -1, CVTOP_ABS | CVTOP_RN, CVT_F32_S32); + if (rdst && rdst != dst) free_temp(pc, dst); } +static INLINE unsigned +map_tgsi_setop_cc(unsigned op) +{ + switch (op) { + case TGSI_OPCODE_SLT: return 0x1; + case TGSI_OPCODE_SGE: return 0x6; + case TGSI_OPCODE_SEQ: return 0x2; + case TGSI_OPCODE_SGT: return 0x4; + case TGSI_OPCODE_SLE: return 0x3; + case TGSI_OPCODE_SNE: return 0xd; + default: + assert(0); + return 0; + } +} + static INLINE void emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { @@ -890,6 +940,12 @@ emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit_cvt(pc, dst, src, -1, CVTOP_ABS, CVT_F32_F32); } +static INLINE void +emit_sat(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + emit_cvt(pc, dst, src, -1, CVTOP_SAT, CVT_F32_F32); +} + static void emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, struct nv50_reg **src) @@ -1159,6 +1215,70 @@ negate_supported(const struct tgsi_full_instruction *insn, int i) } } +/* Return a read mask for source registers deduced from opcode & write mask. */ +static unsigned +nv50_tgsi_src_mask(const struct tgsi_full_instruction *insn, int c) +{ + unsigned x, mask = insn->FullDstRegisters[0].DstRegister.WriteMask; + + switch (insn->Instruction.Opcode) { + case TGSI_OPCODE_COS: + case TGSI_OPCODE_SIN: + return (mask & 0x8) | ((mask & 0x7) ? 0x1 : 0x0); + case TGSI_OPCODE_DP3: + return 0x7; + case TGSI_OPCODE_DP4: + case TGSI_OPCODE_DPH: + case TGSI_OPCODE_KIL: /* WriteMask ignored */ + return 0xf; + case TGSI_OPCODE_DST: + return mask & (c ? 0xa : 0x6); + case TGSI_OPCODE_EX2: + case TGSI_OPCODE_LG2: + case TGSI_OPCODE_POW: + case TGSI_OPCODE_RCP: + case TGSI_OPCODE_RSQ: + case TGSI_OPCODE_SCS: + return 0x1; + case TGSI_OPCODE_LIT: + return 0xb; + case TGSI_OPCODE_TEX: + case TGSI_OPCODE_TXP: + { + const struct tgsi_instruction_ext_texture *tex; + + assert(insn->Instruction.Extended); + tex = &insn->InstructionExtTexture; + + mask = 0x7; + if (insn->Instruction.Opcode == TGSI_OPCODE_TXP) + mask |= 0x8; + + switch (tex->Texture) { + case TGSI_TEXTURE_1D: + mask &= 0x9; + break; + case TGSI_TEXTURE_2D: + mask &= 0xb; + break; + default: + break; + } + } + return mask; + case TGSI_OPCODE_XPD: + x = 0; + if (mask & 1) x |= 0x6; + if (mask & 2) x |= 0x5; + if (mask & 4) x |= 0x3; + return x; + default: + break; + } + + return mask; +} + static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -1258,93 +1378,126 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src, return r; } -/* returns TRUE if instruction can overwrite sources before they're read */ +/* return TRUE for ops that produce only a single result */ static boolean -direct2dest_op(const struct tgsi_full_instruction *insn) +is_scalar_op(unsigned op) { - if (insn->Instruction.Saturate) - return FALSE; - - switch (insn->Instruction.Opcode) { + switch (op) { case TGSI_OPCODE_COS: + case TGSI_OPCODE_DP2: case TGSI_OPCODE_DP3: case TGSI_OPCODE_DP4: case TGSI_OPCODE_DPH: - case TGSI_OPCODE_KIL: - case TGSI_OPCODE_LIT: + case TGSI_OPCODE_EX2: + case TGSI_OPCODE_LG2: case TGSI_OPCODE_POW: case TGSI_OPCODE_RCP: case TGSI_OPCODE_RSQ: - case TGSI_OPCODE_SCS: case TGSI_OPCODE_SIN: + /* + case TGSI_OPCODE_KIL: + case TGSI_OPCODE_LIT: + case TGSI_OPCODE_SCS: + */ + return TRUE; + default: + return FALSE; + } +} + +/* Returns a bitmask indicating which dst components depend + * on source s, component c (reverse of nv50_tgsi_src_mask). + */ +static unsigned +nv50_tgsi_dst_revdep(unsigned op, int s, int c) +{ + if (is_scalar_op(op)) + return 0x1; + + switch (op) { + case TGSI_OPCODE_DST: + return (1 << c) & (s ? 0xa : 0x6); + case TGSI_OPCODE_XPD: + switch (c) { + case 0: return 0x6; + case 1: return 0x5; + case 2: return 0x3; + case 3: return 0x0; + default: + assert(0); + return 0x0; + } + case TGSI_OPCODE_LIT: + case TGSI_OPCODE_SCS: case TGSI_OPCODE_TEX: case TGSI_OPCODE_TXP: - return FALSE; + /* these take care of dangerous swizzles themselves */ + return 0x0; + case TGSI_OPCODE_IF: + case TGSI_OPCODE_KIL: + /* don't call this function for these ops */ + assert(0); + return 0; default: - return TRUE; + /* linear vector instruction */ + return (1 << c); } } static boolean -nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) +nv50_program_tx_insn(struct nv50_pc *pc, + const struct tgsi_full_instruction *inst) { - const struct tgsi_full_instruction *inst = &tok->FullInstruction; - struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp; + struct nv50_reg *rdst[4], *dst[4], *brdc, *src[3][4], *temp; unsigned mask, sat, unit; - boolean assimilate = FALSE; int i, c; mask = inst->FullDstRegisters[0].DstRegister.WriteMask; sat = inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE; + memset(src, 0, sizeof(src)); + for (c = 0; c < 4; c++) { - if (mask & (1 << c)) + if ((mask & (1 << c)) && !pc->r_dst[c]) dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]); else - dst[c] = NULL; - rdst[c] = NULL; - src[0][c] = NULL; - src[1][c] = NULL; - src[2][c] = NULL; + dst[c] = pc->r_dst[c]; + rdst[c] = dst[c]; } for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *fs = &inst->FullSrcRegisters[i]; + unsigned src_mask; + boolean neg_supp; + + src_mask = nv50_tgsi_src_mask(inst, i); + neg_supp = negate_supported(inst, i); if (fs->SrcRegister.File == TGSI_FILE_SAMPLER) unit = fs->SrcRegister.Index; for (c = 0; c < 4; c++) - src[i][c] = tgsi_src(pc, c, fs, - negate_supported(inst, i)); + if (src_mask & (1 << c)) + src[i][c] = tgsi_src(pc, c, fs, neg_supp); } - if (sat) { - for (c = 0; c < 4; c++) { - rdst[c] = dst[c]; - dst[c] = temp_temp(pc); - } + brdc = temp = pc->r_brdc; + if (brdc && brdc->type != P_TEMP) { + temp = temp_temp(pc); + if (sat) + brdc = temp; } else - if (direct2dest_op(inst)) { + if (sat) { for (c = 0; c < 4; c++) { - if (!dst[c] || dst[c]->type != P_TEMP) + if (!(mask & (1 << c)) || dst[c]->type == P_TEMP) continue; - - for (i = c + 1; i < 4; i++) { - if (dst[c] == src[0][i] || - dst[c] == src[1][i] || - dst[c] == src[2][i]) - break; - } - if (i == 4) - continue; - - assimilate = TRUE; rdst[c] = dst[c]; - dst[c] = alloc_temp(pc, NULL); + dst[c] = temp_temp(pc); } } + assert(brdc || !is_scalar_op(inst->Instruction.Opcode)); + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ABS: for (c = 0; c < 4; c++) { @@ -1360,74 +1513,56 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_add(pc, dst[c], src[0][c], src[1][c]); } break; - case TGSI_OPCODE_COS: - temp = temp_temp(pc); - emit_precossin(pc, temp, src[0][0]); - emit_flop(pc, 5, temp, temp); + case TGSI_OPCODE_CEIL: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_mov(pc, dst[c], temp); + emit_cvt(pc, dst[c], src[0][c], -1, + CVTOP_CEIL, CVT_F32_F32); + } + break; + case TGSI_OPCODE_COS: + if (mask & 8) { + emit_precossin(pc, temp, src[0][3]); + emit_flop(pc, 5, dst[3], temp); + if (!(mask &= 7)) + break; + if (temp == dst[3]) + temp = brdc = temp_temp(pc); } + emit_precossin(pc, temp, src[0][0]); + emit_flop(pc, 5, brdc, temp); break; case TGSI_OPCODE_DP3: - temp = temp_temp(pc); emit_mul(pc, temp, src[0][0], src[1][0]); emit_mad(pc, temp, src[0][1], src[1][1], temp); - emit_mad(pc, temp, src[0][2], src[1][2], temp); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); - } + emit_mad(pc, brdc, src[0][2], src[1][2], temp); break; case TGSI_OPCODE_DP4: - temp = temp_temp(pc); emit_mul(pc, temp, src[0][0], src[1][0]); emit_mad(pc, temp, src[0][1], src[1][1], temp); emit_mad(pc, temp, src[0][2], src[1][2], temp); - emit_mad(pc, temp, src[0][3], src[1][3], temp); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); - } + emit_mad(pc, brdc, src[0][3], src[1][3], temp); break; case TGSI_OPCODE_DPH: - temp = temp_temp(pc); emit_mul(pc, temp, src[0][0], src[1][0]); emit_mad(pc, temp, src[0][1], src[1][1], temp); emit_mad(pc, temp, src[0][2], src[1][2], temp); - emit_add(pc, temp, src[1][3], temp); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); - } + emit_add(pc, brdc, src[1][3], temp); break; case TGSI_OPCODE_DST: - { - struct nv50_reg *one = alloc_immd(pc, 1.0); - if (mask & (1 << 0)) - emit_mov(pc, dst[0], one); if (mask & (1 << 1)) emit_mul(pc, dst[1], src[0][1], src[1][1]); if (mask & (1 << 2)) emit_mov(pc, dst[2], src[0][2]); if (mask & (1 << 3)) emit_mov(pc, dst[3], src[1][3]); - FREE(one); - } + if (mask & (1 << 0)) + emit_mov_immdval(pc, dst[0], 1.0f); break; case TGSI_OPCODE_EX2: - temp = temp_temp(pc); emit_preex2(pc, temp, src[0][0]); - emit_flop(pc, 6, temp, temp); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); - } + emit_flop(pc, 6, brdc, temp); break; case TGSI_OPCODE_FLR: for (c = 0; c < 4; c++) { @@ -1450,19 +1585,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_kil(pc, src[0][1]); emit_kil(pc, src[0][2]); emit_kil(pc, src[0][3]); - pc->p->cfg.fp.regs[2] |= 0x00100000; break; case TGSI_OPCODE_LIT: emit_lit(pc, &dst[0], mask, &src[0][0]); break; case TGSI_OPCODE_LG2: - temp = temp_temp(pc); - emit_flop(pc, 3, temp, src[0][0]); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); - } + emit_flop(pc, 3, brdc, src[0][0]); break; case TGSI_OPCODE_LRP: temp = temp_temp(pc); @@ -1510,31 +1638,18 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } break; case TGSI_OPCODE_POW: - temp = temp_temp(pc); - emit_pow(pc, temp, src[0][0], src[1][0]); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); - } + emit_pow(pc, brdc, src[0][0], src[1][0]); break; case TGSI_OPCODE_RCP: - for (c = 3; c >= 0; c--) { - if (!(mask & (1 << c))) - continue; - emit_flop(pc, 0, dst[c], src[0][0]); - } + emit_flop(pc, 0, brdc, src[0][0]); break; case TGSI_OPCODE_RSQ: - for (c = 3; c >= 0; c--) { - if (!(mask & (1 << c))) - continue; - emit_flop(pc, 2, dst[c], src[0][0]); - } + emit_flop(pc, 2, brdc, src[0][0]); break; case TGSI_OPCODE_SCS: temp = temp_temp(pc); - emit_precossin(pc, temp, src[0][0]); + if (mask & 3) + emit_precossin(pc, temp, src[0][0]); if (mask & (1 << 0)) emit_flop(pc, 5, dst[0], temp); if (mask & (1 << 1)) @@ -1544,28 +1659,29 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) if (mask & (1 << 3)) emit_mov_immdval(pc, dst[3], 1.0); break; - case TGSI_OPCODE_SGE: - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_set(pc, 6, dst[c], src[0][c], src[1][c]); - } - break; case TGSI_OPCODE_SIN: - temp = temp_temp(pc); - emit_precossin(pc, temp, src[0][0]); - emit_flop(pc, 4, temp, temp); - for (c = 0; c < 4; c++) { - if (!(mask & (1 << c))) - continue; - emit_mov(pc, dst[c], temp); + if (mask & 8) { + emit_precossin(pc, temp, src[0][3]); + emit_flop(pc, 4, dst[3], temp); + if (!(mask &= 7)) + break; + if (temp == dst[3]) + temp = brdc = temp_temp(pc); } + emit_precossin(pc, temp, src[0][0]); + emit_flop(pc, 4, brdc, temp); break; case TGSI_OPCODE_SLT: + case TGSI_OPCODE_SGE: + case TGSI_OPCODE_SEQ: + case TGSI_OPCODE_SGT: + case TGSI_OPCODE_SLE: + case TGSI_OPCODE_SNE: + i = map_tgsi_setop_cc(inst->Instruction.Opcode); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_set(pc, 1, dst[c], src[0][c], src[1][c]); + emit_set(pc, i, dst[c], -1, src[0][c], src[1][c]); } break; case TGSI_OPCODE_SUB: @@ -1583,6 +1699,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_tex(pc, dst, mask, src[0], unit, inst->InstructionExtTexture.Texture, TRUE); break; + case TGSI_OPCODE_TRUNC: + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_cvt(pc, dst[c], src[0][c], -1, + CVTOP_TRUNC, CVT_F32_F32); + } + break; case TGSI_OPCODE_XPD: temp = temp_temp(pc); if (mask & (1 << 0)) { @@ -1607,17 +1731,22 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) return FALSE; } + if (brdc) { + if (sat) + emit_sat(pc, brdc, brdc); + for (c = 0; c < 4; c++) + if ((mask & (1 << c)) && dst[c] != brdc) + emit_mov(pc, dst[c], brdc); + } else if (sat) { for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_cvt(pc, rdst[c], dst[c], -1, CVTOP_SAT, - CVT_F32_F32); + /* in this case we saturate later */ + if (dst[c]->type == P_TEMP && dst[c]->index < 0) + continue; + emit_sat(pc, rdst[c], dst[c]); } - } else if (assimilate) { - for (c = 0; c < 4; c++) - if (rdst[c]) - assimilate_temp(pc, rdst[c], dst[c]); } for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { @@ -1626,9 +1755,6 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) continue; if (src[i][c]->index == -1 && src[i][c]->type == P_IMMD) FREE(src[i][c]); - else - if (src[i][c]->acc == pc->insn_cur) - release_hw(pc, src[i][c]); } } @@ -1636,180 +1762,271 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) return TRUE; } -/* Adjust a bitmask that indicates what components of a source are used, - * we use this in tx_prep so we only load interpolants that are needed. - */ static void -insn_adjust_mask(const struct tgsi_full_instruction *insn, unsigned *mask) +prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn) { - const struct tgsi_instruction_ext_texture *tex; - - switch (insn->Instruction.Opcode) { - case TGSI_OPCODE_DP3: - *mask = 0x7; - break; - case TGSI_OPCODE_DP4: - case TGSI_OPCODE_DPH: - *mask = 0xF; - break; - case TGSI_OPCODE_LIT: - *mask = 0xB; - break; - case TGSI_OPCODE_RCP: - case TGSI_OPCODE_RSQ: - *mask = 0x1; - break; - case TGSI_OPCODE_TEX: - case TGSI_OPCODE_TXP: - assert(insn->Instruction.Extended); - tex = &insn->InstructionExtTexture; - - *mask = 0x7; - if (tex->Texture == TGSI_TEXTURE_1D) - *mask = 0x1; - else - if (tex->Texture == TGSI_TEXTURE_2D) - *mask = 0x3; - - if (insn->Instruction.Opcode == TGSI_OPCODE_TXP) - *mask |= 0x8; - break; - default: - break; - } -} - -static void -prep_inspect_insn(struct nv50_pc *pc, const union tgsi_full_token *tok, - unsigned *r_usage[2]) -{ - const struct tgsi_full_instruction *insn; + struct nv50_reg *reg = NULL; const struct tgsi_full_src_register *src; const struct tgsi_dst_register *dst; + unsigned i, c, k, mask; - unsigned i, c, k, n, mask, *acc_p; - - insn = &tok->FullInstruction; dst = &insn->FullDstRegisters[0].DstRegister; mask = dst->WriteMask; - if (!r_usage[0]) - r_usage[0] = CALLOC(pc->temp_nr * 4, sizeof(unsigned)); - if (!r_usage[1]) - r_usage[1] = CALLOC(pc->attr_nr * 4, sizeof(unsigned)); + if (dst->File == TGSI_FILE_TEMPORARY) + reg = pc->temp; + else + if (dst->File == TGSI_FILE_OUTPUT) + reg = pc->result; - if (dst->File == TGSI_FILE_TEMPORARY) { + if (reg) { for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - r_usage[0][dst->Index * 4 + c] = pc->insn_nr; + reg[dst->Index * 4 + c].acc = pc->insn_nr; } } for (i = 0; i < insn->Instruction.NumSrcRegs; i++) { src = &insn->FullSrcRegisters[i]; - switch (src->SrcRegister.File) { - case TGSI_FILE_TEMPORARY: - acc_p = r_usage[0]; - break; - case TGSI_FILE_INPUT: - acc_p = r_usage[1]; - break; - default: + if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) + reg = pc->temp; + else + if (src->SrcRegister.File == TGSI_FILE_INPUT) + reg = pc->attr; + else continue; - } - insn_adjust_mask(insn, &mask); + mask = nv50_tgsi_src_mask(insn, i); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - k = tgsi_util_get_full_src_register_extswizzle(src, c); - switch (k) { - case TGSI_EXTSWIZZLE_X: - case TGSI_EXTSWIZZLE_Y: - case TGSI_EXTSWIZZLE_Z: - case TGSI_EXTSWIZZLE_W: - n = src->SrcRegister.Index * 4 + k; - acc_p[n] = pc->insn_nr; - break; - default: - break; - } + + if (k > TGSI_EXTSWIZZLE_W) + continue; + + reg[src->SrcRegister.Index * 4 + k].acc = pc->insn_nr; } } } +/* Returns a bitmask indicating which dst components need to be + * written to temporaries first to avoid 'corrupting' sources. + * + * m[i] (out) indicate component to write in the i-th position + * rdep[c] (in) bitmasks of dst[i] that require dst[c] as source + */ static unsigned -load_fp_attrib(struct nv50_pc *pc, int i, unsigned *acc, int *mid, - int *aid, int *p_oid) +nv50_revdep_reorder(unsigned m[4], unsigned rdep[4]) { - struct nv50_reg *iv; - int oid, c, n; - unsigned mask = 0; + unsigned i, c, x, unsafe; - iv = (pc->interp_mode[i] & INTERP_CENTROID) ? pc->iv_c : pc->iv_p; + for (c = 0; c < 4; c++) + m[c] = c; - for (c = 0, n = i * 4; c < 4; c++, n++) { - oid = (*p_oid)++; - pc->attr[n].type = P_TEMP; - pc->attr[n].index = i; + /* Swap as long as a dst component written earlier is depended on + * by one written later, but the next one isn't depended on by it. + */ + for (c = 0; c < 3; c++) { + if (rdep[m[c + 1]] & (1 << m[c])) + continue; /* if next one is depended on by us */ + for (i = c + 1; i < 4; i++) + /* if we are depended on by a later one */ + if (rdep[m[c]] & (1 << m[i])) + break; + if (i == 4) + continue; + /* now, swap */ + x = m[c]; + m[c] = m[c + 1]; + m[c + 1] = x; + + /* restart */ + c = 0; + } + + /* mark dependencies that could not be resolved by reordering */ + for (i = 0; i < 3; ++i) + for (c = i + 1; c < 4; ++c) + if (rdep[m[i]] & (1 << m[c])) + unsafe |= (1 << i); + + /* NOTE: $unsafe is with respect to order, not component */ + return unsafe; +} - if (pc->attr[n].acc == acc[n]) +/* Select a suitable dst register for broadcasting scalar results, + * or return NULL if we have to allocate an extra TEMP. + * + * If e.g. only 1 component is written, we may also emit the final + * result to a write-only register. + */ +static struct nv50_reg * +tgsi_broadcast_dst(struct nv50_pc *pc, + const struct tgsi_full_dst_register *fd, unsigned mask) +{ + if (fd->DstRegister.File == TGSI_FILE_TEMPORARY) { + int c = ffs(~mask & fd->DstRegister.WriteMask); + if (c) + return tgsi_dst(pc, c - 1, fd); + } else { + int c = ffs(fd->DstRegister.WriteMask) - 1; + if ((1 << c) == fd->DstRegister.WriteMask) + return tgsi_dst(pc, c, fd); + } + + return NULL; +} + +/* Scan source swizzles and return a bitmask indicating dst regs that + * also occur among the src regs, and fill rdep for nv50_revdep_reoder. + */ +static unsigned +nv50_tgsi_scan_swizzle(const struct tgsi_full_instruction *insn, + unsigned rdep[4]) +{ + const struct tgsi_full_dst_register *fd = &insn->FullDstRegisters[0]; + const struct tgsi_full_src_register *fs; + unsigned i, deqs = 0; + + for (i = 0; i < 4; ++i) + rdep[i] = 0; + + for (i = 0; i < insn->Instruction.NumSrcRegs; i++) { + unsigned chn, mask = nv50_tgsi_src_mask(insn, i); + boolean neg_supp = negate_supported(insn, i); + + fs = &insn->FullSrcRegisters[i]; + if (fs->SrcRegister.File != fd->DstRegister.File || + fs->SrcRegister.Index != fd->DstRegister.Index) continue; - mask |= (1 << c); - pc->attr[n].acc = acc[n]; - pc->attr[n].rhw = pc->attr[n].hw = -1; - alloc_reg(pc, &pc->attr[n]); + for (chn = 0; chn < 4; ++chn) { + unsigned s, c; + + if (!(mask & (1 << chn))) /* src is not read */ + continue; + c = tgsi_util_get_full_src_register_extswizzle(fs, chn); + s = tgsi_util_get_full_src_register_sign_mode(fs, chn); - pc->attr[n].rhw = (*aid)++; - emit_interp(pc, &pc->attr[n], iv, pc->interp_mode[i]); + if (c > TGSI_EXTSWIZZLE_W || + !(fd->DstRegister.WriteMask & (1 << c))) + continue; - pc->p->cfg.fp.map[(*mid) / 4] |= oid << (8 * ((*mid) % 4)); - (*mid)++; - pc->p->cfg.fp.regs[1] += 0x00010001; + /* no danger if src is copied to TEMP first */ + if ((s != TGSI_UTIL_SIGN_KEEP) && + (s != TGSI_UTIL_SIGN_TOGGLE || !neg_supp)) + continue; + + rdep[c] |= nv50_tgsi_dst_revdep( + insn->Instruction.Opcode, i, chn); + deqs |= (1 << c); + } } - return mask; + return deqs; } static boolean -nv50_program_tx_prep(struct nv50_pc *pc) +nv50_tgsi_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { - struct tgsi_parse_context p; - boolean ret = FALSE; - unsigned i, c; - unsigned fcol, bcol, fcrd, depr; + struct tgsi_full_instruction insn = tok->FullInstruction; + const struct tgsi_full_dst_register *fd; + unsigned i, deqs, rdep[4], m[4]; + + fd = &tok->FullInstruction.FullDstRegisters[0]; + deqs = nv50_tgsi_scan_swizzle(&insn, rdep); + + if (is_scalar_op(insn.Instruction.Opcode)) { + pc->r_brdc = tgsi_broadcast_dst(pc, fd, deqs); + if (!pc->r_brdc) + pc->r_brdc = temp_temp(pc); + return nv50_program_tx_insn(pc, &insn); + } + pc->r_brdc = NULL; + + if (!deqs) + return nv50_program_tx_insn(pc, &insn); + + deqs = nv50_revdep_reorder(m, rdep); - /* count (centroid) perspective interpolations */ - unsigned centroid_loads = 0; - unsigned perspect_loads = 0; + for (i = 0; i < 4; ++i) { + assert(pc->r_dst[m[i]] == NULL); - /* track register access for temps and attrs */ - unsigned *r_usage[2]; - r_usage[0] = NULL; - r_usage[1] = NULL; + insn.FullDstRegisters[0].DstRegister.WriteMask = + fd->DstRegister.WriteMask & (1 << m[i]); - depr = fcol = bcol = fcrd = 0xffff; + if (!insn.FullDstRegisters[0].DstRegister.WriteMask) + continue; + + if (deqs & (1 << i)) + pc->r_dst[m[i]] = alloc_temp(pc, NULL); - if (pc->p->type == PIPE_SHADER_FRAGMENT) { - pc->p->cfg.fp.regs[0] = 0x01000404; - pc->p->cfg.fp.regs[1] = 0x00000400; + if (!nv50_program_tx_insn(pc, &insn)) + return FALSE; } - tgsi_parse_init(&p, pc->p->pipe.tokens); - while (!tgsi_parse_end_of_tokens(&p)) { - const union tgsi_full_token *tok = &p.FullToken; + for (i = 0; i < 4; i++) { + struct nv50_reg *reg = pc->r_dst[i]; + if (!reg) + continue; + pc->r_dst[i] = NULL; + + if (insn.Instruction.Saturate == TGSI_SAT_ZERO_ONE) + emit_sat(pc, tgsi_dst(pc, i, fd), reg); + else + emit_mov(pc, tgsi_dst(pc, i, fd), reg); + free_temp(pc, reg); + } - tgsi_parse_token(&p); + return TRUE; +} + +static void +load_interpolant(struct nv50_pc *pc, struct nv50_reg *reg) +{ + struct nv50_reg *iv, **ppiv; + unsigned mode = pc->interp_mode[reg->index]; + + ppiv = (mode & INTERP_CENTROID) ? &pc->iv_c : &pc->iv_p; + iv = *ppiv; + + if ((mode & INTERP_PERSPECTIVE) && !iv) { + iv = *ppiv = alloc_temp(pc, NULL); + iv->rhw = popcnt4(pc->p->cfg.regs[1] >> 24) - 1; + + emit_interp(pc, iv, NULL, mode & INTERP_CENTROID); + emit_flop(pc, 0, iv, iv); + + /* XXX: when loading interpolants dynamically, move these + * to the program head, or make sure it can't be skipped. + */ + } + + emit_interp(pc, reg, iv, mode); +} + +static boolean +nv50_program_tx_prep(struct nv50_pc *pc) +{ + struct tgsi_parse_context tp; + struct nv50_program *p = pc->p; + boolean ret = FALSE; + unsigned i, c, flat_nr = 0; + + tgsi_parse_init(&tp, pc->p->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&tp)) { + const union tgsi_full_token *tok = &tp.FullToken; + + tgsi_parse_token(&tp); switch (tok->Token.Type) { case TGSI_TOKEN_TYPE_IMMEDIATE: { const struct tgsi_full_immediate *imm = - &p.FullToken.FullImmediate; + &tp.FullToken.FullImmediate; ctor_immd(pc, imm->u[0].Float, imm->u[1].Float, @@ -1820,78 +2037,61 @@ nv50_program_tx_prep(struct nv50_pc *pc) case TGSI_TOKEN_TYPE_DECLARATION: { const struct tgsi_full_declaration *d; - unsigned last, first, mode; + unsigned si, last, first, mode; - d = &p.FullToken.FullDeclaration; + d = &tp.FullToken.FullDeclaration; first = d->DeclarationRange.First; last = d->DeclarationRange.Last; switch (d->Declaration.File) { case TGSI_FILE_TEMPORARY: - if (pc->temp_nr < (last + 1)) - pc->temp_nr = last + 1; break; case TGSI_FILE_OUTPUT: - if (pc->result_nr < (last + 1)) - pc->result_nr = last + 1; - - if (!d->Declaration.Semantic) + if (!d->Declaration.Semantic || + p->type == PIPE_SHADER_FRAGMENT) break; + si = d->Semantic.SemanticIndex; switch (d->Semantic.SemanticName) { - case TGSI_SEMANTIC_POSITION: - depr = first; - pc->p->cfg.fp.regs[2] |= 0x00000100; - pc->p->cfg.fp.regs[3] |= 0x00000011; + case TGSI_SEMANTIC_BCOLOR: + p->cfg.two_side[si].hw = first; + if (p->cfg.io_nr > first) + p->cfg.io_nr = first; + break; + case TGSI_SEMANTIC_PSIZE: + p->cfg.psiz = first; + if (p->cfg.io_nr > first) + p->cfg.io_nr = first; + break; + /* + case TGSI_SEMANTIC_CLIP_DISTANCE: + p->cfg.clpd = MIN2(p->cfg.clpd, first); break; + */ default: break; } - break; case TGSI_FILE_INPUT: { - if (pc->attr_nr < (last + 1)) - pc->attr_nr = last + 1; - - if (pc->p->type != PIPE_SHADER_FRAGMENT) + if (p->type != PIPE_SHADER_FRAGMENT) break; switch (d->Declaration.Interpolate) { case TGSI_INTERPOLATE_CONSTANT: mode = INTERP_FLAT; + flat_nr++; break; case TGSI_INTERPOLATE_PERSPECTIVE: mode = INTERP_PERSPECTIVE; + p->cfg.regs[1] |= 0x08 << 24; break; default: mode = INTERP_LINEAR; break; } - - if (d->Declaration.Semantic) { - switch (d->Semantic.SemanticName) { - case TGSI_SEMANTIC_POSITION: - fcrd = first; - break; - case TGSI_SEMANTIC_COLOR: - fcol = first; - mode = INTERP_PERSPECTIVE; - break; - case TGSI_SEMANTIC_BCOLOR: - bcol = first; - mode = INTERP_PERSPECTIVE; - break; - } - } - - if (d->Declaration.Centroid) { + if (d->Declaration.Centroid) mode |= INTERP_CENTROID; - if (mode & INTERP_PERSPECTIVE) - centroid_loads++; - } else - if (mode & INTERP_PERSPECTIVE) - perspect_loads++; assert(last < 32); for (i = first; i <= last; i++) @@ -1899,8 +2099,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) } break; case TGSI_FILE_CONSTANT: - if (pc->param_nr < (last + 1)) - pc->param_nr = last + 1; break; case TGSI_FILE_SAMPLER: break; @@ -1913,182 +2111,155 @@ nv50_program_tx_prep(struct nv50_pc *pc) break; case TGSI_TOKEN_TYPE_INSTRUCTION: pc->insn_nr++; - prep_inspect_insn(pc, tok, r_usage); + prep_inspect_insn(pc, &tok->FullInstruction); break; default: break; } } - if (pc->temp_nr) { - pc->temp = CALLOC(pc->temp_nr * 4, sizeof(struct nv50_reg)); - if (!pc->temp) - goto out_err; + if (p->type == PIPE_SHADER_VERTEX) { + int rid = 0; - for (i = 0; i < pc->temp_nr; i++) { - for (c = 0; c < 4; c++) { - pc->temp[i*4+c].type = P_TEMP; - pc->temp[i*4+c].hw = -1; - pc->temp[i*4+c].rhw = -1; - pc->temp[i*4+c].index = i; - pc->temp[i*4+c].acc = r_usage[0][i*4+c]; + for (i = 0; i < pc->attr_nr * 4; ++i) { + if (pc->attr[i].acc) { + pc->attr[i].hw = rid++; + p->cfg.attr[i / 32] |= 1 << (i % 32); } } - } - - if (pc->attr_nr) { - int oid = 4, mid = 4, aid = 0; - /* oid = VP output id - * aid = FP attribute/interpolant id - * mid = VP output mapping field ID - */ - pc->attr = CALLOC(pc->attr_nr * 4, sizeof(struct nv50_reg)); - if (!pc->attr) - goto out_err; + for (i = 0, rid = 0; i < pc->result_nr; ++i) { + p->cfg.io[i].hw = rid; + p->cfg.io[i].id_vp = i; - if (pc->p->type == PIPE_SHADER_FRAGMENT) { - /* position should be loaded first */ - if (fcrd != 0xffff) { - unsigned mask; - mid = 0; - mask = load_fp_attrib(pc, fcrd, r_usage[1], - &mid, &aid, &oid); - oid = 0; - pc->p->cfg.fp.regs[1] |= (mask << 24); - pc->p->cfg.fp.map[0] = 0x04040404 * fcrd; - } - pc->p->cfg.fp.map[0] += 0x03020100; - - /* should do MAD fcrd.xy, fcrd, SOME_CONST, fcrd */ - - if (perspect_loads) { - pc->iv_p = alloc_temp(pc, NULL); - - if (!(pc->p->cfg.fp.regs[1] & 0x08000000)) { - pc->p->cfg.fp.regs[1] |= 0x08000000; - pc->iv_p->rhw = aid++; - emit_interp(pc, pc->iv_p, NULL, - INTERP_LINEAR); - emit_flop(pc, 0, pc->iv_p, pc->iv_p); - } else { - pc->iv_p->rhw = aid - 1; - emit_flop(pc, 0, pc->iv_p, - &pc->attr[fcrd * 4 + 3]); - } + for (c = 0; c < 4; ++c) { + int n = i * 4 + c; + if (!pc->result[n].acc) + continue; + pc->result[n].hw = rid++; + p->cfg.io[i].mask |= 1 << c; } + } - if (centroid_loads) { - pc->iv_c = alloc_temp(pc, NULL); - pc->iv_c->rhw = pc->iv_p ? aid - 1 : aid++; - emit_interp(pc, pc->iv_c, NULL, - INTERP_CENTROID); - emit_flop(pc, 0, pc->iv_c, pc->iv_c); - pc->p->cfg.fp.regs[1] |= 0x08000000; - } + for (c = 0; c < 2; ++c) + if (p->cfg.two_side[c].hw < 0x40) + p->cfg.two_side[c] = p->cfg.io[ + p->cfg.two_side[c].hw]; - for (c = 0; c < 4; c++) { - /* I don't know what these values do, but - * let's set them like the blob does: - */ - if (fcol != 0xffff && r_usage[1][fcol * 4 + c]) - pc->p->cfg.fp.regs[0] += 0x00010000; - if (bcol != 0xffff && r_usage[1][bcol * 4 + c]) - pc->p->cfg.fp.regs[0] += 0x00010000; - } - - for (i = 0; i < pc->attr_nr; i++) - load_fp_attrib(pc, i, r_usage[1], - &mid, &aid, &oid); + if (p->cfg.psiz < 0x40) + p->cfg.psiz = p->cfg.io[p->cfg.psiz].hw; + } else + if (p->type == PIPE_SHADER_FRAGMENT) { + int rid, aid; + unsigned n = 0, m = pc->attr_nr - flat_nr; - if (pc->iv_p) - free_temp(pc, pc->iv_p); - if (pc->iv_c) - free_temp(pc, pc->iv_c); + int base = (TGSI_SEMANTIC_POSITION == + p->info.input_semantic_name[0]) ? 0 : 1; - pc->p->cfg.fp.high_map = (mid / 4); - pc->p->cfg.fp.high_map += ((mid % 4) ? 1 : 0); - } else { - /* vertex program */ - for (i = 0; i < pc->attr_nr * 4; i++) { - pc->p->cfg.vp.attr[aid / 32] |= - (1 << (aid % 32)); - pc->attr[i].type = P_ATTR; - pc->attr[i].hw = aid++; - pc->attr[i].index = i / 4; + /* non-flat interpolants have to be mapped to + * the lower hardware IDs, so sort them: + */ + for (i = 0; i < pc->attr_nr; i++) { + if (pc->interp_mode[i] == INTERP_FLAT) { + p->cfg.io[m].id_vp = i + base; + p->cfg.io[m++].id_fp = i; + } else { + if (!(pc->interp_mode[i] & INTERP_PERSPECTIVE)) + p->cfg.io[n].linear = TRUE; + p->cfg.io[n].id_vp = i + base; + p->cfg.io[n++].id_fp = i; } } - } - if (pc->result_nr) { - int rid = 0; + if (!base) /* set w-coordinate mask from perspective interp */ + p->cfg.io[0].mask |= p->cfg.regs[1] >> 24; - pc->result = CALLOC(pc->result_nr * 4, sizeof(struct nv50_reg)); - if (!pc->result) - goto out_err; + aid = popcnt4( /* if fcrd isn't contained in cfg.io */ + base ? (p->cfg.regs[1] >> 24) : p->cfg.io[0].mask); - for (i = 0; i < pc->result_nr; i++) { - for (c = 0; c < 4; c++) { - if (pc->p->type == PIPE_SHADER_FRAGMENT) { - pc->result[i*4+c].type = P_TEMP; - pc->result[i*4+c].hw = -1; - pc->result[i*4+c].rhw = (i == depr) ? - -1 : rid++; - } else { - pc->result[i*4+c].type = P_RESULT; - pc->result[i*4+c].hw = rid++; - } - pc->result[i*4+c].index = i; - } + for (n = 0; n < pc->attr_nr; ++n) { + p->cfg.io[n].hw = rid = aid; + i = p->cfg.io[n].id_fp; + + for (c = 0; c < 4; ++c) { + if (!pc->attr[i * 4 + c].acc) + continue; + pc->attr[i * 4 + c].rhw = rid++; + p->cfg.io[n].mask |= 1 << c; - if (pc->p->type == PIPE_SHADER_FRAGMENT && - depr != 0xffff) { - pc->result[depr * 4 + 2].rhw = - (pc->result_nr - 1) * 4; + load_interpolant(pc, &pc->attr[i * 4 + c]); } + aid += popcnt4(p->cfg.io[n].mask); } - } - if (pc->param_nr) { - int rid = 0; + if (!base) + p->cfg.regs[1] |= p->cfg.io[0].mask << 24; - pc->param = CALLOC(pc->param_nr * 4, sizeof(struct nv50_reg)); - if (!pc->param) - goto out_err; + m = popcnt4(p->cfg.regs[1] >> 24); - for (i = 0; i < pc->param_nr; i++) { - for (c = 0; c < 4; c++) { - pc->param[i*4+c].type = P_CONST; - pc->param[i*4+c].hw = rid++; - pc->param[i*4+c].index = i; + /* set count of non-position inputs and of non-flat + * non-position inputs for FP_INTERPOLANT_CTRL + */ + p->cfg.regs[1] |= aid - m; + + if (flat_nr) { + i = p->cfg.io[pc->attr_nr - flat_nr].hw; + p->cfg.regs[1] |= (i - m) << 16; + } else + p->cfg.regs[1] |= p->cfg.regs[1] << 16; + + /* mark color semantic for light-twoside */ + n = 0x40; + for (i = 0; i < pc->attr_nr; i++) { + ubyte si, sn; + + sn = p->info.input_semantic_name[p->cfg.io[i].id_fp]; + si = p->info.input_semantic_index[p->cfg.io[i].id_fp]; + + if (sn == TGSI_SEMANTIC_COLOR) { + p->cfg.two_side[si] = p->cfg.io[i]; + + /* increase colour count */ + p->cfg.regs[0] += popcnt4( + p->cfg.two_side[si].mask) << 16; + + n = MIN2(n, p->cfg.io[i].hw - m); } } + if (n < 0x40) + p->cfg.regs[0] += n; + + /* Initialize FP results: + * FragDepth is always first TGSI and last hw output + */ + i = p->info.writes_z ? 4 : 0; + for (rid = 0; i < pc->result_nr * 4; i++) + pc->result[i].rhw = rid++; + if (p->info.writes_z) + pc->result[2].rhw = rid; } if (pc->immd_nr) { int rid = 0; - pc->immd = CALLOC(pc->immd_nr * 4, sizeof(struct nv50_reg)); + pc->immd = MALLOC(pc->immd_nr * 4 * sizeof(struct nv50_reg)); if (!pc->immd) goto out_err; for (i = 0; i < pc->immd_nr; i++) { - for (c = 0; c < 4; c++) { - pc->immd[i*4+c].type = P_IMMD; - pc->immd[i*4+c].hw = rid++; - pc->immd[i*4+c].index = i; - } + for (c = 0; c < 4; c++, rid++) + ctor_reg(&pc->immd[rid], P_IMMD, i, rid); } } ret = TRUE; out_err: - if (r_usage[0]) - FREE(r_usage[0]); - if (r_usage[1]) - FREE(r_usage[1]); + if (pc->iv_p) + free_temp(pc, pc->iv_p); + if (pc->iv_c) + free_temp(pc, pc->iv_c); - tgsi_parse_free(&p); + tgsi_parse_free(&tp); return ret; } @@ -2110,6 +2281,88 @@ free_nv50_pc(struct nv50_pc *pc) } static boolean +ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p) +{ + int i, c; + unsigned rtype[2] = { P_ATTR, P_RESULT }; + + pc->p = p; + pc->temp_nr = p->info.file_max[TGSI_FILE_TEMPORARY] + 1; + pc->attr_nr = p->info.file_max[TGSI_FILE_INPUT] + 1; + pc->result_nr = p->info.file_max[TGSI_FILE_OUTPUT] + 1; + pc->param_nr = p->info.file_max[TGSI_FILE_CONSTANT] + 1; + + p->cfg.high_temp = 4; + + p->cfg.two_side[0].hw = 0x40; + p->cfg.two_side[1].hw = 0x40; + + switch (p->type) { + case PIPE_SHADER_VERTEX: + p->cfg.psiz = 0x40; + p->cfg.clpd = 0x40; + p->cfg.io_nr = pc->result_nr; + break; + case PIPE_SHADER_FRAGMENT: + rtype[0] = rtype[1] = P_TEMP; + + p->cfg.regs[0] = 0x01000004; + p->cfg.io_nr = pc->attr_nr; + + if (p->info.writes_z) { + p->cfg.regs[2] |= 0x00000100; + p->cfg.regs[3] |= 0x00000011; + } + if (p->info.uses_kill) + p->cfg.regs[2] |= 0x00100000; + break; + } + + if (pc->temp_nr) { + pc->temp = MALLOC(pc->temp_nr * 4 * sizeof(struct nv50_reg)); + if (!pc->temp) + return FALSE; + + for (i = 0; i < pc->temp_nr * 4; ++i) + ctor_reg(&pc->temp[i], P_TEMP, i / 4, -1); + } + + if (pc->attr_nr) { + pc->attr = MALLOC(pc->attr_nr * 4 * sizeof(struct nv50_reg)); + if (!pc->attr) + return FALSE; + + for (i = 0; i < pc->attr_nr * 4; ++i) + ctor_reg(&pc->attr[i], rtype[0], i / 4, -1); + } + + if (pc->result_nr) { + unsigned nr = pc->result_nr * 4; + + pc->result = MALLOC(nr * sizeof(struct nv50_reg)); + if (!pc->result) + return FALSE; + + for (i = 0; i < nr; ++i) + ctor_reg(&pc->result[i], rtype[1], i / 4, -1); + } + + if (pc->param_nr) { + int rid = 0; + + pc->param = MALLOC(pc->param_nr * 4 * sizeof(struct nv50_reg)); + if (!pc->param) + return FALSE; + + for (i = 0; i < pc->param_nr; ++i) + for (c = 0; c < 4; ++c, ++rid) + ctor_reg(&pc->param[rid], P_CONST, i, rid); + } + + return TRUE; +} + +static boolean nv50_program_tx(struct nv50_program *p) { struct tgsi_parse_context parse; @@ -2120,8 +2373,10 @@ nv50_program_tx(struct nv50_program *p) pc = CALLOC_STRUCT(nv50_pc); if (!pc) return FALSE; - pc->p = p; - pc->p->cfg.high_temp = 4; + + ret = ctor_nv50_pc(pc, p); + if (ret == FALSE) + goto out_cleanup; ret = nv50_program_tx_prep(pc); if (ret == FALSE) @@ -2141,7 +2396,7 @@ nv50_program_tx(struct nv50_program *p) switch (tok->Token.Type) { case TGSI_TOKEN_TYPE_INSTRUCTION: ++pc->insn_cur; - ret = nv50_program_tx_insn(pc, tok); + ret = nv50_tgsi_insn(pc, tok); if (ret == FALSE) goto out_err; break; @@ -2152,8 +2407,8 @@ nv50_program_tx(struct nv50_program *p) if (p->type == PIPE_SHADER_FRAGMENT) { struct nv50_reg out; + ctor_reg(&out, P_TEMP, -1, -1); - out.type = P_TEMP; for (k = 0; k < pc->result_nr * 4; k++) { if (pc->result[k].rhw == -1) continue; @@ -2258,30 +2513,19 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) p->immd_nr, NV50_CB_PMISC); } - if (!p->data[1] && p->param_nr) { - struct nouveau_resource *heap = - nv50->screen->parm_heap[p->type]; - - if (nouveau_resource_alloc(heap, p->param_nr, p, &p->data[1])) { - while (heap->next && heap->size < p->param_nr) { - struct nv50_program *evict = heap->next->priv; - nouveau_resource_free(&evict->data[1]); - } - - if (nouveau_resource_alloc(heap, p->param_nr, p, - &p->data[1])) - assert(0); - } - } + assert(p->param_nr <= 128); if (p->param_nr) { - unsigned cbuf = NV50_CB_PVP; + unsigned cb; float *map = pipe_buffer_map(pscreen, nv50->constbuf[p->type], PIPE_BUFFER_USAGE_CPU_READ); - if (p->type == PIPE_SHADER_FRAGMENT) - cbuf = NV50_CB_PFP; - nv50_program_upload_data(nv50, map, p->data[1]->start, - p->param_nr, cbuf); + + if (p->type == PIPE_SHADER_VERTEX) + cb = NV50_CB_PVP; + else + cb = NV50_CB_PFP; + + nv50_program_upload_data(nv50, map, 0, p->param_nr, cb); pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]); } } @@ -2303,32 +2547,30 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) upload = TRUE; } - if ((p->data[0] && p->data[0]->start != p->data_start[0]) || - (p->data[1] && p->data[1]->start != p->data_start[1])) { - for (e = p->exec_head; e; e = e->next) { - unsigned ei, ci, bs; - - if (e->param.index < 0) - continue; - bs = (e->inst[1] >> 22) & 0x07; - assert(bs < 2); - ei = e->param.shift >> 5; - ci = e->param.index + p->data[bs]->start; + if (p->data[0] && p->data[0]->start != p->data_start[0]) + upload = TRUE; - e->inst[ei] &= ~e->param.mask; - e->inst[ei] |= (ci << e->param.shift); - } + if (!upload) + return; - if (p->data[0]) - p->data_start[0] = p->data[0]->start; - if (p->data[1]) - p->data_start[1] = p->data[1]->start; + for (e = p->exec_head; e; e = e->next) { + unsigned ei, ci, bs; - upload = TRUE; + if (e->param.index < 0) + continue; + bs = (e->inst[1] >> 22) & 0x07; + assert(bs < 2); + ei = e->param.shift >> 5; + ci = e->param.index; + if (bs == 0) + ci += p->data[bs]->start; + + e->inst[ei] &= ~e->param.mask; + e->inst[ei] |= (ci << e->param.shift); } - if (!upload) - return; + if (p->data[0]) + p->data_start[0] = p->data[0]->start; #ifdef NV50_PROGRAM_DUMP NOUVEAU_ERR("-------\n"); @@ -2402,8 +2644,8 @@ nv50_vertprog_validate(struct nv50_context *nv50) so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2); - so_data (so, p->cfg.vp.attr[0]); - so_data (so, p->cfg.vp.attr[1]); + so_data (so, p->cfg.attr[0]); + so_data (so, p->cfg.attr[1]); so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); so_data (so, p->cfg.high_result); so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2); @@ -2421,7 +2663,6 @@ nv50_fragprog_validate(struct nv50_context *nv50) struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_program *p = nv50->fragprog; struct nouveau_stateobj *so; - unsigned i; if (!p->translated) { nv50_program_validate(nv50, p); @@ -2438,29 +2679,186 @@ nv50_fragprog_validate(struct nv50_context *nv50) NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4); - so_data (so, p->cfg.fp.regs[0]); /* 0x01000404 / 0x00040404 */ - so_data (so, 0x00000004); - so_data (so, 0x00000000); - so_data (so, 0x00000000); - so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), p->cfg.fp.high_map); - for (i = 0; i < p->cfg.fp.high_map; i++) - so_data(so, p->cfg.fp.map[i]); - so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 2); - so_data (so, p->cfg.fp.regs[1]); /* 0x08040404 / 0x0f000401 */ + so_method(so, tesla, NV50TCL_FP_REG_ALLOC_TEMP, 1); so_data (so, p->cfg.high_temp); so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1); so_data (so, p->cfg.high_result); so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1); - so_data (so, p->cfg.fp.regs[2]); + so_data (so, p->cfg.regs[2]); so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1); - so_data (so, p->cfg.fp.regs[3]); + so_data (so, p->cfg.regs[3]); so_method(so, tesla, NV50TCL_FP_START_ID, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.fragprog); so_ref(NULL, &so); } +static void +nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base) +{ + struct nv50_program *fp = nv50->fragprog; + struct nv50_program *vp = nv50->vertprog; + unsigned i, c, m = base; + + /* XXX: This can't work correctly in all cases yet, we either + * have to create TGSI_SEMANTIC_PNTC or sprite_coord_mode has + * to be per FP input instead of per VP output + */ + memset(pntc, 0, 8 * sizeof(uint32_t)); + + for (i = 0; i < fp->cfg.io_nr; i++) { + uint8_t sn, si; + uint8_t j = fp->cfg.io[i].id_vp, k = fp->cfg.io[i].id_fp; + unsigned n = popcnt4(fp->cfg.io[i].mask); + + if (fp->info.input_semantic_name[k] != TGSI_SEMANTIC_GENERIC) { + m += n; + continue; + } + + sn = vp->info.input_semantic_name[j]; + si = vp->info.input_semantic_index[j]; + + if (j < fp->cfg.io_nr && sn == TGSI_SEMANTIC_GENERIC) { + ubyte mode = + nv50->rasterizer->pipe.sprite_coord_mode[si]; + + if (mode == PIPE_SPRITE_COORD_NONE) { + m += n; + continue; + } + } + + /* this is either PointCoord or replaced by sprite coords */ + for (c = 0; c < 4; c++) { + if (!(fp->cfg.io[i].mask & (1 << c))) + continue; + pntc[m / 8] |= (c + 1) << ((m % 8) * 4); + ++m; + } + } +} + +static int +nv50_sreg4_map(uint32_t *p_map, int mid, uint32_t lin[4], + struct nv50_sreg4 *fpi, struct nv50_sreg4 *vpo) +{ + int c; + uint8_t mv = vpo->mask, mf = fpi->mask, oid = vpo->hw; + uint8_t *map = (uint8_t *)p_map; + + for (c = 0; c < 4; ++c) { + if (mf & 1) { + if (fpi->linear == TRUE) + lin[mid / 32] |= 1 << (mid % 32); + map[mid++] = (mv & 1) ? oid : ((c == 3) ? 0x41 : 0x40); + } + + oid += mv & 1; + mf >>= 1; + mv >>= 1; + } + + return mid; +} + +void +nv50_linkage_validate(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_program *vp = nv50->vertprog; + struct nv50_program *fp = nv50->fragprog; + struct nouveau_stateobj *so; + struct nv50_sreg4 dummy, *vpo; + int i, n, c, m = 0; + uint32_t map[16], lin[4], reg[5], pcrd[8]; + + memset(map, 0, sizeof(map)); + memset(lin, 0, sizeof(lin)); + + reg[1] = 0x00000004; /* low and high clip distance map ids */ + reg[2] = 0x00000000; /* layer index map id (disabled, GP only) */ + reg[3] = 0x00000000; /* point size map id & enable */ + reg[0] = fp->cfg.regs[0]; /* colour semantic reg */ + reg[4] = fp->cfg.regs[1]; /* interpolant info */ + + dummy.linear = FALSE; + dummy.mask = 0xf; /* map all components of HPOS */ + m = nv50_sreg4_map(map, m, lin, &dummy, &vp->cfg.io[0]); + + dummy.mask = 0x0; + + if (vp->cfg.clpd < 0x40) { + for (c = 0; c < vp->cfg.clpd_nr; ++c) + map[m++] = vp->cfg.clpd + c; + reg[1] = (m << 8); + } + + reg[0] |= m << 8; /* adjust BFC0 id */ + + /* if light_twoside is active, it seems FFC0_ID == BFC0_ID is bad */ + if (nv50->rasterizer->pipe.light_twoside) { + vpo = &vp->cfg.two_side[0]; + + m = nv50_sreg4_map(map, m, lin, &fp->cfg.two_side[0], &vpo[0]); + m = nv50_sreg4_map(map, m, lin, &fp->cfg.two_side[1], &vpo[1]); + } + + reg[0] += m - 4; /* adjust FFC0 id */ + reg[4] |= m << 8; /* set mid where 'normal' FP inputs start */ + + i = 0; + if (fp->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) + i = 1; + for (; i < fp->cfg.io_nr; i++) { + ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id_fp]; + ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id_fp]; + + n = fp->cfg.io[i].id_vp; + if (n >= vp->cfg.io_nr || + vp->info.output_semantic_name[n] != sn || + vp->info.output_semantic_index[n] != si) + vpo = &dummy; + else + vpo = &vp->cfg.io[n]; + + m = nv50_sreg4_map(map, m, lin, &fp->cfg.io[i], vpo); + } + + if (nv50->rasterizer->pipe.point_size_per_vertex) { + map[m / 4] |= vp->cfg.psiz << ((m % 4) * 8); + reg[3] = (m++ << 4) | 1; + } + + /* now fill the stateobj */ + so = so_new(64, 0); + + n = (m + 3) / 4; + so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1); + so_data (so, m); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), n); + so_datap (so, map, n); + + so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4); + so_datap (so, reg, 4); + + so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 1); + so_data (so, reg[4]); + + so_method(so, tesla, 0x1540, 4); + so_datap (so, lin, 4); + + if (nv50->rasterizer->pipe.point_sprite) { + nv50_pntc_replace(nv50, pcrd, (reg[4] >> 8) & 0xff); + + so_method(so, tesla, NV50TCL_POINT_COORD_REPLACE_MAP(0), 8); + so_datap (so, pcrd, 8); + } + + so_ref(so, &nv50->state.programs); + so_ref(NULL, &so); +} + void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) { @@ -2476,7 +2874,6 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) nouveau_bo_ref(NULL, &p->bo); nouveau_resource_free(&p->data[0]); - nouveau_resource_free(&p->data[1]); p->translated = 0; } diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index 096e0476aab..d78dee083f1 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -15,6 +15,15 @@ struct nv50_program_exec { } param; }; +struct nv50_sreg4 { + uint8_t hw; + uint8_t id_vp; + uint8_t id_fp; + + uint8_t mask; + boolean linear; +}; + struct nv50_program { struct pipe_shader_state pipe; struct tgsi_shader_info info; @@ -24,8 +33,8 @@ struct nv50_program { struct nv50_program_exec *exec_head; struct nv50_program_exec *exec_tail; unsigned exec_size; - struct nouveau_resource *data[2]; - unsigned data_start[2]; + struct nouveau_resource *data[1]; + unsigned data_start[1]; struct nouveau_bo *bo; @@ -36,14 +45,20 @@ struct nv50_program { struct { unsigned high_temp; unsigned high_result; - struct { - unsigned attr[2]; - } vp; - struct { - unsigned regs[4]; - unsigned map[5]; - unsigned high_map; - } fp; + + uint32_t attr[2]; + uint32_t regs[4]; + + /* for VPs, io_nr doesn't count 'private' results (PSIZ etc.) */ + unsigned io_nr; + struct nv50_sreg4 io[PIPE_MAX_SHADER_OUTPUTS]; + + /* FP colour inputs, VP/GP back colour outputs */ + struct nv50_sreg4 two_side[2]; + + /* VP only */ + uint8_t clpd, clpd_nr; + uint8_t psiz; } cfg; }; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index c7f80a22037..3b08e1b89fb 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -87,12 +87,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case PIPE_CAP_GLSL: return 0; - case PIPE_CAP_S3TC: - return 1; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: - return 0; + return 1; case PIPE_CAP_MAX_RENDER_TARGETS: return 8; case PIPE_CAP_OCCLUSION_QUERY: diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 4283808ed93..81fa3e34c59 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -276,6 +276,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, so_method(so, tesla, 0x1684, 1); so_data (so, cso->flatshade_first ? 0 : 1); + so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1); + so_data (so, cso->light_twoside); + so_method(so, tesla, NV50TCL_LINE_WIDTH, 1); so_data (so, fui(cso->line_width)); so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1); @@ -294,6 +297,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, so_method(so, tesla, NV50TCL_POINT_SIZE, 1); so_data (so, fui(cso->point_size)); + so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1); + so_data (so, cso->point_sprite); + so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3); if (cso->front_winding == PIPE_WINDING_CCW) { so_data(so, nvgl_polygon_mode(cso->fill_ccw)); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index d294356f75d..5a3559ed181 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -189,6 +189,8 @@ nv50_state_emit(struct nv50_context *nv50) so_emit(chan, nv50->state.vertprog); if (nv50->state.dirty & NV50_NEW_FRAGPROG) so_emit(chan, nv50->state.fragprog); + if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG)) + so_emit(chan, nv50->state.programs); if (nv50->state.dirty & NV50_NEW_RASTERIZER) so_emit(chan, nv50->state.rast); if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR) @@ -210,6 +212,12 @@ nv50_state_emit(struct nv50_context *nv50) so_emit(chan, nv50->state.vtxattr); } nv50->state.dirty = 0; +} + +void +nv50_state_flush_notify(struct nouveau_channel *chan) +{ + struct nv50_context *nv50 = chan->user_private; so_emit_reloc_markers(chan, nv50->state.fb); so_emit_reloc_markers(chan, nv50->state.vertprog); @@ -240,6 +248,9 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) nv50_fragprog_validate(nv50); + if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG)) + nv50_linkage_validate(nv50); + if (nv50->dirty & NV50_NEW_RASTERIZER) so_ref(nv50->rasterizer->so, &nv50->state.rast); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index e9c3562194b..bb7731855cd 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -89,14 +89,14 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, if (src_bo->tile_flags) { BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1); - OUT_RING (chan, (sy << 16) | sx); + OUT_RING (chan, (sy << 16) | (sx * cpp)); } else { src_offset += (line_count * src_pitch); } if (dst_bo->tile_flags) { BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1); - OUT_RING (chan, (dy << 16) | dx); + OUT_RING (chan, (dy << 16) | (dx * cpp)); } else { dst_offset += (line_count * dst_pitch); } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 593178c50be..3b5b1bbd37f 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -93,8 +93,6 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) } else { return 0; } - case PIPE_CAP_S3TC: - return 1; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 6178c4ac7e3..ce770184158 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -65,8 +65,6 @@ softpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_GLSL: return 1; - case PIPE_CAP_S3TC: - return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: @@ -141,6 +139,7 @@ softpipe_is_format_supported( struct pipe_screen *screen, case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: + case PIPE_FORMAT_Z32_FLOAT: return FALSE; default: return TRUE; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index b01ab6d137c..f252d6df00d 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -281,7 +281,7 @@ enum pipe_transfer_usage { #define PIPE_CAP_NPOT_TEXTURES 2 #define PIPE_CAP_TWO_SIDED_STENCIL 3 #define PIPE_CAP_GLSL 4 /* XXX need something better */ -#define PIPE_CAP_S3TC 5 +#define PIPE_CAP_S3TC 5 /* XXX: deprecated; cap determined via supported sampler formats */ #define PIPE_CAP_ANISOTROPIC_FILTER 6 #define PIPE_CAP_POINT_SPRITE 7 #define PIPE_CAP_MAX_RENDER_TARGETS 8 diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index a5c1e8270a3..30a4aaf4093 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -118,7 +118,7 @@ pipe_buffer_write(struct pipe_screen *screen, unsigned offset, unsigned size, const void *data) { - uint8_t *map; + void *map; assert(offset < buf->size); assert(offset + size <= buf->size); @@ -129,7 +129,7 @@ pipe_buffer_write(struct pipe_screen *screen, PIPE_BUFFER_USAGE_FLUSH_EXPLICIT); assert(map); if(map) { - memcpy(map + offset, data, size); + memcpy((uint8_t *)map + offset, data, size); pipe_buffer_flush_mapped_range(screen, buf, offset, size); pipe_buffer_unmap(screen, buf); } @@ -141,7 +141,7 @@ pipe_buffer_read(struct pipe_screen *screen, unsigned offset, unsigned size, void *data) { - uint8_t *map; + void *map; assert(offset < buf->size); assert(offset + size <= buf->size); @@ -150,11 +150,31 @@ pipe_buffer_read(struct pipe_screen *screen, map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_READ); assert(map); if(map) { - memcpy(data, map + offset, size); + memcpy(data, (const uint8_t *)map + offset, size); pipe_buffer_unmap(screen, buf); } } +static INLINE void * +pipe_transfer_map( struct pipe_transfer *transf ) +{ + struct pipe_screen *screen = transf->texture->screen; + return screen->transfer_map(screen, transf); +} + +static INLINE void +pipe_transfer_unmap( struct pipe_transfer *transf ) +{ + struct pipe_screen *screen = transf->texture->screen; + screen->transfer_unmap(screen, transf); +} + +static INLINE void +pipe_transfer_destroy( struct pipe_transfer *transf ) +{ + struct pipe_screen *screen = transf->texture->screen; + screen->tex_transfer_destroy(transf); +} #ifdef __cplusplus } diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 626bedb35a8..2187f5b3677 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -307,7 +307,7 @@ struct pipe_transfer unsigned nblocksx; /**< allocated width in blocks */ unsigned nblocksy; /**< allocated height in blocks */ unsigned stride; /**< stride in bytes between rows of blocks */ - unsigned usage; /**< PIPE_TRANSFER_* */ + enum pipe_transfer_usage usage; /**< PIPE_TRANSFER_* */ struct pipe_texture *texture; /**< texture to transfer to/from */ unsigned face; diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index b1606dc6526..25e41482325 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -39,7 +39,7 @@ #include "util/u_debug.h" /* for assert */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) #include <pthread.h> /* POSIX threads headers */ #include <stdio.h> /* for perror() */ @@ -213,7 +213,7 @@ typedef unsigned pipe_condvar; */ typedef struct { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) pthread_key_t key; #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) DWORD key; @@ -228,7 +228,7 @@ typedef struct { static INLINE void pipe_tsd_init(pipe_tsd *tsd) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { perror("pthread_key_create(): failed to allocate key for thread specific data"); exit(-1); @@ -245,7 +245,7 @@ pipe_tsd_get(pipe_tsd *tsd) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) return pthread_getspecific(tsd->key); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) assert(0); @@ -262,7 +262,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) if (pthread_setspecific(tsd->key, value) != 0) { perror("pthread_set_specific() failed"); exit(-1); diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c index 7c8e545824f..b1683b891be 100644 --- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c @@ -51,6 +51,7 @@ static int vlResizeFrameBuffer struct vlBasicCSC *basic_csc; struct pipe_context *pipe; struct pipe_texture template; + float clear_color[4]; assert(csc); @@ -68,7 +69,12 @@ static int vlResizeFrameBuffer basic_csc->viewport.translate[1] = 0; basic_csc->viewport.translate[2] = 0; basic_csc->viewport.translate[3] = 0; - + + clear_color[0] = 0.0f; + clear_color[1] = 0.0f; + clear_color[2] = 0.0f; + clear_color[3] = 0.0f; + if (basic_csc->framebuffer_tex) { pipe_surface_reference(&basic_csc->framebuffer.cbufs[0], NULL); @@ -98,7 +104,7 @@ static int vlResizeFrameBuffer /* Clear to black, in case video doesn't fill the entire window */ pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer); - pipe->clear(pipe, PIPE_CLEAR_COLOR, 0, 0.0f, 0); + pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0.0f, 0); return 0; } diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 15c955450d0..66ca4cb5905 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -12,9 +12,9 @@ struct xorg_composite_blend { int op:8; unsigned rgb_src_factor:5; /**< PIPE_BLENDFACTOR_x */ - unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ - unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */ + + unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ }; @@ -653,17 +653,12 @@ boolean xorg_solid_bind_state(struct exa_context *exa, exa->solid_color[3] = 1.f; +#if 0 debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n", (fg >> 24) & 0xff, (fg >> 16) & 0xff, (fg >> 8) & 0xff, (fg >> 0) & 0xff, exa->solid_color[0], exa->solid_color[1], exa->solid_color[2], exa->solid_color[3]); - -#if 0 - exa->solid_color[0] = 1.f; - exa->solid_color[1] = 0.f; - exa->solid_color[2] = 0.f; - exa->solid_color[3] = 1.f; #endif vs_traits = VS_SOLID_FILL; @@ -691,9 +686,6 @@ void xorg_solid(struct exa_context *exa, struct pipe_buffer *buf = 0; float vertices[4][2][4]; - x0 = 10; y0 = 10; - x1 = 300; y1 = 300; - /* 1st vertex */ setup_vertex0(vertices[0], x0, y0, exa->solid_color); @@ -844,11 +836,6 @@ static void renderer_copy_texture(struct exa_context *exa, assert(dst->width[0] != 0); assert(dst->height[0] != 0); -#if 0 - debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n", - sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); -#endif - #if 1 s0 = sx1 / src->width[0]; s1 = sx2 / src->width[0]; @@ -861,8 +848,16 @@ static void renderer_copy_texture(struct exa_context *exa, t1 = 1; #endif - assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); +#if 1 + debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n", + sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, + s0, t0, s1, t1); +#endif + + assert(screen->is_format_supported(screen, dst_surf->format, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, + 0)); /* save state (restored below) */ cso_save_blend(exa->cso); @@ -926,6 +921,8 @@ static void renderer_copy_texture(struct exa_context *exa, fb.cbufs[i] = 0; } cso_set_framebuffer(exa->cso, &fb); + setup_vs_constant_buffer(exa, fb.width, fb.height); + setup_fs_constant_buffer(exa); /* draw quad */ buf = setup_vertex_data_tex(exa, @@ -955,6 +952,61 @@ static void renderer_copy_texture(struct exa_context *exa, pipe_surface_reference(&dst_surf, NULL); } + +static struct pipe_texture * +create_sampler_texture(struct exa_context *ctx, + struct pipe_texture *src) +{ + enum pipe_format format; + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_texture *pt; + struct pipe_texture templ; + + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + /* the coming in texture should already have that invariance */ + debug_assert(screen->is_format_supported(screen, src->format, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_SAMPLER, 0)); + + format = src->format; + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.format = format; + templ.last_level = 0; + templ.width[0] = src->width[0]; + templ.height[0] = src->height[0]; + templ.depth[0] = 1; + pf_get_block(format, &templ.block); + templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; + + pt = screen->texture_create(screen, &templ); + + debug_assert(!pt || pipe_is_referenced(&pt->reference)); + + if (!pt) + return NULL; + + { + /* copy source framebuffer surface into texture */ + struct pipe_surface *ps_read = screen->get_tex_surface( + screen, src, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); + struct pipe_surface *ps_tex = screen->get_tex_surface( + screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE ); + pipe->surface_copy(pipe, + ps_tex, /* dest */ + 0, 0, /* destx/y */ + ps_read, + 0, 0, src->width[0], src->height[0]); + pipe_surface_reference(&ps_read, NULL); + pipe_surface_reference(&ps_tex, NULL); + } + + return pt; +} + void xorg_copy_pixmap(struct exa_context *ctx, struct exa_pixmap_priv *dst_priv, int dx, int dy, struct exa_pixmap_priv *src_priv, int sx, int sy, @@ -966,6 +1018,8 @@ void xorg_copy_pixmap(struct exa_context *ctx, struct pipe_texture *dst = dst_priv->tex; struct pipe_texture *src = src_priv->tex; + xorg_exa_finish(ctx); + dst_loc[0] = dx; dst_loc[1] = dy; dst_loc[2] = width; @@ -1003,17 +1057,25 @@ void xorg_copy_pixmap(struct exa_context *ctx, if (src_loc[2] >= 0 && src_loc[3] >= 0 && dst_loc[2] >= 0 && dst_loc[3] >= 0) { + struct pipe_texture *temp_src = src; + + if (src == dst) + temp_src = create_sampler_texture(ctx, src); + renderer_copy_texture(ctx, - src, + temp_src, src_loc[0], - src_loc[1] + src_loc[3], - src_loc[0] + src_loc[2], src_loc[1], + src_loc[0] + src_loc[2], + src_loc[1] + src_loc[3], dst, dst_loc[0], - dst_loc[1] + dst_loc[3], + dst_loc[1], dst_loc[0] + dst_loc[2], - dst_loc[1]); + dst_loc[1] + dst_loc[3]); + + if (src == dst) + pipe_texture_reference(&temp_src, NULL); } } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 312dab1544c..dea9f4c2bc3 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -47,6 +47,8 @@ #include "util/u_rect.h" +#define DEBUG_SOLID 0 + /* * Helper functions */ @@ -72,6 +74,9 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp) assert(*bbp == 16); break; case 8: + *format = PIPE_FORMAT_A8_UNORM; + assert(*bbp == 8); + break; case 4: case 1: *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ @@ -253,7 +258,7 @@ ExaDone(PixmapPtr pPixmap) #if 1 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); #else - xorg_finish(exa); + xorg_exa_finish(exa); #endif xorg_exa_common_done(exa); } @@ -276,23 +281,35 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); struct exa_context *exa = ms->exa; +#if 0 debug_printf("ExaPrepareSolid - test\n"); - if (pPixmap->drawable.depth < 15) - return FALSE; - +#endif if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) return FALSE; if (!priv || !priv->tex) return FALSE; + if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, + priv->tex->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) + return FALSE; + if (alu != GXcopy) return FALSE; if (!exa->pipe) return FALSE; + +#if DEBUG_SOLID + fg = 0xffff0000; +#endif + +#if 1 debug_printf(" ExaPrepareSolid(0x%x)\n", fg); +#endif + return xorg_solid_bind_state(exa, priv, fg); } @@ -310,11 +327,42 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) if (x0 == 0 && y0 == 0 && x1 == priv->tex->width[0] && y1 == priv->tex->height[0]) { - exa->ctx->clear(exa->ctx, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, + exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR, exa->solid_color, 1., 0); } else #endif - xorg_solid(exa, priv, x0, y0, x1, y1) ; + +#if DEBUG_SOLID + exa->solid_color[0] = 0.f; + exa->solid_color[1] = 1.f; + exa->solid_color[2] = 0.f; + exa->solid_color[3] = 1.f; + xorg_solid(exa, priv, 0, 0, 1024, 768); + exa->solid_color[0] = 1.f; + exa->solid_color[1] = 0.f; + exa->solid_color[2] = 0.f; + exa->solid_color[3] = 1.f; + xorg_solid(exa, priv, 0, 0, 300, 300); + xorg_solid(exa, priv, 300, 300, 350, 350); + xorg_solid(exa, priv, 350, 350, 500, 500); + + xorg_solid(exa, priv, + priv->tex->width[0] - 10, + priv->tex->height[0] - 10, + priv->tex->width[0], + priv->tex->height[0]); + + exa->solid_color[0] = 0.f; + exa->solid_color[1] = 0.f; + exa->solid_color[2] = 1.f; + exa->solid_color[3] = 1.f; + + exa->has_solid_color = FALSE; + ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff); + ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500); +#else + xorg_solid(exa, priv, x0, y0, x1, y1) ; +#endif } static Bool @@ -332,15 +380,20 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, if (alu != GXcopy) return FALSE; - if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15) - return FALSE; - if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) return FALSE; if (!priv || !src_priv) return FALSE; + if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, + priv->tex->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0) || + !exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, + src_priv->tex->target, + PIPE_TEXTURE_USAGE_SAMPLER, 0)) + return FALSE; + if (!priv->tex || !src_priv->tex) return FALSE; @@ -433,14 +486,11 @@ static void ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) { struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); if (!priv) return; - if (priv->tex) - ms->screen->texture_destroy(priv->tex); + pipe_texture_reference(&priv->tex, NULL); xfree(priv); } @@ -583,8 +633,8 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, struct pipe_surface *dst_surf; struct pipe_surface *src_surf; - dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); + dst_surf = exa->scrn->get_tex_surface( + exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); src_surf = exa_gpu_surface(exa, priv); exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, 0, 0, min(width, texture->width[0]), diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index b30cbff4793..2daa5b5628f 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -52,8 +52,7 @@ struct xorg_shaders { static const char over_op[] = "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n" - "MUL TEMP[3], TEMP[0], TEMP[3]\n" - "ADD TEMP[0], TEMP[3], TEMP[0]\n"; + "MAD TEMP[3], TEMP[0], TEMP[3], TEMP[0]\n"; static INLINE void @@ -79,8 +78,7 @@ vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords, { struct ureg_dst tmp = ureg_DECL_temporary(ureg); struct ureg_src ret; - ureg_MUL(ureg, tmp, coords, const0); - ureg_ADD(ureg, tmp, ureg_src(tmp), const1); + ureg_MAD(ureg, tmp, coords, const0, const1); ret = ureg_src(tmp); ureg_release_temporary(ureg, tmp); return ret; @@ -261,7 +259,7 @@ create_vs(struct pipe_context *pipe, if (is_composite) { src = ureg_DECL_vs_input(ureg, input_slot++); - dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); ureg_MOV(ureg, dst, src); } @@ -312,7 +310,7 @@ create_fs(struct pipe_context *pipe, if (is_composite) { src_sampler = ureg_DECL_sampler(ureg, 0); src_input = ureg_DECL_fs_input(ureg, - TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_PERSPECTIVE); } else { @@ -367,11 +365,11 @@ create_fs(struct pipe_context *pipe, else src = out; - coords = ureg_DECL_constant(ureg); - const0124 = ureg_DECL_constant(ureg); - matrow0 = ureg_DECL_constant(ureg); - matrow1 = ureg_DECL_constant(ureg); - matrow2 = ureg_DECL_constant(ureg); + coords = ureg_DECL_constant(ureg, 0); + const0124 = ureg_DECL_constant(ureg, 1); + matrow0 = ureg_DECL_constant(ureg, 2); + matrow1 = ureg_DECL_constant(ureg, 3); + matrow2 = ureg_DECL_constant(ureg, 4); if (is_lingrad) { linear_gradient(ureg, src, diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 698c2856a4f..37d60ce5406 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -105,6 +105,7 @@ static struct pipe_buffer* xsp_surface_buffer_create unsigned height, enum pipe_format format, unsigned usage, + unsigned tex_usage, unsigned *stride ) { diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript index 243146fca7f..9fbe9e800c3 100644 --- a/src/gallium/winsys/gdi/SConscript +++ b/src/gallium/winsys/gdi/SConscript @@ -5,35 +5,39 @@ Import('*') if env['platform'] == 'windows': - env = env.Clone() + env = env.Clone() - env.Append(CPPPATH = [ - '#src/gallium/state_trackers/wgl', - ]) + env.Append(CPPPATH = [ + '#src/gallium/state_trackers/wgl', + ]) - env.Append(LIBS = [ - 'gdi32', - 'user32', - 'kernel32', - 'ws2_32', - ]) + env.Append(LIBS = [ + 'gdi32', + 'user32', + 'kernel32', + 'ws2_32', + ]) - sources = [ - 'gdi_softpipe_winsys.c', - ] - - if env['gcc']: - sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def'] - else: - sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] - - drivers = [ - trace, - softpipe, - ] + if 'llvmpipe' in env['drivers']: + sources = ['gdi_llvmpipe_winsys.c'] + drivers = [llvmpipe] + env.Tool('llvm') + elif 'softpipe' in env['drivers']: + sources = ['gdi_softpipe_winsys.c'] + drivers = [softpipe] + else: + print 'warning: softpipe or llvmpipe not selected, gdi winsys disabled' + Return() + + if env['gcc']: + sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def'] + else: + sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] + + drivers += [trace] - env.SharedLibrary( - target ='opengl32', - source = sources, - LIBS = wgl + glapi + mesa + drivers + auxiliaries + glsl + env['LIBS'], - ) + env.SharedLibrary( + target ='opengl32', + source = sources, + LIBS = wgl + glapi + mesa + drivers + auxiliaries + glsl + env['LIBS'], + ) diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c new file mode 100644 index 00000000000..c0c33b45d59 --- /dev/null +++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c @@ -0,0 +1,284 @@ +/************************************************************************** + * + * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * LLVMpipe support. + * + * @author Jose Fonseca <[email protected]> + */ + + +#include <windows.h> + +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "llvmpipe/lp_winsys.h" +#include "llvmpipe/lp_texture.h" +#include "shared/stw_winsys.h" + + +struct gdi_llvmpipe_displaytarget +{ + enum pipe_format format; + struct pipe_format_block block; + unsigned width; + unsigned height; + unsigned stride; + + unsigned size; + + void *data; + + BITMAPINFO bmi; +}; + + +/** Cast wrapper */ +static INLINE struct gdi_llvmpipe_displaytarget * +gdi_llvmpipe_displaytarget( struct llvmpipe_displaytarget *buf ) +{ + return (struct gdi_llvmpipe_displaytarget *)buf; +} + + +static boolean +gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws, + enum pipe_format format ) +{ + switch(format) { + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_A8R8G8B8_UNORM: + return TRUE; + + /* TODO: Support other formats possible with BMPs, as described in + * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */ + + default: + return FALSE; + } +} + + +static void * +gdi_llvmpipe_displaytarget_map(struct llvmpipe_winsys *ws, + struct llvmpipe_displaytarget *dt, + unsigned flags ) +{ + struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt); + + return gdt->data; +} + + +static void +gdi_llvmpipe_displaytarget_unmap(struct llvmpipe_winsys *ws, + struct llvmpipe_displaytarget *dt ) +{ + +} + + +static void +gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys, + struct llvmpipe_displaytarget *dt) +{ + struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt); + + align_free(gdt->data); + FREE(gdt); +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static struct llvmpipe_displaytarget * +gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) +{ + struct gdi_llvmpipe_displaytarget *gdt; + unsigned cpp; + unsigned bpp; + + gdt = CALLOC_STRUCT(gdi_llvmpipe_displaytarget); + if(!gdt) + goto no_gdt; + + gdt->format = format; + gdt->width = width; + gdt->height = height; + + bpp = pf_get_bits(format); + cpp = pf_get_size(format); + + gdt->stride = round_up(width * cpp, alignment); + gdt->size = gdt->stride * height; + + gdt->data = align_malloc(gdt->size, alignment); + if(!gdt->data) + goto no_data; + + gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp; + gdt->bmi.bmiHeader.biHeight= -(long)height; + gdt->bmi.bmiHeader.biPlanes = 1; + gdt->bmi.bmiHeader.biBitCount = bpp; + gdt->bmi.bmiHeader.biCompression = BI_RGB; + gdt->bmi.bmiHeader.biSizeImage = 0; + gdt->bmi.bmiHeader.biXPelsPerMeter = 0; + gdt->bmi.bmiHeader.biYPelsPerMeter = 0; + gdt->bmi.bmiHeader.biClrUsed = 0; + gdt->bmi.bmiHeader.biClrImportant = 0; + + *stride = gdt->stride; + return (struct llvmpipe_displaytarget *)gdt; + +no_data: + FREE(gdt); +no_gdt: + return NULL; +} + + +static void +gdi_llvmpipe_displaytarget_display(struct llvmpipe_winsys *winsys, + struct llvmpipe_displaytarget *dt, + void *context_private) +{ + assert(0); +} + + +static void +gdi_llvmpipe_destroy(struct llvmpipe_winsys *winsys) +{ + FREE(winsys); +} + + +static struct pipe_screen * +gdi_llvmpipe_screen_create(void) +{ + static struct llvmpipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(llvmpipe_winsys); + if(!winsys) + goto no_winsys; + + winsys->destroy = gdi_llvmpipe_destroy; + winsys->is_displaytarget_format_supported = gdi_llvmpipe_is_displaytarget_format_supported; + winsys->displaytarget_create = gdi_llvmpipe_displaytarget_create; + winsys->displaytarget_map = gdi_llvmpipe_displaytarget_map; + winsys->displaytarget_unmap = gdi_llvmpipe_displaytarget_unmap; + winsys->displaytarget_display = gdi_llvmpipe_displaytarget_display; + winsys->displaytarget_destroy = gdi_llvmpipe_displaytarget_destroy; + + screen = llvmpipe_create_screen(winsys); + if(!screen) + goto no_screen; + + return screen; + +no_screen: + FREE(winsys); +no_winsys: + return NULL; +} + + +static struct pipe_context * +gdi_llvmpipe_context_create(struct pipe_screen *screen) +{ + return llvmpipe_create(screen); +} + + +static void +gdi_llvmpipe_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surface, + HDC hDC) +{ + struct llvmpipe_texture *texture; + struct gdi_llvmpipe_displaytarget *gdt; + + texture = llvmpipe_texture(surface->texture); + gdt = gdi_llvmpipe_displaytarget(texture->dt); + + StretchDIBits(hDC, + 0, 0, gdt->width, gdt->height, + 0, 0, gdt->width, gdt->height, + gdt->data, &gdt->bmi, 0, SRCCOPY); +} + + +static const struct stw_winsys stw_winsys = { + &gdi_llvmpipe_screen_create, + &gdi_llvmpipe_context_create, + &gdi_llvmpipe_flush_frontbuffer +}; + + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + if (!stw_init(&stw_winsys)) { + return FALSE; + } + return stw_init_thread(); + + case DLL_THREAD_ATTACH: + return stw_init_thread(); + + case DLL_THREAD_DETACH: + stw_cleanup_thread(); + break; + + case DLL_PROCESS_DETACH: + stw_cleanup_thread(); + stw_cleanup(); + break; + } + return TRUE; +} diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 522f6dc5aee..3a1945d92c5 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -34,6 +34,7 @@ XLIB_WINSYS_SOURCES = \ xlib_brw_aub.c \ xlib_brw_context.c \ xlib_brw_screen.c \ + xlib_llvmpipe.c \ xlib_softpipe.c \ xlib_trace.c diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c index bc876591c0d..3dd15e099b0 100644 --- a/src/gallium/winsys/xlib/xlib_llvmpipe.c +++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c @@ -33,6 +33,8 @@ */ +#if defined(GALLIUM_LLVMPIPE) + #include "xm_api.h" #undef ASSERT @@ -459,3 +461,4 @@ struct xm_driver xlib_llvmpipe_driver = +#endif /* GALLIUM_LLVMPIPE */ diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c index 88a17df6f8d..01569213f2d 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/x11/glx_pbuffer.c @@ -41,6 +41,23 @@ /** + * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems. + */ +static void +warn_GLX_1_3(Display *dpy, const char *function_name) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + + if (priv->minorVersion < 3) { + fprintf(stderr, + "WARNING: Application calling GLX 1.3 function \"%s\" " + "when GLX 1.3 is not supported! This is an application bug!\n", + function_name); + } +} + + +/** * Change a drawable's attribute. * * This function is used to implement \c glXSelectEvent and @@ -559,6 +576,8 @@ glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) width = 0; height = 0; + warn_GLX_1_3(dpy, __func__); + for (i = 0; attrib_list[i * 2]; i++) { switch (attrib_list[i * 2]) { case GLX_PBUFFER_WIDTH: @@ -592,6 +611,7 @@ PUBLIC void glXQueryDrawable(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { + warn_GLX_1_3(dpy, __func__); GetDrawableAttribute(dpy, drawable, attribute, value); } @@ -645,6 +665,8 @@ PUBLIC GLXPixmap glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list) { + warn_GLX_1_3(dpy, __func__); + return CreateDrawable(dpy, (__GLcontextModes *) config, (Drawable) pixmap, attrib_list, X_GLXCreatePixmap); } @@ -654,6 +676,8 @@ PUBLIC GLXWindow glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, const int *attrib_list) { + warn_GLX_1_3(dpy, __func__); + return CreateDrawable(dpy, (__GLcontextModes *) config, (Drawable) win, attrib_list, X_GLXCreateWindow); } @@ -662,6 +686,8 @@ glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, PUBLIC void glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) { + warn_GLX_1_3(dpy, __func__); + DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap); } @@ -669,6 +695,8 @@ glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) PUBLIC void glXDestroyWindow(Display * dpy, GLXWindow win) { + warn_GLX_1_3(dpy, __func__); + DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow); } diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 05909cfa307..aa7c73ba36a 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -68,6 +68,29 @@ /** + * Flags passed to _mesa_meta_begin(). + */ +/*@{*/ +#define META_ALL ~0x0 +#define META_ALPHA_TEST 0x1 +#define META_BLEND 0x2 /**< includes logicop */ +#define META_COLOR_MASK 0x4 +#define META_DEPTH_TEST 0x8 +#define META_FOG 0x10 +#define META_PIXEL_STORE 0x20 +#define META_PIXEL_TRANSFER 0x40 +#define META_RASTERIZATION 0x80 +#define META_SCISSOR 0x100 +#define META_SHADER 0x200 +#define META_STENCIL_TEST 0x400 +#define META_TRANSFORM 0x800 /**< modelview, projection, clip planes */ +#define META_TEXTURE 0x1000 +#define META_VERTEX 0x2000 +#define META_VIEWPORT 0x4000 +/*@}*/ + + +/** * State which we may save/restore across meta ops. * XXX this may be incomplete... */ @@ -94,6 +117,17 @@ struct save_state /** META_PIXEL_STORE */ struct gl_pixelstore_attrib Pack, Unpack; + /** META_PIXEL_TRANSFER */ + GLfloat RedBias, RedScale; + GLfloat GreenBias, GreenScale; + GLfloat BlueBias, BlueScale; + GLfloat AlphaBias, AlphaScale; + GLfloat DepthBias, DepthScale; + GLboolean MapColorFlag; + GLboolean Convolution1DEnabled; + GLboolean Convolution2DEnabled; + GLboolean Separable2DEnabled; + /** META_RASTERIZATION */ GLenum FrontPolygonMode, BackPolygonMode; GLboolean PolygonOffset; @@ -363,6 +397,35 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state) ctx->Unpack = ctx->DefaultPacking; } + if (state & META_PIXEL_TRANSFER) { + save->RedScale = ctx->Pixel.RedScale; + save->RedBias = ctx->Pixel.RedBias; + save->GreenScale = ctx->Pixel.GreenScale; + save->GreenBias = ctx->Pixel.GreenBias; + save->BlueScale = ctx->Pixel.BlueScale; + save->BlueBias = ctx->Pixel.BlueBias; + save->AlphaScale = ctx->Pixel.AlphaScale; + save->AlphaBias = ctx->Pixel.AlphaBias; + save->MapColorFlag = ctx->Pixel.MapColorFlag; + save->Convolution1DEnabled = ctx->Pixel.Convolution1DEnabled; + save->Convolution2DEnabled = ctx->Pixel.Convolution2DEnabled; + save->Separable2DEnabled = ctx->Pixel.Separable2DEnabled; + ctx->Pixel.RedScale = 1.0F; + ctx->Pixel.RedBias = 0.0F; + ctx->Pixel.GreenScale = 1.0F; + ctx->Pixel.GreenBias = 0.0F; + ctx->Pixel.BlueScale = 1.0F; + ctx->Pixel.BlueBias = 0.0F; + ctx->Pixel.AlphaScale = 1.0F; + ctx->Pixel.AlphaBias = 0.0F; + ctx->Pixel.MapColorFlag = GL_FALSE; + ctx->Pixel.Convolution1DEnabled = GL_FALSE; + ctx->Pixel.Convolution2DEnabled = GL_FALSE; + ctx->Pixel.Separable2DEnabled = GL_FALSE; + /* XXX more state */ + ctx->NewState |=_NEW_PIXEL; + } + if (state & META_RASTERIZATION) { save->FrontPolygonMode = ctx->Polygon.FrontMode; save->BackPolygonMode = ctx->Polygon.BackMode; @@ -415,11 +478,6 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state) save->ClientActiveUnit = ctx->Array.ActiveTexture; save->EnvMode = ctx->Texture.Unit[0].EnvMode; - if (ctx->Texture._EnabledUnits | - ctx->Texture._EnabledCoordUnits | - ctx->Texture._TexGenEnabled | - ctx->Texture._TexMatEnabled) { - /* Disable all texture units */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled; @@ -438,7 +496,6 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state) _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE); } } - } /* save current texture objects for unit[0] only */ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { @@ -564,6 +621,23 @@ _mesa_meta_end(GLcontext *ctx) ctx->Unpack = save->Unpack; } + if (state & META_PIXEL_TRANSFER) { + ctx->Pixel.RedScale = save->RedScale; + ctx->Pixel.RedBias = save->RedBias; + ctx->Pixel.GreenScale = save->GreenScale; + ctx->Pixel.GreenBias = save->GreenBias; + ctx->Pixel.BlueScale = save->BlueScale; + ctx->Pixel.BlueBias = save->BlueBias; + ctx->Pixel.AlphaScale = save->AlphaScale; + ctx->Pixel.AlphaBias = save->AlphaBias; + ctx->Pixel.MapColorFlag = save->MapColorFlag; + ctx->Pixel.Convolution1DEnabled = save->Convolution1DEnabled; + ctx->Pixel.Convolution2DEnabled = save->Convolution2DEnabled; + ctx->Pixel.Separable2DEnabled = save->Separable2DEnabled; + /* XXX more state */ + ctx->NewState |=_NEW_PIXEL; + } + if (state & META_RASTERIZATION) { _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); @@ -2037,3 +2111,231 @@ _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target, /* restore (XXX add to meta_begin/end()? */ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave); } + + +/** + * Determine the GL data type to use for the temporary image read with + * ReadPixels() and passed to Tex[Sub]Image(). + */ +static GLenum +get_temp_image_type(GLcontext *ctx, GLenum baseFormat) +{ + switch (baseFormat) { + case GL_RGBA: + case GL_RGB: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + if (ctx->DrawBuffer->Visual.redBits <= 8) + return GL_UNSIGNED_BYTE; + else if (ctx->DrawBuffer->Visual.redBits <= 8) + return GL_UNSIGNED_SHORT; + else + return GL_FLOAT; + case GL_DEPTH_COMPONENT: + return GL_UNSIGNED_INT; + case GL_DEPTH_STENCIL: + return GL_UNSIGNED_INT_24_8; + default: + _mesa_problem(ctx, "Unexpected format in get_temp_image_type()"); + return 0; + } +} + + +/** + * Helper for _mesa_meta_CopyTexImage1/2D() functions. + * Have to be careful with locking and meta state for pixel transfer. + */ +static void +copy_tex_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLenum format, type; + GLint bpp; + void *buf; + + texUnit = _mesa_get_current_tex_unit(ctx); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + + format = _mesa_base_tex_format(ctx, internalFormat); + type = get_temp_image_type(ctx, format); + bpp = _mesa_bytes_per_pixel(format, type); + if (bpp <= 0) { + _mesa_problem(ctx, "Bad bpp in meta copy_tex_image()"); + return; + } + + /* + * Alloc image buffer (XXX could use a PBO) + */ + buf = _mesa_malloc(width * height * bpp); + if (!buf) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); + return; + } + + _mesa_unlock_texture(ctx, texObj); /* need to unlock first */ + + /* + * Read image from framebuffer (disable pixel transfer ops) + */ + _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER); + ctx->Driver.ReadPixels(ctx, x, y, width, height, + format, type, &ctx->Pack, buf); + _mesa_meta_end(ctx); + + /* + * Store texture data (with pixel transfer ops) + */ + _mesa_meta_begin(ctx, META_PIXEL_STORE); + if (target == GL_TEXTURE_1D) { + ctx->Driver.TexImage1D(ctx, target, level, internalFormat, + width, border, format, type, + buf, &ctx->Unpack, texObj, texImage); + } + else { + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, format, type, + buf, &ctx->Unpack, texObj, texImage); + } + _mesa_meta_end(ctx); + + _mesa_lock_texture(ctx, texObj); /* re-lock */ + + _mesa_free(buf); +} + + +void +_mesa_meta_CopyTexImage1D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLint border) +{ + copy_tex_image(ctx, 1, target, level, internalFormat, x, y, + width, 1, border); +} + + +void +_mesa_meta_CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) +{ + copy_tex_image(ctx, 2, target, level, internalFormat, x, y, + width, height, border); +} + + + +/** + * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. + * Have to be careful with locking and meta state for pixel transfer. + */ +static void +copy_tex_sub_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLenum format, type; + GLint bpp; + void *buf; + + texUnit = _mesa_get_current_tex_unit(ctx); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + format = texImage->TexFormat->BaseFormat; + type = get_temp_image_type(ctx, format); + bpp = _mesa_bytes_per_pixel(format, type); + if (bpp <= 0) { + _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()"); + return; + } + + /* + * Alloc image buffer (XXX could use a PBO) + */ + buf = _mesa_malloc(width * height * bpp); + if (!buf) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims); + return; + } + + _mesa_unlock_texture(ctx, texObj); /* need to unlock first */ + + /* + * Read image from framebuffer (disable pixel transfer ops) + */ + _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER); + ctx->Driver.ReadPixels(ctx, x, y, width, height, + format, type, &ctx->Pack, buf); + _mesa_meta_end(ctx); + + /* + * Store texture data (with pixel transfer ops) + */ + _mesa_meta_begin(ctx, META_PIXEL_STORE); + if (target == GL_TEXTURE_1D) { + ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, + width, format, type, buf, + &ctx->Unpack, texObj, texImage); + } + else if (target == GL_TEXTURE_3D) { + ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset, + width, height, 1, format, type, buf, + &ctx->Unpack, texObj, texImage); + } + else { + ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset, + width, height, format, type, buf, + &ctx->Unpack, texObj, texImage); + } + _mesa_meta_end(ctx); + + _mesa_lock_texture(ctx, texObj); /* re-lock */ + + _mesa_free(buf); +} + + +void +_mesa_meta_CopyTexSubImage1D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, + GLint x, GLint y, GLsizei width) +{ + copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0, + x, y, width, 1); +} + + +void +_mesa_meta_CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0, + x, y, width, height); +} + + +void +_mesa_meta_CopyTexSubImage3D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset, + x, y, width, height); +} diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h index 171ad27f265..9f7100f09c1 100644 --- a/src/mesa/drivers/common/meta.h +++ b/src/mesa/drivers/common/meta.h @@ -27,29 +27,6 @@ #define META_H -/** - * Flags passed to _mesa_meta_begin(). - * XXX these flags may evolve... - */ -/*@{*/ -#define META_ALPHA_TEST 0x1 -#define META_BLEND 0x2 /**< includes logicop */ -#define META_COLOR_MASK 0x4 -#define META_DEPTH_TEST 0x8 -#define META_FOG 0x10 -#define META_RASTERIZATION 0x20 -#define META_SCISSOR 0x40 -#define META_SHADER 0x80 -#define META_STENCIL_TEST 0x100 -#define META_TRANSFORM 0x200 /**< modelview, projection */ -#define META_TEXTURE 0x400 -#define META_VERTEX 0x800 -#define META_VIEWPORT 0x1000 -#define META_PIXEL_STORE 0x2000 -#define META_ALL ~0x0 -/*@}*/ - - extern void _mesa_meta_init(GLcontext *ctx); @@ -87,5 +64,32 @@ extern void _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj); +extern void +_mesa_meta_CopyTexImage1D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLint border); + +extern void +_mesa_meta_CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border); + +extern void +_mesa_meta_CopyTexSubImage1D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, + GLint x, GLint y, GLsizei width); + +extern void +_mesa_meta_CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); + +extern void +_mesa_meta_CopyTexSubImage3D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); + #endif /* META_H */ diff --git a/src/mesa/drivers/dri/ffb/ffb_tex.c b/src/mesa/drivers/dri/ffb/ffb_tex.c index 69d30aedbaf..95058e9069f 100644 --- a/src/mesa/drivers/dri/ffb/ffb_tex.c +++ b/src/mesa/drivers/dri/ffb/ffb_tex.c @@ -30,24 +30,6 @@ #include "ffb_tex.h" /* No texture unit, all software. */ -/* XXX this function isn't needed since _mesa_init_driver_functions() - * will make all these assignments. - */ void ffbDDInitTexFuncs(GLcontext *ctx) { - /* - ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; - ctx->Driver.TexImage1D = _mesa_store_teximage1d; - ctx->Driver.TexImage2D = _mesa_store_teximage2d; - ctx->Driver.TexImage3D = _mesa_store_teximage3d; - ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; - ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; - ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; - ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; - ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; - ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; - ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; - ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; - ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; - */ } diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index bce23724b38..9efe6a277c7 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -170,6 +170,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) } DBG("\n"); } + intelFlush(&intel->ctx); _mesa_meta_clear(&intel->ctx, tri_mask); } diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 7e21b94acc4..03db8b1c68e 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -587,11 +587,6 @@ intelInitDriverFunctions(struct dd_function_table *functions) functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; - functions->CopyColorTable = _swrast_CopyColorTable; - functions->CopyColorSubTable = _swrast_CopyColorSubTable; - functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; - functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; - intelInitTextureFuncs(functions); intelInitTextureImageFuncs(functions); intelInitTextureSubImageFuncs(functions); @@ -922,6 +917,14 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv) { + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + + /* Deassociate the context with the drawables. + */ + intel->driDrawable = NULL; + intel->driReadDrawable = NULL; + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c index fe986092db6..237754d4695 100644 --- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -223,10 +223,6 @@ fail: * * The texture object's miptree must be mapped. * - * It would be really nice if this was just called by Mesa whenever mipmaps - * needed to be regenerated, rather than us having to remember to do so in - * each texture image modification path. - * * This function should also include an accelerated path. */ void diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index 1e739434577..28eabbc0054 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -448,24 +448,22 @@ intel_map_unmap_framebuffer(struct intel_context *intel, struct gl_framebuffer *fb, GLboolean map) { - GLcontext *ctx = &intel->ctx; - GLuint i, j; - - /* color buffers */ - if (fb == ctx->DrawBuffer) { - for (j = 0; j < fb->_NumColorDrawBuffers; j++) { - if (map) - intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[j]); - else - intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[j]); - } - } else { + GLuint i; + + /* color draw buffers */ + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { if (map) - intel_renderbuffer_map(intel, fb->_ColorReadBuffer); + intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]); else - intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer); + intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[i]); } + /* color read buffer */ + if (map) + intel_renderbuffer_map(intel, fb->_ColorReadBuffer); + else + intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer); + /* check for render to textures */ for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = @@ -484,20 +482,17 @@ intel_map_unmap_framebuffer(struct intel_context *intel, /* depth buffer (Note wrapper!) */ if (fb->_DepthBuffer) { if (map) - intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped); + intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped); else - intel_renderbuffer_unmap(intel, - fb->_DepthBuffer->Wrapped); + intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped); } /* stencil buffer (Note wrapper!) */ if (fb->_StencilBuffer) { if (map) - intel_renderbuffer_map(intel, - fb->_StencilBuffer->Wrapped); + intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped); else - intel_renderbuffer_unmap(intel, - fb->_StencilBuffer->Wrapped); + intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped); } } @@ -524,7 +519,8 @@ intelSpanRenderStart(GLcontext * ctx) } intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE); - intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE); + if (ctx->ReadBuffer != ctx->DrawBuffer) + intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE); } /** @@ -547,7 +543,8 @@ intelSpanRenderFinish(GLcontext * ctx) } intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE); - intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE); + if (ctx->ReadBuffer != ctx->DrawBuffer) + intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE); UNLOCK_HARDWARE(intel); } diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 028b49c14d3..148e8c048c7 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -90,7 +90,6 @@ do_copy_texsubimage(struct intel_context *intel, GLint x, GLint y, GLsizei width, GLsizei height) { GLcontext *ctx = &intel->ctx; - struct gl_texture_object *texObj = intelImage->base.TexObject; const struct intel_region *src = get_teximage_source(intel, internalFormat); @@ -170,11 +169,6 @@ do_copy_texsubimage(struct intel_context *intel, UNLOCK_HARDWARE(intel); - /* GL_SGIS_generate_mipmap */ - if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } - return GL_TRUE; } diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index a206fe6805b..66201b1f465 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -546,11 +546,6 @@ intelTexImage(GLcontext * ctx, } UNLOCK_HARDWARE(intel); - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } } diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index 89037073f84..751ec2c98c2 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -129,11 +129,6 @@ intelTexSubimage(GLcontext * ctx, } UNLOCK_HARDWARE(intel); - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } } diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 42635bf9d90..fbce70c37bc 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -55,8 +55,7 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) X86_SOURCES = -DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200 \ - -Wall +DRIVER_DEFINES = -DRADEON_R200 -Wall DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 5d8d6f66589..fe775eac99a 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -62,8 +62,7 @@ DRIVER_SOURCES = \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -DRIVER_DEFINES = -DCOMPILE_R300 -DR200_MERGED=0 \ - -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 \ +DRIVER_DEFINES = -DRADEON_R300 # -DRADEON_BO_TRACK \ -Wall diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 250570f6b89..da4812d3234 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -51,26 +51,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" -#if R200_MERGED -extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode); - -#define FALLBACK( radeon, bit, mode ) do { \ - if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \ - __FUNCTION__, bit, mode ); \ - radeonFallback( (radeon)->glCtx, bit, mode ); \ -} while (0) -#else #define FALLBACK( radeon, bit, mode ) fprintf(stderr, "%s:%s\n", __LINE__, __FILE__); -#endif /* TCL fallbacks */ extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode); -#if R200_MERGED -#define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode ) -#else #define TCL_FALLBACK( ctx, bit, mode ) ; -#endif #endif /* __RADEON_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile index d925a2dfe39..36bf773c054 100644 --- a/src/mesa/drivers/dri/r600/Makefile +++ b/src/mesa/drivers/dri/r600/Makefile @@ -65,8 +65,7 @@ DRIVER_SOURCES = \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -DRIVER_DEFINES = -DCOMPILE_R600 -DR200_MERGED=0 \ - -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R600 \ +DRIVER_DEFINES = -DRADEON_R600 \ # -DRADEON_BO_TRACK \ -Wall diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 07a7bcf11f1..f8fd9c13d77 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -385,9 +385,6 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual, if (driQueryOptionb(&r600->radeon.optionCache, "no_rast")) { radeon_warning("disabling 3D acceleration\n"); -#if R200_MERGED - FALLBACK(&r600->radeon, RADEON_FALLBACK_DISABLE, 1); -#endif } return GL_TRUE; diff --git a/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h b/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h index 9d5aa3c7e49..edd85b0facc 100644 --- a/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h +++ b/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h @@ -1366,6 +1366,7 @@ enum { DB_DEPTH_INFO__READ_SIZE_bit = 1 << 3, DB_DEPTH_INFO__ARRAY_MODE_mask = 0x0f << 15, DB_DEPTH_INFO__ARRAY_MODE_shift = 15, + ARRAY_1D_TILED_THIN1 = 0x02, ARRAY_2D_TILED_THIN1 = 0x04, TILE_SURFACE_ENABLE_bit = 1 << 25, TILE_COMPACT_bit = 1 << 26, @@ -1449,6 +1450,7 @@ enum { CB_COLOR0_INFO__ARRAY_MODE_shift = 8, ARRAY_LINEAR_GENERAL = 0x00, ARRAY_LINEAR_ALIGNED = 0x01, +/* ARRAY_1D_TILED_THIN1 = 0x02, */ /* ARRAY_2D_TILED_THIN1 = 0x04, */ NUMBER_TYPE_mask = 0x07 << 12, NUMBER_TYPE_shift = 12, diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index fda66927253..efeccb25f1e 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -3387,6 +3387,7 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) break; case PROGRAM_TEMPORARY: case PROGRAM_INPUT: + default: src_const = GL_FALSE; break; } diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index 1b560591974..06d7e9c9ab1 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -351,7 +351,7 @@ static void r700SetDepthTarget(context_t *context) SETfield(r700->DB_DEPTH_INFO.u32All, DEPTH_16, DB_DEPTH_INFO__FORMAT_shift, DB_DEPTH_INFO__FORMAT_mask); } - SETfield(r700->DB_DEPTH_INFO.u32All, ARRAY_2D_TILED_THIN1, + SETfield(r700->DB_DEPTH_INFO.u32All, ARRAY_1D_TILED_THIN1, DB_DEPTH_INFO__ARRAY_MODE_shift, DB_DEPTH_INFO__ARRAY_MODE_mask); /* r700->DB_PREFETCH_LIMIT.bits.DEPTH_HEIGHT_TILE_MAX = (context->currentDraw->h >> 3) - 1; */ /* z buffer sie may much bigger than what need, so use actual used h. */ } diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index 8c2b0071df9..9ee26286d9b 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -42,6 +42,7 @@ #include "radeon_debug.h" #include "r600_context.h" #include "r600_cmdbuf.h" +#include "shader/programopt.c" #include "r700_debug.h" #include "r700_vertprog.h" @@ -272,6 +273,11 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, vp = _mesa_calloc(sizeof(*vp)); vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base); + if (mesa_vp->IsPositionInvariant) + { + _mesa_insert_mvp_code(ctx, vp->mesa_program); + } + for(i=0; i<VERT_ATTRIB_MAX; i++) { unBit = 1 << i; @@ -290,21 +296,21 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, //Init_Program Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) ); - Map_Vertex_Program( vp, mesa_vp ); + Map_Vertex_Program( vp, vp->mesa_program ); - if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, mesa_vp)) + if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program)) { return NULL; } - if(GL_FALSE == AssembleInstr(mesa_vp->Base.NumInstructions, - &(mesa_vp->Base.Instructions[0]), + if(GL_FALSE == AssembleInstr(vp->mesa_program->Base.NumInstructions, + &(vp->mesa_program->Base.Instructions[0]), &(vp->r700AsmCode)) ) { return NULL; } - if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), mesa_vp->Base.OutputsWritten) ) + if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), vp->mesa_program->Base.OutputsWritten) ) { return NULL; } @@ -329,23 +335,23 @@ void r700SelectVertexShader(GLcontext *ctx) unsigned int unBit; unsigned int i; GLboolean match; + GLbitfield InputsRead; vpc = (struct r700_vertex_program_cont *)ctx->VertexProgram._Current; -#if 0 - if (context->radeon.NewGLState & (_NEW_PROGRAM_CONSTANTS|_NEW_PROGRAM)) + InputsRead = vpc->mesa_program.Base.InputsRead; + if (vpc->mesa_program.IsPositionInvariant) { - vpc->needUpdateVF = 1; - } -#endif - + InputsRead |= VERT_BIT_POS; + } + for (vp = vpc->progs; vp; vp = vp->next) { match = GL_TRUE; for(i=0; i<VERT_ATTRIB_MAX; i++) { unBit = 1 << i; - if(vpc->mesa_program.Base.InputsRead & unBit) + if(InputsRead & unBit) { if (vp->aos_desc[i].size != vb->AttribPtr[i]->size) match = GL_FALSE; diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 1f286776b5f..b1efc72872f 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -47,8 +47,7 @@ C_SOURCES = \ $(DRIVER_SOURCES) \ $(CS_SOURCES) -DRIVER_DEFINES = -DRADEON_COMMON=0 \ - -Wall +DRIVER_DEFINES = -DRADEON_R100 -Wall DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 71ee06d9a79..1c53c04da77 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -47,7 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */ +#if defined(RADEON_R600) #include "r600_context.h" #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 2eefa3f2b1b..c9a32c808be 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -263,7 +263,7 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa, void radeonFreeDmaRegions(radeonContextPtr rmesa) { - struct radeon_dma_bo *dma_bo = CALLOC_STRUCT(radeon_dma_bo); + struct radeon_dma_bo *dma_bo; struct radeon_dma_bo *temp; if (RADEON_DEBUG & RADEON_DMA) fprintf(stderr, "%s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 5ffb55db5ef..573eb6c9c18 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -48,17 +48,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" #include "radeon_common.h" #include "radeon_span.h" -#if !RADEON_COMMON +#if defined(RADEON_R100) #include "radeon_context.h" #include "radeon_tex.h" -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R200) #include "r200_context.h" #include "r200_ioctl.h" #include "r200_tex.h" -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +#elif defined(RADEON_R300) #include "r300_context.h" #include "r300_tex.h" -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) +#elif defined(RADEON_R600) #include "r600_context.h" #include "r700_driconf.h" /* +r6/r7 */ #include "r600_tex.h" /* +r6/r7 */ @@ -82,7 +82,7 @@ DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \ DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \ DRI_CONF_OPT_END -#if !RADEON_COMMON /* R100 */ +#if defined(RADEON_R100) /* R100 */ PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE @@ -109,7 +109,7 @@ DRI_CONF_BEGIN DRI_CONF_END; static const GLuint __driNConfigOptions = 15; -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R200) PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -147,7 +147,7 @@ extern const struct dri_extension NV_vp_extension[]; extern const struct dri_extension ATI_fs_extension[]; extern const struct dri_extension point_extensions[]; -#elif RADEON_COMMON && (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600)) +#elif defined(RADEON_R300) || defined(RADEON_R600) #define DRI_CONF_FP_OPTIMIZATION_SPEED 0 #define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 @@ -220,7 +220,7 @@ static const GLuint __driNConfigOptions = 17; extern const struct dri_extension gl_20_extension[]; -#endif /* RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) */ +#endif extern const struct dri_extension card_extensions[]; extern const struct dri_extension mm_extensions[]; @@ -337,7 +337,7 @@ radeonFillInModes( __DRIscreenPrivate *psp, return (const __DRIconfig **) configs; } -#if !RADEON_COMMON +#if defined(RADEON_R100) static const __DRItexOffsetExtension radeonTexOffsetExtension = { { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, radeonSetTexOffset, @@ -350,7 +350,7 @@ static const __DRItexBufferExtension radeonTexBufferExtension = { }; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) static const __DRIallocateExtension r200AllocateExtension = { { __DRI_ALLOCATE, __DRI_ALLOCATE_VERSION }, r200AllocateMemoryMESA, @@ -370,7 +370,7 @@ static const __DRItexBufferExtension r200TexBufferExtension = { }; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +#if defined(RADEON_R300) static const __DRItexOffsetExtension r300texOffsetExtension = { { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, r300SetTexOffset, @@ -383,7 +383,7 @@ static const __DRItexBufferExtension r300TexBufferExtension = { }; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) +#if defined(RADEON_R600) static const __DRItexOffsetExtension r600texOffsetExtension = { { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, r600SetTexOffset, /* +r6/r7 */ @@ -1222,22 +1222,22 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->extensions[i++] = &driMediaStreamCounterExtension.base; } -#if !RADEON_COMMON +#if defined(RADEON_R100) screen->extensions[i++] = &radeonTexOffsetExtension.base; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) if (IS_R200_CLASS(screen)) screen->extensions[i++] = &r200AllocateExtension.base; screen->extensions[i++] = &r200texOffsetExtension.base; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +#if defined(RADEON_R300) screen->extensions[i++] = &r300texOffsetExtension.base; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) +#if defined(RADEON_R600) screen->extensions[i++] = &r600texOffsetExtension.base; #endif @@ -1376,22 +1376,22 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv) screen->extensions[i++] = &driMediaStreamCounterExtension.base; } -#if !RADEON_COMMON +#if defined(RADEON_R100) screen->extensions[i++] = &radeonTexBufferExtension.base; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) if (IS_R200_CLASS(screen)) screen->extensions[i++] = &r200AllocateExtension.base; screen->extensions[i++] = &r200TexBufferExtension.base; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +#if defined(RADEON_R300) screen->extensions[i++] = &r300TexBufferExtension.base; #endif -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) +#if defined(RADEON_R600) screen->extensions[i++] = &r600TexBufferExtension.base; #endif @@ -1589,22 +1589,22 @@ radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) static const __DRIconfig ** radeonInitScreen(__DRIscreenPrivate *psp) { -#if !RADEON_COMMON +#if defined(RADEON_R100) static const char *driver_name = "Radeon"; static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 6, 0 }; -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R200) static const char *driver_name = "R200"; static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 6, 0 }; -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +#elif defined(RADEON_R300) static const char *driver_name = "R300"; static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 24, 0 }; -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) +#elif defined(RADEON_R600) static const char *driver_name = "R600"; static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; @@ -1630,13 +1630,13 @@ radeonInitScreen(__DRIscreenPrivate *psp) * Hello chicken. Hello egg. How are you two today? */ driInitExtensions( NULL, card_extensions, GL_FALSE ); -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) driInitExtensions( NULL, blend_extensions, GL_FALSE ); driInitSingleExtension( NULL, ARB_vp_extension ); driInitSingleExtension( NULL, NV_vp_extension ); driInitSingleExtension( NULL, ATI_fs_extension ); driInitExtensions( NULL, point_extensions, GL_FALSE ); -#elif (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600)) +#elif (defined(RADEON_R300) || defined(RADEON_R600)) driInitSingleExtension( NULL, gl_20_extension ); #endif @@ -1684,13 +1684,13 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) */ driInitExtensions( NULL, card_extensions, GL_FALSE ); driInitExtensions( NULL, mm_extensions, GL_FALSE ); -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) driInitExtensions( NULL, blend_extensions, GL_FALSE ); driInitSingleExtension( NULL, ARB_vp_extension ); driInitSingleExtension( NULL, NV_vp_extension ); driInitSingleExtension( NULL, ATI_fs_extension ); driInitExtensions( NULL, point_extensions, GL_FALSE ); -#elif (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600)) +#elif (defined(RADEON_R300) || defined(RADEON_R600)) driInitSingleExtension( NULL, gl_20_extension ); #endif @@ -1772,13 +1772,13 @@ getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) const struct __DriverAPIRec driDriverAPI = { .InitScreen = radeonInitScreen, .DestroyScreen = radeonDestroyScreen, -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) .CreateContext = r200CreateContext, .DestroyContext = r200DestroyContext, -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) +#elif defined(RADEON_R600) .CreateContext = r600CreateContext, .DestroyContext = radeonDestroyContext, -#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +#elif defined(RADEON_R300) .CreateContext = r300CreateContext, .DestroyContext = radeonDestroyContext, #else diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 4e100d854ed..0c49c3713af 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -55,7 +55,7 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); /* r200 depth buffer is always tiled - this is the formula according to the docs unless I typo'ed in it */ -#if defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { @@ -106,6 +106,141 @@ static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb, } #endif +/* r600 tiling + * two main types: + * - 1D (akin to macro-linear/micro-tiled on older asics) + * - 2D (akin to macro-tiled/micro-tiled on older asics) + * only 1D tiling is implemented below + */ +#if defined(RADEON_R600) +static inline GLint r600_1d_tile_helper(const struct radeon_renderbuffer * rrb, + GLint x, GLint y, GLint is_depth, GLint is_stencil) +{ + GLint element_bytes = rrb->cpp; + GLint num_samples = 1; + GLint tile_width = 8; + GLint tile_height = 8; + GLint tile_thickness = 1; + GLint pitch_elements = rrb->pitch / element_bytes; + GLint height = rrb->base.Height; + GLint z = 0; + GLint sample_number = 0; + /* */ + GLint tile_bytes; + GLint tiles_per_row; + GLint tiles_per_slice; + GLint slice_offset; + GLint tile_row_index; + GLint tile_column_index; + GLint tile_offset; + GLint pixel_number = 0; + GLint element_offset; + GLint offset = 0; + + tile_bytes = tile_width * tile_height * tile_thickness * element_bytes * num_samples; + tiles_per_row = pitch_elements / tile_width; + tiles_per_slice = tiles_per_row * (height / tile_height); + slice_offset = (z / tile_thickness) * tiles_per_slice * tile_bytes; + tile_row_index = y / tile_height; + tile_column_index = x / tile_width; + tile_offset = ((tile_row_index * tiles_per_row) + tile_column_index) * tile_bytes; + + if (is_depth) { + GLint pixel_offset = 0; + + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((y >> 0) & 1) << 1; // pn[1] = y[0] + pixel_number |= ((x >> 1) & 1) << 2; // pn[2] = x[1] + pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1] + pixel_number |= ((x >> 2) & 1) << 4; // pn[4] = x[2] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + switch (element_bytes) { + case 2: + pixel_offset = pixel_number * element_bytes * num_samples; + break; + case 4: + /* stencil and depth data are stored separately within a tile. + * stencil is stored in a contiguous tile before the depth tile. + * stencil element is 1 byte, depth element is 3 bytes. + * stencil tile is 64 bytes. + */ + if (is_stencil) + pixel_offset = pixel_number * 1 * num_samples; + else + pixel_offset = (pixel_number * 3 * num_samples) + 64; + break; + } + element_offset = pixel_offset + (sample_number * element_bytes); + } else { + GLint sample_offset; + + switch (element_bytes) { + case 1: + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1] + pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2] + pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1] + pixel_number |= ((y >> 0) & 1) << 4; // pn[4] = y[0] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + break; + case 2: + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1] + pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2] + pixel_number |= ((y >> 0) & 1) << 3; // pn[3] = y[0] + pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + break; + case 4: + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1] + pixel_number |= ((y >> 0) & 1) << 2; // pn[2] = y[0] + pixel_number |= ((x >> 2) & 1) << 3; // pn[3] = x[2] + pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + break; + } + sample_offset = sample_number * (tile_bytes / num_samples); + element_offset = sample_offset + (pixel_number * element_bytes); + } + offset = slice_offset + tile_offset + element_offset; + return offset; +} + +/* depth buffers */ +static GLubyte *r600_ptr_depth(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + GLint offset = r600_1d_tile_helper(rrb, x, y, 1, 0); + return &ptr[offset]; +} + +static GLubyte *r600_ptr_stencil(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + GLint offset = r600_1d_tile_helper(rrb, x, y, 1, 1); + return &ptr[offset]; +} + +static GLubyte *r600_ptr_color(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = r600_1d_tile_helper(rrb, x, y, 0, 0); + } + return &ptr[offset]; +} + +#else + /* radeon tiling on r300-r500 has 4 states, macro-linear/micro-linear macro-linear/micro-tiled @@ -197,7 +332,10 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, return &ptr[offset]; } -#ifndef COMPILE_R300 +#endif + +#ifndef RADEON_R300 +#ifndef RADEON_R600 static uint32_t z24s8_to_s8z24(uint32_t val) { @@ -210,6 +348,7 @@ s8z24_to_z24s8(uint32_t val) return (val >> 24) | (val << 8); } #endif +#endif /* * Note that all information needed to access pixels in a renderbuffer @@ -270,7 +409,11 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#endif #include "spantmp2.h" /* 16 bit, ARGB1555 color spanline and pixel functions @@ -280,7 +423,11 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_ARGB1555 #define TAG2(x,y) radeon##x##_ARGB1555##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#endif #include "spantmp2.h" /* 16 bit, RGBA4 color spanline and pixel functions @@ -290,7 +437,11 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_ARGB4444 #define TAG2(x,y) radeon##x##_ARGB4444##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#endif #include "spantmp2.h" /* 32 bit, xRGB8888 color spanline and pixel functions @@ -300,11 +451,19 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_xRGB8888 #define TAG2(x,y) radeon##x##_xRGB8888##y +#if defined(RADEON_R600) +#define GET_VALUE(_x, _y) ((*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off)) | 0xff000000)) +#define PUT_VALUE(_x, _y, d) { \ + GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off ); \ + *_ptr = d; \ +} while (0) +#else #define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0xff000000)) #define PUT_VALUE(_x, _y, d) { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ *_ptr = d; \ } while (0) +#endif #include "spantmp2.h" /* 32 bit, ARGB8888 color spanline and pixel functions @@ -314,11 +473,19 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y +#if defined(RADEON_R600) +#define GET_VALUE(_x, _y) (*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))) +#define PUT_VALUE(_x, _y, d) { \ + GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off ); \ + *_ptr = d; \ +} while (0) +#else #define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) #define PUT_VALUE(_x, _y, d) { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ *_ptr = d; \ } while (0) +#endif #include "spantmp2.h" /* ================================================================ @@ -339,17 +506,23 @@ s8z24_to_z24s8(uint32_t val) */ #define VALUE_TYPE GLushort -#if defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) #define WRITE_DEPTH( _x, _y, d ) \ *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off) = d +#elif defined(RADEON_R600) +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)r600_ptr_depth(rrb, _x + x_off, _y + y_off) = d #else #define WRITE_DEPTH( _x, _y, d ) \ *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d #endif -#if defined(RADEON_COMMON_FOR_R200) +#if defined(RADEON_R200) #define READ_DEPTH( d, _x, _y ) \ d = *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off) +#elif defined(RADEON_R600) +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)r600_ptr_depth(rrb, _x + x_off, _y + y_off) #else #define READ_DEPTH( d, _x, _y ) \ d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) @@ -365,7 +538,7 @@ s8z24_to_z24s8(uint32_t val) */ #define VALUE_TYPE GLuint -#if defined(COMPILE_R300) +#if defined(RADEON_R300) #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ @@ -374,7 +547,16 @@ do { \ tmp |= ((d << 8) & 0xffffff00); \ *_ptr = tmp; \ } while (0) -#elif defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R600) +#define WRITE_DEPTH( _x, _y, d ) \ +do { \ + GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off ); \ + GLuint tmp = *_ptr; \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *_ptr = tmp; \ +} while (0) +#elif defined(RADEON_R200) #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \ @@ -394,12 +576,17 @@ do { \ } while (0) #endif -#if defined(COMPILE_R300) +#if defined(RADEON_R300) #define READ_DEPTH( d, _x, _y ) \ do { \ d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \ }while(0) -#elif defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R600) +#define READ_DEPTH( d, _x, _y ) \ + do { \ + d = (*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off)) & 0x00ffffff); \ + }while(0) +#elif defined(RADEON_R200) #define READ_DEPTH( d, _x, _y ) \ do { \ d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; \ @@ -420,13 +607,27 @@ do { \ */ #define VALUE_TYPE GLuint -#if defined(COMPILE_R300) +#if defined(RADEON_R300) #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ *_ptr = d; \ } while (0) -#elif defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R600) +#define WRITE_DEPTH( _x, _y, d ) \ +do { \ + GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off ); \ + GLuint tmp = *_ptr; \ + tmp &= 0xff000000; \ + tmp |= (((d) >> 8) & 0x00ffffff); \ + *_ptr = tmp; \ + _ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off); \ + tmp = *_ptr; \ + tmp &= 0xffffff00; \ + tmp |= (d) & 0xff; \ + *_ptr = tmp; \ +} while (0) +#elif defined(RADEON_R200) #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \ @@ -442,12 +643,18 @@ do { \ } while (0) #endif -#if defined(COMPILE_R300) +#if defined(RADEON_R300) #define READ_DEPTH( d, _x, _y ) \ do { \ d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \ }while(0) -#elif defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R600) +#define READ_DEPTH( d, _x, _y ) \ + do { \ + d = ((*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off))) << 8) & 0xffffff00; \ + d |= (*(GLuint*)(r600_ptr_stencil(rrb, _x + x_off, _y + y_off))) & 0x000000ff; \ + }while(0) +#elif defined(RADEON_R200) #define READ_DEPTH( d, _x, _y ) \ do { \ d = s8z24_to_z24s8(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \ @@ -467,7 +674,7 @@ do { \ /* 24 bit depth, 8 bit stencil depthbuffer functions */ -#ifdef COMPILE_R300 +#ifdef RADEON_R300 #define WRITE_STENCIL( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \ @@ -476,7 +683,16 @@ do { \ tmp |= (d) & 0xff; \ *_ptr = tmp; \ } while (0) -#elif defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R600) +#define WRITE_STENCIL( _x, _y, d ) \ +do { \ + GLuint *_ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off); \ + GLuint tmp = *_ptr; \ + tmp &= 0xffffff00; \ + tmp |= (d) & 0xff; \ + *_ptr = tmp; \ +} while (0) +#elif defined(RADEON_R200) #define WRITE_STENCIL( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off); \ @@ -496,14 +712,21 @@ do { \ } while (0) #endif -#ifdef COMPILE_R300 +#ifdef RADEON_R300 #define READ_STENCIL( d, _x, _y ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ d = tmp & 0x000000ff; \ } while (0) -#elif defined(RADEON_COMMON_FOR_R200) +#elif defined(RADEON_R600) +#define READ_STENCIL( d, _x, _y ) \ +do { \ + GLuint *_ptr = (GLuint*)r600_ptr_stencil( rrb, _x + x_off, _y + y_off ); \ + GLuint tmp = *_ptr; \ + d = tmp & 0x000000ff; \ +} while (0) +#elif defined(RADEON_R200) #define READ_STENCIL( d, _x, _y ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \ diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c index 9d252aa74c5..ae41b90efe5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texstate.c +++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c @@ -833,11 +833,14 @@ static void import_tex_obj_state( r100ContextPtr rmesa, cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; - if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) { - GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] ); + if (texobj->pp_txformat & RADEON_TXFORMAT_NON_POWER2) { + uint32_t *txr_cmd = &rmesa->hw.txr[unit].cmd[TXR_CMD_0]; txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */ txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */ - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] ); + RADEON_STATECHANGE( rmesa, txr[unit] ); + } + + if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) { se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit; } else { @@ -1114,7 +1117,6 @@ static GLboolean radeon_validate_texture(GLcontext *ctx, struct gl_texture_objec RADEON_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; - RADEON_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit); diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index fad3d1cedaf..049284ef8c5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -659,11 +659,6 @@ static void radeon_teximage( if (dims == 3) _mesa_free(dstImageOffsets); } - - /* SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, target, texObj); - } } _mesa_unmap_teximage_pbo(ctx, packing); @@ -792,11 +787,6 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve format, type, pixels, packing)) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, target, texObj); - } } radeon_teximage_unmap(image); diff --git a/src/mesa/drivers/dri/s3v/s3v_tex.c b/src/mesa/drivers/dri/s3v/s3v_tex.c index 9b92519862a..ec1182f34f7 100644 --- a/src/mesa/drivers/dri/s3v/s3v_tex.c +++ b/src/mesa/drivers/dri/s3v/s3v_tex.c @@ -536,24 +536,13 @@ void s3vInitTextureFuncs( GLcontext *ctx ) #endif ctx->Driver.TexEnv = s3vTexEnv; - ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; - ctx->Driver.TexImage1D = _mesa_store_teximage1d; ctx->Driver.TexImage2D = s3vTexImage2D; - ctx->Driver.TexImage3D = _mesa_store_teximage3d; - ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; ctx->Driver.TexSubImage2D = s3vTexSubImage2D; - ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; - ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; - ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; - ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; - ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; - ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; ctx->Driver.BindTexture = s3vBindTexture; ctx->Driver.DeleteTexture = s3vDeleteTexture; ctx->Driver.TexParameter = s3vTexParameter; ctx->Driver.UpdateTexturePalette = 0; ctx->Driver.IsTextureResident = s3vIsTextureResident; - ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; s3vInitTextureObjects( ctx ); } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index 1f7257eaead..f6a48b3ae12 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -176,6 +176,54 @@ logbase2(int n) } +static void +tdfxGenerateMipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + GLint mipWidth, mipHeight; + tdfxMipMapLevel *mip; + struct gl_texture_image *mipImage; /* the new/next image */ + struct gl_texture_image *texImage; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + GLint level = texObj->BaseLevel; + GLsizei width, height, texelBytes; + const tdfxMipMapLevel *mml; + + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + assert(!texImage->IsCompressed); + + mml = TDFX_TEXIMAGE_DATA(texImage); + + width = texImage->Width; + height = texImage->Height; + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + ++level; + mipImage = _mesa_select_tex_image(ctx, texObj, target, level); + mip = TDFX_TEXIMAGE_DATA(mipImage); + _mesa_halve2x2_teximage2d(ctx, + texImage, + texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } +} + + /* * Compute various texture image parameters. * Input: w, h - source texture width and height @@ -1397,45 +1445,6 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, width, height, 1, format, type, pixels, packing); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - GLint mipWidth, mipHeight; - tdfxMipMapLevel *mip; - struct gl_texture_image *mipImage; - const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); - - assert(!texImage->IsCompressed); - - while (level < texObj->MaxLevel && level < maxLevels - 1) { - mipWidth = width / 2; - if (!mipWidth) { - mipWidth = 1; - } - mipHeight = height / 2; - if (!mipHeight) { - mipHeight = 1; - } - if ((mipWidth == width) && (mipHeight == height)) { - break; - } - _mesa_TexImage2D(target, ++level, internalFormat, - mipWidth, mipHeight, border, - format, type, - NULL); - mipImage = _mesa_select_tex_image(ctx, texObj, target, level); - mip = TDFX_TEXIMAGE_DATA(mipImage); - _mesa_halve2x2_teximage2d(ctx, - texImage, - texelBytes, - mml->width, mml->height, - texImage->Data, mipImage->Data); - texImage = mipImage; - mml = mip; - width = mipWidth; - height = mipHeight; - } - } } RevalidateTexture(ctx, texObj); @@ -1507,44 +1516,6 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, format, type, pixels, packing); } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - GLint mipWidth, mipHeight; - tdfxMipMapLevel *mip; - struct gl_texture_image *mipImage; - const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); - - assert(!texImage->IsCompressed); - - width = texImage->Width; - height = texImage->Height; - while (level < texObj->MaxLevel && level < maxLevels - 1) { - mipWidth = width / 2; - if (!mipWidth) { - mipWidth = 1; - } - mipHeight = height / 2; - if (!mipHeight) { - mipHeight = 1; - } - if ((mipWidth == width) && (mipHeight == height)) { - break; - } - ++level; - mipImage = _mesa_select_tex_image(ctx, texObj, target, level); - mip = TDFX_TEXIMAGE_DATA(mipImage); - _mesa_halve2x2_teximage2d(ctx, - texImage, - texelBytes, - mml->width, mml->height, - texImage->Data, mipImage->Data); - texImage = mipImage; - mml = mip; - width = mipWidth; - height = mipHeight; - } - } - ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */ } @@ -1703,11 +1674,6 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, MEMCPY(texImage->Data, data, texImage->CompressedSize); } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - assert(!texImage->IsCompressed); - } - RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; @@ -1770,11 +1736,6 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target, texImage->Data); } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - assert(!texImage->IsCompressed); - } - RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; @@ -1914,4 +1875,5 @@ void tdfxInitTextureFuncs( struct dd_function_table *functions ) functions->CompressedTexImage2D = tdfxCompressedTexImage2D; functions->CompressedTexSubImage2D = tdfxCompressedTexSubImage2D; functions->UpdateTexturePalette = tdfxUpdateTexturePalette; + functions->GenerateMipmap = tdfxGenerateMipmap; } diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c index d2010f09074..54073e76918 100644 --- a/src/mesa/drivers/dri/unichrome/via_tex.c +++ b/src/mesa/drivers/dri/unichrome/via_tex.c @@ -818,11 +818,6 @@ static void viaTexImage(GLcontext *ctx, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index d721f699fd1..9c25de41871 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -329,6 +329,34 @@ typedef enum OPCODE_STENCIL_OP_SEPARATE, OPCODE_STENCIL_MASK_SEPARATE, + /* GL_ARB_shader_objects */ + OPCODE_USE_PROGRAM, + OPCODE_UNIFORM_1F, + OPCODE_UNIFORM_2F, + OPCODE_UNIFORM_3F, + OPCODE_UNIFORM_4F, + OPCODE_UNIFORM_1FV, + OPCODE_UNIFORM_2FV, + OPCODE_UNIFORM_3FV, + OPCODE_UNIFORM_4FV, + OPCODE_UNIFORM_1I, + OPCODE_UNIFORM_2I, + OPCODE_UNIFORM_3I, + OPCODE_UNIFORM_4I, + OPCODE_UNIFORM_1IV, + OPCODE_UNIFORM_2IV, + OPCODE_UNIFORM_3IV, + OPCODE_UNIFORM_4IV, + OPCODE_UNIFORM_MATRIX22, + OPCODE_UNIFORM_MATRIX33, + OPCODE_UNIFORM_MATRIX44, + OPCODE_UNIFORM_MATRIX23, + OPCODE_UNIFORM_MATRIX32, + OPCODE_UNIFORM_MATRIX24, + OPCODE_UNIFORM_MATRIX42, + OPCODE_UNIFORM_MATRIX34, + OPCODE_UNIFORM_MATRIX43, + /* GL_EXT_framebuffer_blit */ OPCODE_BLIT_FRAMEBUFFER, @@ -576,6 +604,30 @@ _mesa_delete_list(GLcontext *ctx, struct gl_display_list *dlist) n += InstSize[n[0].opcode]; break; #endif + case OPCODE_UNIFORM_1FV: + case OPCODE_UNIFORM_2FV: + case OPCODE_UNIFORM_3FV: + case OPCODE_UNIFORM_4FV: + case OPCODE_UNIFORM_1IV: + case OPCODE_UNIFORM_2IV: + case OPCODE_UNIFORM_3IV: + case OPCODE_UNIFORM_4IV: + _mesa_free(n[3].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_UNIFORM_MATRIX22: + case OPCODE_UNIFORM_MATRIX33: + case OPCODE_UNIFORM_MATRIX44: + case OPCODE_UNIFORM_MATRIX24: + case OPCODE_UNIFORM_MATRIX42: + case OPCODE_UNIFORM_MATRIX23: + case OPCODE_UNIFORM_MATRIX32: + case OPCODE_UNIFORM_MATRIX34: + case OPCODE_UNIFORM_MATRIX43: + _mesa_free(n[4].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_CONTINUE: n = (Node *) n[1].next; _mesa_free(block); @@ -5804,6 +5856,493 @@ save_ProvokingVertexEXT(GLenum mode) } +/* aka UseProgram() */ +static void GLAPIENTRY +save_UseProgramObjectARB(GLhandleARB program) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_USE_PROGRAM, 1); + if (n) { + n[1].ui = program; + } + if (ctx->ExecuteFlag) { + CALL_UseProgramObjectARB(ctx->Exec, (program)); + } +} + + +static void GLAPIENTRY +save_Uniform1fARB(GLint location, GLfloat x) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1F, 2); + if (n) { + n[1].i = location; + n[2].f = x; + } + if (ctx->ExecuteFlag) { + CALL_Uniform1fARB(ctx->Exec, (location, x)); + } +} + + +static void GLAPIENTRY +save_Uniform2fARB(GLint location, GLfloat x, GLfloat y) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2F, 3); + if (n) { + n[1].i = location; + n[2].f = x; + n[3].f = y; + } + if (ctx->ExecuteFlag) { + CALL_Uniform2fARB(ctx->Exec, (location, x, y)); + } +} + + +static void GLAPIENTRY +save_Uniform3fARB(GLint location, GLfloat x, GLfloat y, GLfloat z) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3F, 4); + if (n) { + n[1].i = location; + n[2].f = x; + n[3].f = y; + n[4].f = z; + } + if (ctx->ExecuteFlag) { + CALL_Uniform3fARB(ctx->Exec, (location, x, y, z)); + } +} + + +static void GLAPIENTRY +save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4F, 5); + if (n) { + n[1].i = location; + n[2].f = x; + n[3].f = y; + n[4].f = z; + n[5].f = w; + } + if (ctx->ExecuteFlag) { + CALL_Uniform4fARB(ctx->Exec, (location, x, y, z, w)); + } +} + + +/** Return copy of memory */ +static void * +memdup(const void *src, GLsizei bytes) +{ + void *b = bytes >= 0 ? _mesa_malloc(bytes) : NULL; + if (b) + _mesa_memcpy(b, src, bytes); + return b; +} + + +static void GLAPIENTRY +save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1FV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 1 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform1fvARB(ctx->Exec, (location, count, v)); + } +} + +static void GLAPIENTRY +save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2FV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 2 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform2fvARB(ctx->Exec, (location, count, v)); + } +} + +static void GLAPIENTRY +save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3FV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 3 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform3fvARB(ctx->Exec, (location, count, v)); + } +} + +static void GLAPIENTRY +save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4FV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 4 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform4fvARB(ctx->Exec, (location, count, v)); + } +} + + +static void GLAPIENTRY +save_Uniform1iARB(GLint location, GLint x) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1I, 2); + if (n) { + n[1].i = location; + n[2].i = x; + } + if (ctx->ExecuteFlag) { + CALL_Uniform1iARB(ctx->Exec, (location, x)); + } +} + +static void GLAPIENTRY +save_Uniform2iARB(GLint location, GLint x, GLint y) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2I, 3); + if (n) { + n[1].i = location; + n[2].i = x; + n[3].i = y; + } + if (ctx->ExecuteFlag) { + CALL_Uniform2iARB(ctx->Exec, (location, x, y)); + } +} + +static void GLAPIENTRY +save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3I, 4); + if (n) { + n[1].i = location; + n[2].i = x; + n[3].i = y; + n[4].i = z; + } + if (ctx->ExecuteFlag) { + CALL_Uniform3iARB(ctx->Exec, (location, x, y, z)); + } +} + +static void GLAPIENTRY +save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4I, 5); + if (n) { + n[1].i = location; + n[2].i = x; + n[3].i = y; + n[4].i = z; + n[5].i = w; + } + if (ctx->ExecuteFlag) { + CALL_Uniform4iARB(ctx->Exec, (location, x, y, z, w)); + } +} + + + +static void GLAPIENTRY +save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1IV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 1 * sizeof(GLint)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform1ivARB(ctx->Exec, (location, count, v)); + } +} + +static void GLAPIENTRY +save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2IV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 2 * sizeof(GLint)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform2ivARB(ctx->Exec, (location, count, v)); + } +} + +static void GLAPIENTRY +save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3IV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 3 * sizeof(GLint)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform3ivARB(ctx->Exec, (location, count, v)); + } +} + +static void GLAPIENTRY +save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4IV, 3); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].data = memdup(v, count * 4 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_Uniform4ivARB(ctx->Exec, (location, count, v)); + } +} + + +static void GLAPIENTRY +save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX22, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 2 * 2 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix2fvARB(ctx->Exec, (location, count, transpose, m)); + } +} + +static void GLAPIENTRY +save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX33, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 3 * 3 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix3fvARB(ctx->Exec, (location, count, transpose, m)); + } +} + +static void GLAPIENTRY +save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX44, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 4 * 4 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix4fvARB(ctx->Exec, (location, count, transpose, m)); + } +} + + +static void GLAPIENTRY +save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX23, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 2 * 3 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix2x3fv(ctx->Exec, (location, count, transpose, m)); + } +} + +static void GLAPIENTRY +save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX32, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 3 * 2 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix3x2fv(ctx->Exec, (location, count, transpose, m)); + } +} + + +static void GLAPIENTRY +save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX24, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 2 * 4 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix2x4fv(ctx->Exec, (location, count, transpose, m)); + } +} + +static void GLAPIENTRY +save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX42, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 4 * 2 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix4x2fv(ctx->Exec, (location, count, transpose, m)); + } +} + + +static void GLAPIENTRY +save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX34, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 3 * 4 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix3x4fv(ctx->Exec, (location, count, transpose, m)); + } +} + +static void GLAPIENTRY +save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *m) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX43, 4); + if (n) { + n[1].i = location; + n[2].i = count; + n[3].b = transpose; + n[4].data = memdup(m, count * 4 * 3 * sizeof(GLfloat)); + } + if (ctx->ExecuteFlag) { + CALL_UniformMatrix4x3fv(ctx->Exec, (location, count, transpose, m)); + } +} + + /** * Save an error-generating command into display list. @@ -6640,6 +7179,98 @@ execute_list(GLcontext *ctx, GLuint list) n[9].i, n[10].e)); break; #endif + + case OPCODE_USE_PROGRAM: + CALL_UseProgramObjectARB(ctx->Exec, (n[1].ui)); + break; + case OPCODE_UNIFORM_1F: + CALL_Uniform1fARB(ctx->Exec, (n[1].i, n[2].f)); + break; + case OPCODE_UNIFORM_2F: + CALL_Uniform2fARB(ctx->Exec, (n[1].i, n[2].f, n[3].f)); + break; + case OPCODE_UNIFORM_3F: + CALL_Uniform3fARB(ctx->Exec, (n[1].i, n[2].f, n[3].f, n[4].f)); + break; + case OPCODE_UNIFORM_4F: + CALL_Uniform4fARB(ctx->Exec, + (n[1].i, n[2].f, n[3].f, n[4].f, n[5].f)); + break; + case OPCODE_UNIFORM_1FV: + CALL_Uniform1fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_2FV: + CALL_Uniform2fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_3FV: + CALL_Uniform3fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_4FV: + CALL_Uniform4fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_1I: + CALL_Uniform1iARB(ctx->Exec, (n[1].i, n[2].i)); + break; + case OPCODE_UNIFORM_2I: + CALL_Uniform2iARB(ctx->Exec, (n[1].i, n[2].i, n[3].i)); + break; + case OPCODE_UNIFORM_3I: + CALL_Uniform3iARB(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); + break; + case OPCODE_UNIFORM_4I: + CALL_Uniform4iARB(ctx->Exec, + (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i)); + break; + case OPCODE_UNIFORM_1IV: + CALL_Uniform1ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_2IV: + CALL_Uniform2ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_3IV: + CALL_Uniform3ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + case OPCODE_UNIFORM_4IV: + CALL_Uniform4ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + break; + + case OPCODE_UNIFORM_MATRIX22: + CALL_UniformMatrix2fvARB(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX33: + CALL_UniformMatrix3fvARB(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX44: + CALL_UniformMatrix4fvARB(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX23: + CALL_UniformMatrix2x3fv(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX32: + CALL_UniformMatrix3x2fv(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX24: + CALL_UniformMatrix2x4fv(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX42: + CALL_UniformMatrix4x2fv(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX34: + CALL_UniformMatrix3x4fv(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_UNIFORM_MATRIX43: + CALL_UniformMatrix4x3fv(ctx->Exec, + (n[1].i, n[2].i, n[3].b, n[4].data)); + break; + case OPCODE_TEX_BUMP_PARAMETER_ATI: { GLfloat values[4]; @@ -8309,6 +8940,34 @@ _mesa_init_dlist_table(struct _glapi_table *table) SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT); #endif + /* GL_ARB_shader_objects */ + SET_UseProgramObjectARB(table, save_UseProgramObjectARB); + SET_Uniform1fARB(table, save_Uniform1fARB); + SET_Uniform2fARB(table, save_Uniform2fARB); + SET_Uniform3fARB(table, save_Uniform3fARB); + SET_Uniform4fARB(table, save_Uniform4fARB); + SET_Uniform1fvARB(table, save_Uniform1fvARB); + SET_Uniform2fvARB(table, save_Uniform2fvARB); + SET_Uniform3fvARB(table, save_Uniform3fvARB); + SET_Uniform4fvARB(table, save_Uniform4fvARB); + SET_Uniform1iARB(table, save_Uniform1iARB); + SET_Uniform2iARB(table, save_Uniform2iARB); + SET_Uniform3iARB(table, save_Uniform3iARB); + SET_Uniform4iARB(table, save_Uniform4iARB); + SET_Uniform1ivARB(table, save_Uniform1ivARB); + SET_Uniform2ivARB(table, save_Uniform2ivARB); + SET_Uniform3ivARB(table, save_Uniform3ivARB); + SET_Uniform4ivARB(table, save_Uniform4ivARB); + SET_UniformMatrix2fvARB(table, save_UniformMatrix2fvARB); + SET_UniformMatrix3fvARB(table, save_UniformMatrix3fvARB); + SET_UniformMatrix4fvARB(table, save_UniformMatrix4fvARB); + SET_UniformMatrix2x3fv(table, save_UniformMatrix2x3fv); + SET_UniformMatrix3x2fv(table, save_UniformMatrix3x2fv); + SET_UniformMatrix2x4fv(table, save_UniformMatrix2x4fv); + SET_UniformMatrix4x2fv(table, save_UniformMatrix4x2fv); + SET_UniformMatrix3x4fv(table, save_UniformMatrix3x4fv); + SET_UniformMatrix4x3fv(table, save_UniformMatrix4x3fv); + /* ARB 30/31/32. GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */ SET_BindAttribLocationARB(table, exec_BindAttribLocationARB); SET_GetAttribLocationARB(table, exec_GetAttribLocationARB); diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 2ad66de7dd1..6b11aceb5ce 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -63,6 +63,7 @@ static const struct { { OFF, "GL_ARB_pixel_buffer_object", F(EXT_pixel_buffer_object) }, { OFF, "GL_ARB_point_parameters", F(EXT_point_parameters) }, { OFF, "GL_ARB_point_sprite", F(ARB_point_sprite) }, + { OFF, "GL_ARB_provoking_vertex", F(EXT_provoking_vertex) }, { OFF, "GL_ARB_seamless_cube_map", F(ARB_seamless_cube_map) }, { OFF, "GL_ARB_shader_objects", F(ARB_shader_objects) }, { OFF, "GL_ARB_shading_language_100", F(ARB_shading_language_100) }, diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 825a23090b5..13f49da5a78 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -46,6 +46,10 @@ #include "texstore.h" +/** Set this to 1 to help debug FBO incompleteness problems */ +#define DEBUG_FBO 0 + + /** * Notes: * @@ -308,8 +312,8 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, static void att_incomplete(const char *msg) { -#if 0 - _mesa_printf("attachment incomplete: %s\n", msg); +#if DEBUG_FBO + _mesa_debug(NULL, "attachment incomplete: %s\n", msg); #else (void) msg; #endif @@ -317,6 +321,23 @@ att_incomplete(const char *msg) /** + * For debug only. + */ +static void +fbo_incomplete(const char *msg, int index) +{ +#if DEBUG_FBO + _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index); +#else + (void) msg; + (void) index; +#endif +} + + + + +/** * Test if an attachment point is complete and update its Complete field. * \param format if GL_COLOR, this is a color attachment point, * if GL_DEPTH, this is a depth component attachment point, @@ -468,20 +489,6 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, /** - * Helpful for debugging - */ -static void -fbo_incomplete(const char *msg, int index) -{ - (void) msg; - (void) index; - /* - _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index); - */ -} - - -/** * Test if the given framebuffer object is complete and update its * Status field with the results. * Calls the ctx->Driver.ValidateFramebuffer() function to allow the @@ -1953,13 +1960,13 @@ _mesa_GenerateMipmapEXT(GLenum target) _mesa_lock_texture(ctx, texObj); if (target == GL_TEXTURE_CUBE_MAP) { - int face; - + GLuint face; for (face = 0; face < 6; face++) ctx->Driver.GenerateMipmap(ctx, GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, texObj); - } else { + } + else { ctx->Driver.GenerateMipmap(ctx, target, texObj); } _mesa_unlock_texture(ctx, texObj); diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 82283030409..b0aa04e9aa4 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -2075,6 +2075,23 @@ update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj, } +/** + * If the texture object's GenerateMipmap flag is set and we've + * changed the texture base level image, regenerate the rest of the + * mipmap levels now. + */ +static INLINE void +check_gen_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, GLint level) +{ + ASSERT(target != GL_TEXTURE_CUBE_MAP); + if (texObj->GenerateMipmap && level == texObj->BaseLevel) { + ASSERT(ctx->Driver.GenerateMipmap); + ctx->Driver.GenerateMipmap(ctx, target, texObj); + } +} + + /** Debug helper: override the user-requested internal format */ static GLenum override_internal_format(GLenum internalFormat, GLint width, GLint height) @@ -2161,36 +2178,36 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - goto out; - } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); } + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); + + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, 1, 1, + border, internalFormat); + + /* Give the texture to the driver. <pixels> may be null. */ + ASSERT(ctx->Driver.TexImage1D); + ctx->Driver.TexImage1D(ctx, target, level, internalFormat, + width, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + ASSERT(texImage->TexFormat); + + check_gen_mipmap(ctx, target, texObj, level); - ASSERT(texImage->Data == NULL); - - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, 1, 1, - border, internalFormat); - - ASSERT(ctx->Driver.TexImage1D); - - /* Give the texture to the driver! <pixels> may be null! */ - (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, - width, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - - ASSERT(texImage->TexFormat); - - update_fbo_texture(ctx, texObj, face, level); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - out: + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + } _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_1D) { @@ -2269,35 +2286,35 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - goto out; - } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); } - - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); - - ASSERT(ctx->Driver.TexImage2D); - - /* Give the texture to the driver! <pixels> may be null! */ - (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, - width, height, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - - ASSERT(texImage->TexFormat); - - update_fbo_texture(ctx, texObj, face, level); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - out: + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + + /* Give the texture to the driver. <pixels> may be null. */ + ASSERT(ctx->Driver.TexImage2D); + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, format, type, + pixels, &ctx->Unpack, texObj, texImage); + + ASSERT(texImage->TexFormat); + + check_gen_mipmap(ctx, target, texObj, level); + + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + } _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_2D || @@ -2372,35 +2389,35 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - goto out; } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - width, height, depth, - border, internalFormat); + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } - ASSERT(ctx->Driver.TexImage3D); + ASSERT(texImage->Data == NULL); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat); - /* Give the texture to the driver! <pixels> may be null! */ - (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, - width, height, depth, border, format, type, - pixels, &ctx->Unpack, texObj, texImage); + /* Give the texture to the driver. <pixels> may be null. */ + ASSERT(ctx->Driver.TexImage3D); + ctx->Driver.TexImage3D(ctx, target, level, internalFormat, + width, height, depth, border, format, type, + pixels, &ctx->Unpack, texObj, texImage); - ASSERT(texImage->TexFormat); + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + check_gen_mipmap(ctx, target, texObj, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_3D || @@ -2480,23 +2497,24 @@ _mesa_TexSubImage1D( GLenum target, GLint level, texImage = _mesa_select_tex_image(ctx, texObj, target, level); if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0, - postConvWidth, 1, 1, format, type, texImage)) { - goto out; /* error was detected */ + postConvWidth, 1, 1, + format, type, texImage)) { + /* error was recorded */ } + else if (width > 0) { + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; - if (width == 0) - goto out; /* no-op, not an error */ + ASSERT(ctx->Driver.TexSubImage1D); + ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, + format, type, pixels, &ctx->Unpack, + texObj, texImage); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + check_gen_mipmap(ctx, target, texObj, level); - ASSERT(ctx->Driver.TexSubImage1D); - (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, - format, type, pixels, &ctx->Unpack, - texObj, texImage); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2533,30 +2551,31 @@ _mesa_TexSubImage2D( GLenum target, GLint level, texUnit = _mesa_get_current_tex_unit(ctx); texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_select_tex_image(ctx, texObj, target, level); if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, - postConvWidth, postConvHeight, 1, format, type, - texImage)) { - goto out; /* error was detected */ + postConvWidth, postConvHeight, 1, + format, type, texImage)) { + /* error was recorded */ } + else if (width > 0 && height >= 0) { + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage2D); + ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + &ctx->Unpack, texObj, texImage); - if (width == 0 || height == 0) - goto out; /* no-op, not an error */ + check_gen_mipmap(ctx, target, texObj, level); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - - ASSERT(ctx->Driver.TexSubImage2D); - (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, - width, height, format, type, pixels, - &ctx->Unpack, texObj, texImage); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2590,28 +2609,30 @@ _mesa_TexSubImage3D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, type, texImage)) { - goto out; /* error was detected */ + if (subtexture_error_check2(ctx, 3, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, texImage)) { + /* error was recorded */ } + else if (width > 0 && height > 0 && height > 0) { + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; - if (width == 0 || height == 0 || height == 0) - goto out; /* no-op, not an error */ + ASSERT(ctx->Driver.TexSubImage3D); + ctx->Driver.TexSubImage3D(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; + check_gen_mipmap(ctx, target, texObj, level); - ASSERT(ctx->Driver.TexSubImage3D); - (*ctx->Driver.TexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, - &ctx->Unpack, texObj, texImage ); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2646,38 +2667,39 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, texUnit = _mesa_get_current_tex_unit(ctx); texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); - goto out; } + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - - ASSERT(texImage->Data == NULL); + ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, - border, internalFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, + border, internalFormat); + ASSERT(ctx->Driver.CopyTexImage1D); + ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat, + x, y, width, border); - ASSERT(ctx->Driver.CopyTexImage1D); - (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, - x, y, width, border); + ASSERT(texImage->TexFormat); - ASSERT(texImage->TexFormat); + check_gen_mipmap(ctx, target, texObj, level); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2719,33 +2741,34 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); - goto out; } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - - ASSERT(texImage->Data == NULL); + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); - - ASSERT(ctx->Driver.CopyTexImage2D); - (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, - x, y, width, height, border); - - ASSERT(texImage->TexFormat); + ASSERT(texImage->Data == NULL); - update_fbo_texture(ctx, texObj, face, level); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + + ASSERT(ctx->Driver.CopyTexImage2D); + ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat, + x, y, width, height, border); + + ASSERT(texImage->TexFormat); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + check_gen_mipmap(ctx, target, texObj, level); + + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2785,23 +2808,25 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, if (copytexsubimage_error_check2(ctx, 1, target, level, xoffset, 0, 0, postConvWidth, 1, - texImage)) - goto out; - + texImage)) { + /* error was recorded */ + } + else { + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, + &width, &height)) { + ASSERT(ctx->Driver.CopyTexSubImage1D); + ctx->Driver.CopyTexSubImage1D(ctx, target, level, + xoffset, x, y, width); - if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, - &width, &height)) { - ASSERT(ctx->Driver.CopyTexSubImage1D); - ctx->Driver.CopyTexSubImage1D(ctx, target, level, - xoffset, x, y, width); - } + check_gen_mipmap(ctx, target, texObj, level); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE; + } + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2839,24 +2864,29 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, } #endif - if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, - postConvWidth, postConvHeight, texImage)) - goto out; + if (copytexsubimage_error_check2(ctx, 2, target, level, + xoffset, yoffset, 0, + postConvWidth, postConvHeight, + texImage)) { + /* error was recorded */ + } + else { + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, + &width, &height)) { + ASSERT(ctx->Driver.CopyTexSubImage2D); + ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset, + x, y, width, height); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; + check_gen_mipmap(ctx, target, texObj, level); - if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, - &width, &height)) { - ASSERT(ctx->Driver.CopyTexSubImage2D); - ctx->Driver.CopyTexSubImage2D(ctx, target, level, - xoffset, yoffset, x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; + } } - - ctx->NewState |= _NEW_TEXTURE; } - out: _mesa_unlock_texture(ctx, texObj); } @@ -2896,25 +2926,28 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset, postConvWidth, postConvHeight, - texImage)) - goto out; - - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; - - if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, - &width, &height)) { - ASSERT(ctx->Driver.CopyTexSubImage3D); - ctx->Driver.CopyTexSubImage3D(ctx, target, level, - xoffset, yoffset, zoffset, - x, y, width, height); + texImage)) { + /* error was recored */ } + else { + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, + &width, &height)) { + ASSERT(ctx->Driver.CopyTexSubImage3D); + ctx->Driver.CopyTexSubImage3D(ctx, target, level, + xoffset, yoffset, zoffset, + x, y, width, height); + + check_gen_mipmap(ctx, target, texObj, level); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE; + } + } } - out: _mesa_unlock_texture(ctx, texObj); } @@ -3142,28 +3175,29 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); - goto out; } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, + border, internalFormat); - ASSERT(ctx->Driver.CompressedTexImage1D); - (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, - internalFormat, width, border, - imageSize, data, - texObj, texImage); + ASSERT(ctx->Driver.CompressedTexImage1D); + ctx->Driver.CompressedTexImage1D(ctx, target, level, + internalFormat, width, border, + imageSize, data, + texObj, texImage); - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + check_gen_mipmap(ctx, target, texObj, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } } - out: _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_1D) { @@ -3239,28 +3273,29 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); - goto out; - } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); } - ASSERT(texImage->Data == NULL); - - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); - - ASSERT(ctx->Driver.CompressedTexImage2D); - (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, - internalFormat, width, height, - border, imageSize, data, - texObj, texImage); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - out: + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); + + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); + + ASSERT(ctx->Driver.CompressedTexImage2D); + ctx->Driver.CompressedTexImage2D(ctx, target, level, + internalFormat, width, height, + border, imageSize, data, + texObj, texImage); + + check_gen_mipmap(ctx, target, texObj, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + } _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_2D || @@ -3334,29 +3369,31 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); - goto out; - } - - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); } - ASSERT(texImage->Data == NULL); - - _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, - border, internalFormat); - - ASSERT(ctx->Driver.CompressedTexImage3D); - (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, - internalFormat, - width, height, depth, - border, imageSize, data, - texObj, texImage); - - /* state update */ - texObj->_Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; - } - out: + else { + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); + + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat); + + ASSERT(ctx->Driver.CompressedTexImage3D); + ctx->Driver.CompressedTexImage3D(ctx, target, level, + internalFormat, + width, height, depth, + border, imageSize, data, + texObj, texImage); + + check_gen_mipmap(ctx, target, texObj, level); + + /* state update */ + texObj->_Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + } _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_3D) { @@ -3422,6 +3459,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, texUnit = _mesa_get_current_tex_unit(ctx); texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_select_tex_image(ctx, texObj, target, level); @@ -3430,26 +3468,25 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage1D(format)"); - goto out; } + else if ((width == 1 || width == 2) && + (GLuint) width != texImage->Width) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCompressedTexSubImage1D(width)"); + } + else if (width > 0) { + if (ctx->Driver.CompressedTexSubImage1D) { + ctx->Driver.CompressedTexSubImage1D(ctx, target, level, + xoffset, width, + format, imageSize, data, + texObj, texImage); + } - if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)"); - goto out; - } - - if (width == 0) - goto out; /* no-op, not an error */ + check_gen_mipmap(ctx, target, texObj, level); - if (ctx->Driver.CompressedTexSubImage1D) { - (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, - xoffset, width, - format, imageSize, data, - texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; } - out: _mesa_unlock_texture(ctx, texObj); } @@ -3479,6 +3516,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, texUnit = _mesa_get_current_tex_unit(ctx); texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_select_tex_image(ctx, texObj, target, level); @@ -3487,27 +3525,26 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage2D(format)"); - goto out; } - - if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || - ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) { + else if (((width == 1 || width == 2) + && (GLuint) width != texImage->Width) || + ((height == 1 || height == 2) + && (GLuint) height != texImage->Height)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)"); - goto out; } - - if (width == 0 || height == 0) - goto out; /* no-op, not an error */ - - if (ctx->Driver.CompressedTexSubImage2D) { - (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, + else if (width > 0 && height > 0) { + if (ctx->Driver.CompressedTexSubImage2D) { + ctx->Driver.CompressedTexSubImage2D(ctx, target, level, xoffset, yoffset, width, height, format, imageSize, data, texObj, texImage); + } + + check_gen_mipmap(ctx, target, texObj, level); + + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; } - out: _mesa_unlock_texture(ctx, texObj); } @@ -3536,6 +3573,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, texUnit = _mesa_get_current_tex_unit(ctx); texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_select_tex_image(ctx, texObj, target, level); @@ -3544,29 +3582,29 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage3D(format)"); - goto out; } - - if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || - ((height == 1 || height == 2) && (GLuint) height != texImage->Height) || - ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) { + else if (((width == 1 || width == 2) + && (GLuint) width != texImage->Width) || + ((height == 1 || height == 2) + && (GLuint) height != texImage->Height) || + ((depth == 1 || depth == 2) + && (GLuint) depth != texImage->Depth)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)"); - goto out; } - - if (width == 0 || height == 0 || depth == 0) - goto out; /* no-op, not an error */ - - if (ctx->Driver.CompressedTexSubImage3D) { - (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, + else if (width > 0 && height > 0 && depth > 0) { + if (ctx->Driver.CompressedTexSubImage3D) { + ctx->Driver.CompressedTexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data, texObj, texImage); + } + + check_gen_mipmap(ctx, target, texObj, level); + + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; } - out: _mesa_unlock_texture(ctx, texObj); } diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 05d144270ec..b2fbe2205ba 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -70,7 +70,7 @@ validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap) return GL_TRUE; } - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap ); + _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap ); return GL_FALSE; } @@ -210,7 +210,7 @@ set_tex_parameteri(GLcontext *ctx, } /* fall-through */ default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", params[0] ); } return GL_FALSE; @@ -225,7 +225,7 @@ set_tex_parameteri(GLcontext *ctx, texObj->MagFilter = params[0]; return GL_TRUE; default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", params[0]); } return GL_FALSE; diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index a22db628d3e..ab9973b8101 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -3302,32 +3302,9 @@ _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims) } -/** - * Choose the actual storage format for a new texture image. - * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function. - * Also set some other texImage fields related to texture compression, etc. - * \param ctx rendering context - * \param texImage the gl_texture_image - * \param dims texture dimensions (1, 2 or 3) - * \param format the user-specified format parameter - * \param type the user-specified type parameter - * \param internalFormat the user-specified internal format hint - */ static void -choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage, - GLuint dims, - GLenum format, GLenum type, GLint internalFormat) +compute_texture_size(GLcontext *ctx, struct gl_texture_image *texImage) { - ASSERT(dims == 1 || dims == 2 || dims == 3); - ASSERT(ctx->Driver.ChooseTextureFormat); - - texImage->TexFormat - = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); - - ASSERT(texImage->TexFormat); - - _mesa_set_fetch_functions(texImage, dims); - if (texImage->TexFormat->TexelBytes == 0) { /* must be a compressed format */ texImage->IsCompressed = GL_TRUE; @@ -3365,7 +3342,12 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, GLint sizeInBytes; (void) border; - choose_texture_format(ctx, texImage, 1, format, type, internalFormat); + texImage->TexFormat + = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); + ASSERT(texImage->TexFormat); + + _mesa_set_fetch_functions(texImage, 1); + compute_texture_size(ctx, texImage); /* allocate memory */ if (texImage->IsCompressed) @@ -3403,11 +3385,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } @@ -3434,7 +3411,12 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, GLint texelBytes, sizeInBytes; (void) border; - choose_texture_format(ctx, texImage, 2, format, type, internalFormat); + texImage->TexFormat + = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); + ASSERT(texImage->TexFormat); + + _mesa_set_fetch_functions(texImage, 2); + compute_texture_size(ctx, texImage); texelBytes = texImage->TexFormat->TexelBytes; @@ -3481,11 +3463,6 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } @@ -3508,7 +3485,12 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, GLint texelBytes, sizeInBytes; (void) border; - choose_texture_format(ctx, texImage, 3, format, type, internalFormat); + texImage->TexFormat + = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); + ASSERT(texImage->TexFormat); + + _mesa_set_fetch_functions(texImage, 3); + compute_texture_size(ctx, texImage); texelBytes = texImage->TexFormat->TexelBytes; @@ -3555,11 +3537,6 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } @@ -3601,11 +3578,6 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } @@ -3654,11 +3626,6 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } @@ -3707,11 +3674,6 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, } } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); } @@ -3762,7 +3724,12 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, ASSERT(texImage->Depth == 1); ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ - choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat); + texImage->TexFormat + = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 0, 0); + ASSERT(texImage->TexFormat); + + _mesa_set_fetch_functions(texImage, 2); + compute_texture_size(ctx, texImage); /* allocate storage */ texImage->Data = _mesa_alloc_texmemory(imageSize); @@ -3781,11 +3748,6 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, ASSERT(texImage->CompressedSize == (GLuint) imageSize); MEMCPY(texImage->Data, data, imageSize); - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); } @@ -3891,11 +3853,6 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, src += srcRowStride; } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); } diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c index 9f2d4de90fc..2de950b73b6 100644 --- a/src/mesa/shader/program_parse.tab.c +++ b/src/mesa/shader/program_parse.tab.c @@ -769,27 +769,27 @@ static const yytype_uint16 yyrline[] = 440, 447, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 467, 480, 493, 506, 528, 537, 570, 577, 592, 642, 684, 695, 716, 726, 732, 763, - 780, 780, 782, 789, 801, 802, 803, 806, 818, 830, - 848, 859, 871, 873, 874, 875, 876, 879, 879, 879, - 879, 880, 883, 884, 885, 886, 887, 888, 891, 909, - 913, 919, 923, 927, 931, 940, 949, 953, 958, 964, - 975, 975, 976, 978, 982, 986, 990, 996, 996, 998, - 1014, 1037, 1040, 1051, 1057, 1063, 1064, 1071, 1077, 1083, - 1091, 1097, 1103, 1111, 1117, 1123, 1131, 1132, 1135, 1136, - 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1148, - 1157, 1161, 1165, 1171, 1180, 1184, 1188, 1197, 1201, 1207, - 1213, 1220, 1225, 1233, 1243, 1245, 1253, 1259, 1263, 1267, - 1273, 1284, 1293, 1297, 1302, 1306, 1310, 1314, 1320, 1327, - 1331, 1337, 1345, 1356, 1363, 1367, 1373, 1383, 1394, 1398, - 1416, 1425, 1428, 1434, 1438, 1442, 1448, 1459, 1464, 1469, - 1474, 1479, 1484, 1492, 1495, 1500, 1513, 1521, 1532, 1540, - 1540, 1542, 1542, 1544, 1554, 1559, 1566, 1576, 1585, 1590, - 1597, 1607, 1617, 1629, 1629, 1630, 1630, 1632, 1642, 1650, - 1660, 1668, 1676, 1685, 1696, 1700, 1706, 1707, 1708, 1711, - 1711, 1714, 1714, 1717, 1723, 1731, 1744, 1753, 1762, 1766, - 1775, 1784, 1795, 1802, 1807, 1816, 1828, 1831, 1840, 1851, - 1852, 1853, 1856, 1857, 1858, 1861, 1862, 1865, 1866, 1869, - 1870, 1873, 1884, 1895, 1906 + 780, 780, 782, 789, 801, 802, 803, 806, 820, 834, + 852, 863, 875, 877, 878, 879, 880, 883, 883, 883, + 883, 884, 887, 888, 889, 890, 891, 892, 895, 913, + 917, 923, 927, 931, 935, 944, 953, 957, 962, 968, + 979, 979, 980, 982, 986, 990, 994, 1000, 1000, 1002, + 1018, 1041, 1044, 1055, 1061, 1067, 1068, 1075, 1081, 1087, + 1095, 1101, 1107, 1115, 1121, 1127, 1135, 1136, 1139, 1140, + 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1152, + 1161, 1165, 1169, 1175, 1184, 1188, 1192, 1201, 1205, 1211, + 1217, 1224, 1229, 1237, 1247, 1249, 1257, 1263, 1267, 1271, + 1277, 1288, 1297, 1301, 1306, 1310, 1314, 1318, 1324, 1331, + 1335, 1341, 1349, 1360, 1367, 1371, 1377, 1387, 1398, 1402, + 1420, 1429, 1432, 1438, 1442, 1446, 1452, 1463, 1468, 1473, + 1478, 1483, 1488, 1496, 1499, 1504, 1517, 1525, 1536, 1544, + 1544, 1546, 1546, 1548, 1558, 1563, 1570, 1580, 1589, 1594, + 1601, 1611, 1621, 1633, 1633, 1634, 1634, 1636, 1646, 1654, + 1664, 1672, 1680, 1689, 1700, 1704, 1710, 1711, 1712, 1715, + 1715, 1718, 1718, 1721, 1727, 1735, 1748, 1757, 1766, 1770, + 1779, 1788, 1799, 1806, 1811, 1820, 1832, 1835, 1844, 1855, + 1856, 1857, 1860, 1861, 1862, 1865, 1866, 1869, 1870, 1873, + 1874, 1877, 1888, 1899, 1910 }; #endif @@ -2791,8 +2791,10 @@ yyreduce: #line 807 "program_parse.y" { if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) { - yyerror(& (yylsp[(1) - (1)]), state, - "relative address offset too large (positive)"); + char s[100]; + _mesa_snprintf(s, sizeof(s), + "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer)); + yyerror(& (yylsp[(1) - (1)]), state, s); YYERROR; } else { (yyval.integer) = (yyvsp[(1) - (1)].integer); @@ -2803,11 +2805,13 @@ yyreduce: case 68: /* Line 1455 of yacc.c */ -#line 819 "program_parse.y" +#line 821 "program_parse.y" { if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) { - yyerror(& (yylsp[(1) - (1)]), state, - "relative address offset too large (negative)"); + char s[100]; + _mesa_snprintf(s, sizeof(s), + "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer)); + yyerror(& (yylsp[(1) - (1)]), state, s); YYERROR; } else { (yyval.integer) = (yyvsp[(1) - (1)].integer); @@ -2818,7 +2822,7 @@ yyreduce: case 69: /* Line 1455 of yacc.c */ -#line 831 "program_parse.y" +#line 835 "program_parse.y" { struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); @@ -2839,7 +2843,7 @@ yyreduce: case 70: /* Line 1455 of yacc.c */ -#line 849 "program_parse.y" +#line 853 "program_parse.y" { if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector"); @@ -2853,7 +2857,7 @@ yyreduce: case 71: /* Line 1455 of yacc.c */ -#line 860 "program_parse.y" +#line 864 "program_parse.y" { if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { yyerror(& (yylsp[(1) - (1)]), state, @@ -2868,21 +2872,21 @@ yyreduce: case 76: /* Line 1455 of yacc.c */ -#line 876 "program_parse.y" +#line 880 "program_parse.y" { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} break; case 81: /* Line 1455 of yacc.c */ -#line 880 "program_parse.y" +#line 884 "program_parse.y" { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} break; case 88: /* Line 1455 of yacc.c */ -#line 892 "program_parse.y" +#line 896 "program_parse.y" { struct asm_symbol *const s = declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)])); @@ -2903,7 +2907,7 @@ yyreduce: case 89: /* Line 1455 of yacc.c */ -#line 910 "program_parse.y" +#line 914 "program_parse.y" { (yyval.attrib) = (yyvsp[(2) - (2)].attrib); ;} @@ -2912,7 +2916,7 @@ yyreduce: case 90: /* Line 1455 of yacc.c */ -#line 914 "program_parse.y" +#line 918 "program_parse.y" { (yyval.attrib) = (yyvsp[(2) - (2)].attrib); ;} @@ -2921,7 +2925,7 @@ yyreduce: case 91: /* Line 1455 of yacc.c */ -#line 920 "program_parse.y" +#line 924 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_POS; ;} @@ -2930,7 +2934,7 @@ yyreduce: case 92: /* Line 1455 of yacc.c */ -#line 924 "program_parse.y" +#line 928 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_WEIGHT; ;} @@ -2939,7 +2943,7 @@ yyreduce: case 93: /* Line 1455 of yacc.c */ -#line 928 "program_parse.y" +#line 932 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_NORMAL; ;} @@ -2948,7 +2952,7 @@ yyreduce: case 94: /* Line 1455 of yacc.c */ -#line 932 "program_parse.y" +#line 936 "program_parse.y" { if (!state->ctx->Extensions.EXT_secondary_color) { yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported"); @@ -2962,7 +2966,7 @@ yyreduce: case 95: /* Line 1455 of yacc.c */ -#line 941 "program_parse.y" +#line 945 "program_parse.y" { if (!state->ctx->Extensions.EXT_fog_coord) { yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported"); @@ -2976,7 +2980,7 @@ yyreduce: case 96: /* Line 1455 of yacc.c */ -#line 950 "program_parse.y" +#line 954 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); ;} @@ -2985,7 +2989,7 @@ yyreduce: case 97: /* Line 1455 of yacc.c */ -#line 954 "program_parse.y" +#line 958 "program_parse.y" { yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); YYERROR; @@ -2995,7 +2999,7 @@ yyreduce: case 98: /* Line 1455 of yacc.c */ -#line 959 "program_parse.y" +#line 963 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer); ;} @@ -3004,7 +3008,7 @@ yyreduce: case 99: /* Line 1455 of yacc.c */ -#line 965 "program_parse.y" +#line 969 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) { yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference"); @@ -3018,7 +3022,7 @@ yyreduce: case 103: /* Line 1455 of yacc.c */ -#line 979 "program_parse.y" +#line 983 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_WPOS; ;} @@ -3027,7 +3031,7 @@ yyreduce: case 104: /* Line 1455 of yacc.c */ -#line 983 "program_parse.y" +#line 987 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer); ;} @@ -3036,7 +3040,7 @@ yyreduce: case 105: /* Line 1455 of yacc.c */ -#line 987 "program_parse.y" +#line 991 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_FOGC; ;} @@ -3045,7 +3049,7 @@ yyreduce: case 106: /* Line 1455 of yacc.c */ -#line 991 "program_parse.y" +#line 995 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); ;} @@ -3054,7 +3058,7 @@ yyreduce: case 109: /* Line 1455 of yacc.c */ -#line 999 "program_parse.y" +#line 1003 "program_parse.y" { struct asm_symbol *const s = declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)])); @@ -3073,7 +3077,7 @@ yyreduce: case 110: /* Line 1455 of yacc.c */ -#line 1015 "program_parse.y" +#line 1019 "program_parse.y" { if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) { yyerror(& (yylsp[(4) - (6)]), state, @@ -3098,7 +3102,7 @@ yyreduce: case 111: /* Line 1455 of yacc.c */ -#line 1037 "program_parse.y" +#line 1041 "program_parse.y" { (yyval.integer) = 0; ;} @@ -3107,7 +3111,7 @@ yyreduce: case 112: /* Line 1455 of yacc.c */ -#line 1041 "program_parse.y" +#line 1045 "program_parse.y" { if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxParameters)) { yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size"); @@ -3121,7 +3125,7 @@ yyreduce: case 113: /* Line 1455 of yacc.c */ -#line 1052 "program_parse.y" +#line 1056 "program_parse.y" { (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym); ;} @@ -3130,7 +3134,7 @@ yyreduce: case 114: /* Line 1455 of yacc.c */ -#line 1058 "program_parse.y" +#line 1062 "program_parse.y" { (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym); ;} @@ -3139,7 +3143,7 @@ yyreduce: case 116: /* Line 1455 of yacc.c */ -#line 1065 "program_parse.y" +#line 1069 "program_parse.y" { (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length; (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym); @@ -3149,7 +3153,7 @@ yyreduce: case 117: /* Line 1455 of yacc.c */ -#line 1072 "program_parse.y" +#line 1076 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3160,7 +3164,7 @@ yyreduce: case 118: /* Line 1455 of yacc.c */ -#line 1078 "program_parse.y" +#line 1082 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3171,7 +3175,7 @@ yyreduce: case 119: /* Line 1455 of yacc.c */ -#line 1084 "program_parse.y" +#line 1088 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3182,7 +3186,7 @@ yyreduce: case 120: /* Line 1455 of yacc.c */ -#line 1092 "program_parse.y" +#line 1096 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3193,7 +3197,7 @@ yyreduce: case 121: /* Line 1455 of yacc.c */ -#line 1098 "program_parse.y" +#line 1102 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3204,7 +3208,7 @@ yyreduce: case 122: /* Line 1455 of yacc.c */ -#line 1104 "program_parse.y" +#line 1108 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3215,7 +3219,7 @@ yyreduce: case 123: /* Line 1455 of yacc.c */ -#line 1112 "program_parse.y" +#line 1116 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3226,7 +3230,7 @@ yyreduce: case 124: /* Line 1455 of yacc.c */ -#line 1118 "program_parse.y" +#line 1122 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3237,7 +3241,7 @@ yyreduce: case 125: /* Line 1455 of yacc.c */ -#line 1124 "program_parse.y" +#line 1128 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3248,98 +3252,98 @@ yyreduce: case 126: /* Line 1455 of yacc.c */ -#line 1131 "program_parse.y" +#line 1135 "program_parse.y" { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;} break; case 127: /* Line 1455 of yacc.c */ -#line 1132 "program_parse.y" +#line 1136 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 128: /* Line 1455 of yacc.c */ -#line 1135 "program_parse.y" +#line 1139 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 129: /* Line 1455 of yacc.c */ -#line 1136 "program_parse.y" +#line 1140 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 130: /* Line 1455 of yacc.c */ -#line 1137 "program_parse.y" +#line 1141 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 131: /* Line 1455 of yacc.c */ -#line 1138 "program_parse.y" +#line 1142 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 132: /* Line 1455 of yacc.c */ -#line 1139 "program_parse.y" +#line 1143 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 133: /* Line 1455 of yacc.c */ -#line 1140 "program_parse.y" +#line 1144 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 134: /* Line 1455 of yacc.c */ -#line 1141 "program_parse.y" +#line 1145 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 135: /* Line 1455 of yacc.c */ -#line 1142 "program_parse.y" +#line 1146 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 136: /* Line 1455 of yacc.c */ -#line 1143 "program_parse.y" +#line 1147 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 137: /* Line 1455 of yacc.c */ -#line 1144 "program_parse.y" +#line 1148 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 138: /* Line 1455 of yacc.c */ -#line 1145 "program_parse.y" +#line 1149 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 139: /* Line 1455 of yacc.c */ -#line 1149 "program_parse.y" +#line 1153 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_MATERIAL; @@ -3351,7 +3355,7 @@ yyreduce: case 140: /* Line 1455 of yacc.c */ -#line 1158 "program_parse.y" +#line 1162 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} @@ -3360,7 +3364,7 @@ yyreduce: case 141: /* Line 1455 of yacc.c */ -#line 1162 "program_parse.y" +#line 1166 "program_parse.y" { (yyval.integer) = STATE_EMISSION; ;} @@ -3369,7 +3373,7 @@ yyreduce: case 142: /* Line 1455 of yacc.c */ -#line 1166 "program_parse.y" +#line 1170 "program_parse.y" { (yyval.integer) = STATE_SHININESS; ;} @@ -3378,7 +3382,7 @@ yyreduce: case 143: /* Line 1455 of yacc.c */ -#line 1172 "program_parse.y" +#line 1176 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHT; @@ -3390,7 +3394,7 @@ yyreduce: case 144: /* Line 1455 of yacc.c */ -#line 1181 "program_parse.y" +#line 1185 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} @@ -3399,7 +3403,7 @@ yyreduce: case 145: /* Line 1455 of yacc.c */ -#line 1185 "program_parse.y" +#line 1189 "program_parse.y" { (yyval.integer) = STATE_POSITION; ;} @@ -3408,7 +3412,7 @@ yyreduce: case 146: /* Line 1455 of yacc.c */ -#line 1189 "program_parse.y" +#line 1193 "program_parse.y" { if (!state->ctx->Extensions.EXT_point_parameters) { yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported"); @@ -3422,7 +3426,7 @@ yyreduce: case 147: /* Line 1455 of yacc.c */ -#line 1198 "program_parse.y" +#line 1202 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} @@ -3431,7 +3435,7 @@ yyreduce: case 148: /* Line 1455 of yacc.c */ -#line 1202 "program_parse.y" +#line 1206 "program_parse.y" { (yyval.integer) = STATE_HALF_VECTOR; ;} @@ -3440,7 +3444,7 @@ yyreduce: case 149: /* Line 1455 of yacc.c */ -#line 1208 "program_parse.y" +#line 1212 "program_parse.y" { (yyval.integer) = STATE_SPOT_DIRECTION; ;} @@ -3449,7 +3453,7 @@ yyreduce: case 150: /* Line 1455 of yacc.c */ -#line 1214 "program_parse.y" +#line 1218 "program_parse.y" { (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0]; (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1]; @@ -3459,7 +3463,7 @@ yyreduce: case 151: /* Line 1455 of yacc.c */ -#line 1221 "program_parse.y" +#line 1225 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT; @@ -3469,7 +3473,7 @@ yyreduce: case 152: /* Line 1455 of yacc.c */ -#line 1226 "program_parse.y" +#line 1230 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR; @@ -3480,7 +3484,7 @@ yyreduce: case 153: /* Line 1455 of yacc.c */ -#line 1234 "program_parse.y" +#line 1238 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHTPROD; @@ -3493,7 +3497,7 @@ yyreduce: case 155: /* Line 1455 of yacc.c */ -#line 1246 "program_parse.y" +#line 1250 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = (yyvsp[(3) - (3)].integer); @@ -3504,7 +3508,7 @@ yyreduce: case 156: /* Line 1455 of yacc.c */ -#line 1254 "program_parse.y" +#line 1258 "program_parse.y" { (yyval.integer) = STATE_TEXENV_COLOR; ;} @@ -3513,7 +3517,7 @@ yyreduce: case 157: /* Line 1455 of yacc.c */ -#line 1260 "program_parse.y" +#line 1264 "program_parse.y" { (yyval.integer) = STATE_AMBIENT; ;} @@ -3522,7 +3526,7 @@ yyreduce: case 158: /* Line 1455 of yacc.c */ -#line 1264 "program_parse.y" +#line 1268 "program_parse.y" { (yyval.integer) = STATE_DIFFUSE; ;} @@ -3531,7 +3535,7 @@ yyreduce: case 159: /* Line 1455 of yacc.c */ -#line 1268 "program_parse.y" +#line 1272 "program_parse.y" { (yyval.integer) = STATE_SPECULAR; ;} @@ -3540,7 +3544,7 @@ yyreduce: case 160: /* Line 1455 of yacc.c */ -#line 1274 "program_parse.y" +#line 1278 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) { yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector"); @@ -3554,7 +3558,7 @@ yyreduce: case 161: /* Line 1455 of yacc.c */ -#line 1285 "program_parse.y" +#line 1289 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_TEXGEN; @@ -3566,7 +3570,7 @@ yyreduce: case 162: /* Line 1455 of yacc.c */ -#line 1294 "program_parse.y" +#line 1298 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_S; ;} @@ -3575,7 +3579,7 @@ yyreduce: case 163: /* Line 1455 of yacc.c */ -#line 1298 "program_parse.y" +#line 1302 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_OBJECT_S; ;} @@ -3584,7 +3588,7 @@ yyreduce: case 164: /* Line 1455 of yacc.c */ -#line 1303 "program_parse.y" +#line 1307 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; ;} @@ -3593,7 +3597,7 @@ yyreduce: case 165: /* Line 1455 of yacc.c */ -#line 1307 "program_parse.y" +#line 1311 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; ;} @@ -3602,7 +3606,7 @@ yyreduce: case 166: /* Line 1455 of yacc.c */ -#line 1311 "program_parse.y" +#line 1315 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; ;} @@ -3611,7 +3615,7 @@ yyreduce: case 167: /* Line 1455 of yacc.c */ -#line 1315 "program_parse.y" +#line 1319 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; ;} @@ -3620,7 +3624,7 @@ yyreduce: case 168: /* Line 1455 of yacc.c */ -#line 1321 "program_parse.y" +#line 1325 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = (yyvsp[(2) - (2)].integer); @@ -3630,7 +3634,7 @@ yyreduce: case 169: /* Line 1455 of yacc.c */ -#line 1328 "program_parse.y" +#line 1332 "program_parse.y" { (yyval.integer) = STATE_FOG_COLOR; ;} @@ -3639,7 +3643,7 @@ yyreduce: case 170: /* Line 1455 of yacc.c */ -#line 1332 "program_parse.y" +#line 1336 "program_parse.y" { (yyval.integer) = STATE_FOG_PARAMS; ;} @@ -3648,7 +3652,7 @@ yyreduce: case 171: /* Line 1455 of yacc.c */ -#line 1338 "program_parse.y" +#line 1342 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_CLIPPLANE; @@ -3659,7 +3663,7 @@ yyreduce: case 172: /* Line 1455 of yacc.c */ -#line 1346 "program_parse.y" +#line 1350 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) { yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector"); @@ -3673,7 +3677,7 @@ yyreduce: case 173: /* Line 1455 of yacc.c */ -#line 1357 "program_parse.y" +#line 1361 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = (yyvsp[(2) - (2)].integer); @@ -3683,7 +3687,7 @@ yyreduce: case 174: /* Line 1455 of yacc.c */ -#line 1364 "program_parse.y" +#line 1368 "program_parse.y" { (yyval.integer) = STATE_POINT_SIZE; ;} @@ -3692,7 +3696,7 @@ yyreduce: case 175: /* Line 1455 of yacc.c */ -#line 1368 "program_parse.y" +#line 1372 "program_parse.y" { (yyval.integer) = STATE_POINT_ATTENUATION; ;} @@ -3701,7 +3705,7 @@ yyreduce: case 176: /* Line 1455 of yacc.c */ -#line 1374 "program_parse.y" +#line 1378 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0]; (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1]; @@ -3714,7 +3718,7 @@ yyreduce: case 177: /* Line 1455 of yacc.c */ -#line 1384 "program_parse.y" +#line 1388 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0]; (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1]; @@ -3727,7 +3731,7 @@ yyreduce: case 178: /* Line 1455 of yacc.c */ -#line 1394 "program_parse.y" +#line 1398 "program_parse.y" { (yyval.state)[2] = 0; (yyval.state)[3] = 3; @@ -3737,7 +3741,7 @@ yyreduce: case 179: /* Line 1455 of yacc.c */ -#line 1399 "program_parse.y" +#line 1403 "program_parse.y" { /* It seems logical that the matrix row range specifier would have * to specify a range or more than one row (i.e., $5 > $3). @@ -3758,7 +3762,7 @@ yyreduce: case 180: /* Line 1455 of yacc.c */ -#line 1417 "program_parse.y" +#line 1421 "program_parse.y" { (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0]; (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1]; @@ -3769,7 +3773,7 @@ yyreduce: case 181: /* Line 1455 of yacc.c */ -#line 1425 "program_parse.y" +#line 1429 "program_parse.y" { (yyval.integer) = 0; ;} @@ -3778,7 +3782,7 @@ yyreduce: case 182: /* Line 1455 of yacc.c */ -#line 1429 "program_parse.y" +#line 1433 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} @@ -3787,7 +3791,7 @@ yyreduce: case 183: /* Line 1455 of yacc.c */ -#line 1435 "program_parse.y" +#line 1439 "program_parse.y" { (yyval.integer) = STATE_MATRIX_INVERSE; ;} @@ -3796,7 +3800,7 @@ yyreduce: case 184: /* Line 1455 of yacc.c */ -#line 1439 "program_parse.y" +#line 1443 "program_parse.y" { (yyval.integer) = STATE_MATRIX_TRANSPOSE; ;} @@ -3805,7 +3809,7 @@ yyreduce: case 185: /* Line 1455 of yacc.c */ -#line 1443 "program_parse.y" +#line 1447 "program_parse.y" { (yyval.integer) = STATE_MATRIX_INVTRANS; ;} @@ -3814,7 +3818,7 @@ yyreduce: case 186: /* Line 1455 of yacc.c */ -#line 1449 "program_parse.y" +#line 1453 "program_parse.y" { if ((yyvsp[(1) - (1)].integer) > 3) { yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference"); @@ -3828,7 +3832,7 @@ yyreduce: case 187: /* Line 1455 of yacc.c */ -#line 1460 "program_parse.y" +#line 1464 "program_parse.y" { (yyval.state)[0] = STATE_MODELVIEW_MATRIX; (yyval.state)[1] = (yyvsp[(2) - (2)].integer); @@ -3838,7 +3842,7 @@ yyreduce: case 188: /* Line 1455 of yacc.c */ -#line 1465 "program_parse.y" +#line 1469 "program_parse.y" { (yyval.state)[0] = STATE_PROJECTION_MATRIX; (yyval.state)[1] = 0; @@ -3848,7 +3852,7 @@ yyreduce: case 189: /* Line 1455 of yacc.c */ -#line 1470 "program_parse.y" +#line 1474 "program_parse.y" { (yyval.state)[0] = STATE_MVP_MATRIX; (yyval.state)[1] = 0; @@ -3858,7 +3862,7 @@ yyreduce: case 190: /* Line 1455 of yacc.c */ -#line 1475 "program_parse.y" +#line 1479 "program_parse.y" { (yyval.state)[0] = STATE_TEXTURE_MATRIX; (yyval.state)[1] = (yyvsp[(2) - (2)].integer); @@ -3868,7 +3872,7 @@ yyreduce: case 191: /* Line 1455 of yacc.c */ -#line 1480 "program_parse.y" +#line 1484 "program_parse.y" { yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); YYERROR; @@ -3878,7 +3882,7 @@ yyreduce: case 192: /* Line 1455 of yacc.c */ -#line 1485 "program_parse.y" +#line 1489 "program_parse.y" { (yyval.state)[0] = STATE_PROGRAM_MATRIX; (yyval.state)[1] = (yyvsp[(3) - (4)].integer); @@ -3888,7 +3892,7 @@ yyreduce: case 193: /* Line 1455 of yacc.c */ -#line 1492 "program_parse.y" +#line 1496 "program_parse.y" { (yyval.integer) = 0; ;} @@ -3897,7 +3901,7 @@ yyreduce: case 194: /* Line 1455 of yacc.c */ -#line 1496 "program_parse.y" +#line 1500 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} @@ -3906,7 +3910,7 @@ yyreduce: case 195: /* Line 1455 of yacc.c */ -#line 1501 "program_parse.y" +#line 1505 "program_parse.y" { /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix * zero is valid. @@ -3923,7 +3927,7 @@ yyreduce: case 196: /* Line 1455 of yacc.c */ -#line 1514 "program_parse.y" +#line 1518 "program_parse.y" { /* Since GL_ARB_matrix_palette isn't supported, just let any value * through here. The error will be generated later. @@ -3935,7 +3939,7 @@ yyreduce: case 197: /* Line 1455 of yacc.c */ -#line 1522 "program_parse.y" +#line 1526 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) { yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector"); @@ -3949,7 +3953,7 @@ yyreduce: case 198: /* Line 1455 of yacc.c */ -#line 1533 "program_parse.y" +#line 1537 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_DEPTH_RANGE; @@ -3959,7 +3963,7 @@ yyreduce: case 203: /* Line 1455 of yacc.c */ -#line 1545 "program_parse.y" +#line 1549 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -3972,7 +3976,7 @@ yyreduce: case 204: /* Line 1455 of yacc.c */ -#line 1555 "program_parse.y" +#line 1559 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (1)].integer); (yyval.state)[1] = (yyvsp[(1) - (1)].integer); @@ -3982,7 +3986,7 @@ yyreduce: case 205: /* Line 1455 of yacc.c */ -#line 1560 "program_parse.y" +#line 1564 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (3)].integer); (yyval.state)[1] = (yyvsp[(3) - (3)].integer); @@ -3992,7 +3996,7 @@ yyreduce: case 206: /* Line 1455 of yacc.c */ -#line 1567 "program_parse.y" +#line 1571 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4005,7 +4009,7 @@ yyreduce: case 207: /* Line 1455 of yacc.c */ -#line 1577 "program_parse.y" +#line 1581 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4018,7 +4022,7 @@ yyreduce: case 208: /* Line 1455 of yacc.c */ -#line 1586 "program_parse.y" +#line 1590 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (1)].integer); (yyval.state)[1] = (yyvsp[(1) - (1)].integer); @@ -4028,7 +4032,7 @@ yyreduce: case 209: /* Line 1455 of yacc.c */ -#line 1591 "program_parse.y" +#line 1595 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (3)].integer); (yyval.state)[1] = (yyvsp[(3) - (3)].integer); @@ -4038,7 +4042,7 @@ yyreduce: case 210: /* Line 1455 of yacc.c */ -#line 1598 "program_parse.y" +#line 1602 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4051,7 +4055,7 @@ yyreduce: case 211: /* Line 1455 of yacc.c */ -#line 1608 "program_parse.y" +#line 1612 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) { yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference"); @@ -4064,7 +4068,7 @@ yyreduce: case 212: /* Line 1455 of yacc.c */ -#line 1618 "program_parse.y" +#line 1622 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) { yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference"); @@ -4077,7 +4081,7 @@ yyreduce: case 217: /* Line 1455 of yacc.c */ -#line 1633 "program_parse.y" +#line 1637 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); @@ -4090,7 +4094,7 @@ yyreduce: case 218: /* Line 1455 of yacc.c */ -#line 1643 "program_parse.y" +#line 1647 "program_parse.y" { (yyval.vector).count = 1; (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); @@ -4103,7 +4107,7 @@ yyreduce: case 219: /* Line 1455 of yacc.c */ -#line 1651 "program_parse.y" +#line 1655 "program_parse.y" { (yyval.vector).count = 1; (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer); @@ -4116,7 +4120,7 @@ yyreduce: case 220: /* Line 1455 of yacc.c */ -#line 1661 "program_parse.y" +#line 1665 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (3)].real); @@ -4129,7 +4133,7 @@ yyreduce: case 221: /* Line 1455 of yacc.c */ -#line 1669 "program_parse.y" +#line 1673 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (5)].real); @@ -4142,7 +4146,7 @@ yyreduce: case 222: /* Line 1455 of yacc.c */ -#line 1678 "program_parse.y" +#line 1682 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (7)].real); @@ -4155,7 +4159,7 @@ yyreduce: case 223: /* Line 1455 of yacc.c */ -#line 1687 "program_parse.y" +#line 1691 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (9)].real); @@ -4168,7 +4172,7 @@ yyreduce: case 224: /* Line 1455 of yacc.c */ -#line 1697 "program_parse.y" +#line 1701 "program_parse.y" { (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real); ;} @@ -4177,7 +4181,7 @@ yyreduce: case 225: /* Line 1455 of yacc.c */ -#line 1701 "program_parse.y" +#line 1705 "program_parse.y" { (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer)); ;} @@ -4186,42 +4190,42 @@ yyreduce: case 226: /* Line 1455 of yacc.c */ -#line 1706 "program_parse.y" +#line 1710 "program_parse.y" { (yyval.negate) = FALSE; ;} break; case 227: /* Line 1455 of yacc.c */ -#line 1707 "program_parse.y" +#line 1711 "program_parse.y" { (yyval.negate) = TRUE; ;} break; case 228: /* Line 1455 of yacc.c */ -#line 1708 "program_parse.y" +#line 1712 "program_parse.y" { (yyval.negate) = FALSE; ;} break; case 229: /* Line 1455 of yacc.c */ -#line 1711 "program_parse.y" +#line 1715 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} break; case 231: /* Line 1455 of yacc.c */ -#line 1714 "program_parse.y" +#line 1718 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} break; case 233: /* Line 1455 of yacc.c */ -#line 1718 "program_parse.y" +#line 1722 "program_parse.y" { if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) { YYERROR; @@ -4232,7 +4236,7 @@ yyreduce: case 234: /* Line 1455 of yacc.c */ -#line 1724 "program_parse.y" +#line 1728 "program_parse.y" { if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) { YYERROR; @@ -4243,7 +4247,7 @@ yyreduce: case 235: /* Line 1455 of yacc.c */ -#line 1732 "program_parse.y" +#line 1736 "program_parse.y" { struct asm_symbol *const s = declare_variable(state, (yyvsp[(2) - (4)].string), at_output, & (yylsp[(2) - (4)])); @@ -4259,7 +4263,7 @@ yyreduce: case 236: /* Line 1455 of yacc.c */ -#line 1745 "program_parse.y" +#line 1749 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_HPOS; @@ -4273,7 +4277,7 @@ yyreduce: case 237: /* Line 1455 of yacc.c */ -#line 1754 "program_parse.y" +#line 1758 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_FOGC; @@ -4287,7 +4291,7 @@ yyreduce: case 238: /* Line 1455 of yacc.c */ -#line 1763 "program_parse.y" +#line 1767 "program_parse.y" { (yyval.result) = (yyvsp[(2) - (2)].result); ;} @@ -4296,7 +4300,7 @@ yyreduce: case 239: /* Line 1455 of yacc.c */ -#line 1767 "program_parse.y" +#line 1771 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_PSIZ; @@ -4310,7 +4314,7 @@ yyreduce: case 240: /* Line 1455 of yacc.c */ -#line 1776 "program_parse.y" +#line 1780 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer); @@ -4324,7 +4328,7 @@ yyreduce: case 241: /* Line 1455 of yacc.c */ -#line 1785 "program_parse.y" +#line 1789 "program_parse.y" { if (state->mode == ARB_fragment) { (yyval.result) = FRAG_RESULT_DEPTH; @@ -4338,7 +4342,7 @@ yyreduce: case 242: /* Line 1455 of yacc.c */ -#line 1796 "program_parse.y" +#line 1800 "program_parse.y" { (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;} @@ -4347,7 +4351,7 @@ yyreduce: case 243: /* Line 1455 of yacc.c */ -#line 1802 "program_parse.y" +#line 1806 "program_parse.y" { (yyval.integer) = (state->mode == ARB_vertex) ? VERT_RESULT_COL0 @@ -4358,7 +4362,7 @@ yyreduce: case 244: /* Line 1455 of yacc.c */ -#line 1808 "program_parse.y" +#line 1812 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = VERT_RESULT_COL0; @@ -4372,7 +4376,7 @@ yyreduce: case 245: /* Line 1455 of yacc.c */ -#line 1817 "program_parse.y" +#line 1821 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = VERT_RESULT_BFC0; @@ -4386,7 +4390,7 @@ yyreduce: case 246: /* Line 1455 of yacc.c */ -#line 1828 "program_parse.y" +#line 1832 "program_parse.y" { (yyval.integer) = 0; ;} @@ -4395,7 +4399,7 @@ yyreduce: case 247: /* Line 1455 of yacc.c */ -#line 1832 "program_parse.y" +#line 1836 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = 0; @@ -4409,7 +4413,7 @@ yyreduce: case 248: /* Line 1455 of yacc.c */ -#line 1841 "program_parse.y" +#line 1845 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = 1; @@ -4423,91 +4427,91 @@ yyreduce: case 249: /* Line 1455 of yacc.c */ -#line 1851 "program_parse.y" +#line 1855 "program_parse.y" { (yyval.integer) = 0; ;} break; case 250: /* Line 1455 of yacc.c */ -#line 1852 "program_parse.y" +#line 1856 "program_parse.y" { (yyval.integer) = 0; ;} break; case 251: /* Line 1455 of yacc.c */ -#line 1853 "program_parse.y" +#line 1857 "program_parse.y" { (yyval.integer) = 1; ;} break; case 252: /* Line 1455 of yacc.c */ -#line 1856 "program_parse.y" +#line 1860 "program_parse.y" { (yyval.integer) = 0; ;} break; case 253: /* Line 1455 of yacc.c */ -#line 1857 "program_parse.y" +#line 1861 "program_parse.y" { (yyval.integer) = 0; ;} break; case 254: /* Line 1455 of yacc.c */ -#line 1858 "program_parse.y" +#line 1862 "program_parse.y" { (yyval.integer) = 1; ;} break; case 255: /* Line 1455 of yacc.c */ -#line 1861 "program_parse.y" +#line 1865 "program_parse.y" { (yyval.integer) = 0; ;} break; case 256: /* Line 1455 of yacc.c */ -#line 1862 "program_parse.y" +#line 1866 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} break; case 257: /* Line 1455 of yacc.c */ -#line 1865 "program_parse.y" +#line 1869 "program_parse.y" { (yyval.integer) = 0; ;} break; case 258: /* Line 1455 of yacc.c */ -#line 1866 "program_parse.y" +#line 1870 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} break; case 259: /* Line 1455 of yacc.c */ -#line 1869 "program_parse.y" +#line 1873 "program_parse.y" { (yyval.integer) = 0; ;} break; case 260: /* Line 1455 of yacc.c */ -#line 1870 "program_parse.y" +#line 1874 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} break; case 261: /* Line 1455 of yacc.c */ -#line 1874 "program_parse.y" +#line 1878 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) { yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector"); @@ -4521,7 +4525,7 @@ yyreduce: case 262: /* Line 1455 of yacc.c */ -#line 1885 "program_parse.y" +#line 1889 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) { yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector"); @@ -4535,7 +4539,7 @@ yyreduce: case 263: /* Line 1455 of yacc.c */ -#line 1896 "program_parse.y" +#line 1900 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) { yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector"); @@ -4549,7 +4553,7 @@ yyreduce: case 264: /* Line 1455 of yacc.c */ -#line 1907 "program_parse.y" +#line 1911 "program_parse.y" { struct asm_symbol *exist = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string)); @@ -4573,7 +4577,7 @@ yyreduce: /* Line 1455 of yacc.c */ -#line 4577 "program_parse.tab.c" +#line 4581 "program_parse.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -4792,7 +4796,7 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 1927 "program_parse.y" +#line 1931 "program_parse.y" struct asm_instruction * diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y index 06c1915fbee..89da91064b2 100644 --- a/src/mesa/shader/program_parse.y +++ b/src/mesa/shader/program_parse.y @@ -806,8 +806,10 @@ addrRegRelOffset: { $$ = 0; } addrRegPosOffset: INTEGER { if (($1 < 0) || ($1 > 63)) { - yyerror(& @1, state, - "relative address offset too large (positive)"); + char s[100]; + _mesa_snprintf(s, sizeof(s), + "relative address offset too large (%d)", $1); + yyerror(& @1, state, s); YYERROR; } else { $$ = $1; @@ -818,8 +820,10 @@ addrRegPosOffset: INTEGER addrRegNegOffset: INTEGER { if (($1 < 0) || ($1 > 64)) { - yyerror(& @1, state, - "relative address offset too large (negative)"); + char s[100]; + _mesa_snprintf(s, sizeof(s), + "relative address offset too large (%d)", $1); + yyerror(& @1, state, s); YYERROR; } else { $$ = $1; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 54a25dfaf07..178b7d0dbaf 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1474,6 +1474,21 @@ _mesa_link_program(GLcontext *ctx, GLuint program) FLUSH_VERTICES(ctx, _NEW_PROGRAM); _slang_link(ctx, program, shProg); + + /* debug code */ + if (0) { + GLuint i; + + _mesa_printf("Link %u shaders in program %u: %s\n", + shProg->NumShaders, shProg->Name, + shProg->LinkStatus ? "Success" : "Failed"); + + for (i = 0; i < shProg->NumShaders; i++) { + _mesa_printf(" shader %u, type 0x%x\n", + shProg->Shaders[i]->Name, + shProg->Shaders[i]->Type); + } + } } diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 169c07f8cea..8f2b40d5dfb 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -546,6 +546,32 @@ _slang_update_inputs_outputs(struct gl_program *prog) +/** + * Remove extra #version directives from the concatenated source string. + * Disable the extra ones by converting first two chars to //, a comment. + * This is a bit of hack to work around a preprocessor bug that only + * allows one #version directive per source. + */ +static void +remove_extra_version_directives(GLchar *source) +{ + GLuint verCount = 0; + while (1) { + char *ver = _mesa_strstr(source, "#version"); + if (ver) { + verCount++; + if (verCount > 1) { + ver[0] = '/'; + ver[1] = '/'; + } + source += 8; + } + else { + break; + } + } +} + /** @@ -593,6 +619,8 @@ concat_shaders(struct gl_shader_program *shProg, GLenum shaderType) _mesa_printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source); */ + remove_extra_version_directives(source); + newShader = CALLOC_STRUCT(gl_shader); newShader->Type = shaderType; newShader->Source = source; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index abaf9d2c353..c0ace3b9eac 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -760,10 +760,6 @@ done: st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } - - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } @@ -1134,10 +1130,6 @@ done: st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } - - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } @@ -1601,10 +1593,6 @@ st_copy_texsubimage(GLcontext *ctx, destX, destY, destZ, srcX, srcY, width, height); } - - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index df0cf8df266..04be57f8ffa 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -27,834 +27,648 @@ /* * \author - * Michal Krol + * Michal Krol, + * Keith Whitwell */ #include "pipe/p_compiler.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_build.h" -#include "tgsi/tgsi_util.h" -#include "tgsi/tgsi_dump.h" -#include "tgsi/tgsi_sanity.h" +#include "pipe/p_state.h" +#include "tgsi/tgsi_ureg.h" #include "st_mesa_to_tgsi.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "util/u_debug.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +struct label { + unsigned branch_target; + unsigned token; +}; + +struct st_translate { + struct ureg_program *ureg; + + struct ureg_dst temps[MAX_PROGRAM_TEMPS]; + struct ureg_src *constants; + struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; + struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; + struct ureg_dst address[1]; + struct ureg_src samplers[PIPE_MAX_SAMPLERS]; + + const GLuint *inputMapping; + const GLuint *outputMapping; + + /* For every instruction that contains a label (eg CALL), keep + * details so that we can go back afterwards and emit the correct + * tgsi instruction number for each label. + */ + struct label *labels; + unsigned labels_size; + unsigned labels_count; + + /* Keep a record of the tgsi instruction number that each mesa + * instruction starts at, will be used to fix up labels after + * translation. + */ + unsigned *insn; + unsigned insn_size; + unsigned insn_count; + + unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ + + boolean error; +}; + + +static unsigned *get_label( struct st_translate *t, + unsigned branch_target ) +{ + unsigned i; + + if (t->labels_count + 1 >= t->labels_size) { + unsigned old_size = t->labels_size; + t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); + t->labels = REALLOC( t->labels, + old_size * sizeof t->labels[0], + t->labels_size * sizeof t->labels[0] ); + if (t->labels == NULL) { + static unsigned dummy; + t->error = TRUE; + return &dummy; + } + } + + i = t->labels_count++; + t->labels[i].branch_target = branch_target; + return &t->labels[i].token; +} + + +static void set_insn_start( struct st_translate *t, + unsigned start ) +{ + if (t->insn_count + 1 >= t->insn_size) { + unsigned old_size = t->insn_size; + t->insn_size = 1 << (util_logbase2(t->insn_size) + 1); + t->insn = REALLOC( t->insn, + old_size * sizeof t->insn[0], + t->insn_size * sizeof t->insn[0] ); + if (t->insn == NULL) { + t->error = TRUE; + return; + } + } + + t->insn[t->insn_count++] = start; +} + /* * Map mesa register file to TGSI register file. */ -static GLuint -map_register_file( - gl_register_file file, - GLuint index, - const GLuint immediateMapping[], - GLboolean indirectAccess ) +static struct ureg_dst +dst_register( struct st_translate *t, + gl_register_file file, + GLuint index ) { switch( file ) { case PROGRAM_UNDEFINED: - return TGSI_FILE_NULL; + return ureg_dst_undef(); + case PROGRAM_TEMPORARY: - return TGSI_FILE_TEMPORARY; - /*case PROGRAM_LOCAL_PARAM:*/ - /*case PROGRAM_ENV_PARAM:*/ - - /* Because of the longstanding problem with mesa arb shaders - * where constants, immediates and state variables are all - * bundled together as PROGRAM_STATE_VAR, we can't tell from the - * mesa register file whether this is a CONSTANT or an - * IMMEDIATE, hence we need all the other information. - */ - case PROGRAM_STATE_VAR: - case PROGRAM_NAMED_PARAM: - case PROGRAM_UNIFORM: - if (!indirectAccess && immediateMapping && immediateMapping[index] != ~0) - return TGSI_FILE_IMMEDIATE; - else - return TGSI_FILE_CONSTANT; - case PROGRAM_CONSTANT: - if (indirectAccess) - return TGSI_FILE_CONSTANT; - assert(immediateMapping[index] != ~0); - return TGSI_FILE_IMMEDIATE; - case PROGRAM_INPUT: - return TGSI_FILE_INPUT; + if (ureg_dst_is_undef(t->temps[index])) + t->temps[index] = ureg_DECL_temporary( t->ureg ); + + return t->temps[index]; + case PROGRAM_OUTPUT: - return TGSI_FILE_OUTPUT; + return t->outputs[t->outputMapping[index]]; + case PROGRAM_ADDRESS: - return TGSI_FILE_ADDRESS; + return t->address[index]; + default: assert( 0 ); - return TGSI_FILE_NULL; + return ureg_dst_undef(); } } -/** - * Map mesa register file index to TGSI index. - * Take special care when processing input and output indices. - * \param file one of TGSI_FILE_x - * \param index the mesa register file index - * \param inputMapping maps Mesa input indexes to TGSI input indexes - * \param outputMapping maps Mesa output indexes to TGSI output indexes - */ -static GLuint -map_register_file_index( - GLuint procType, - GLuint file, - GLuint index, - GLuint *swizzle, - const GLuint inputMapping[], - const GLuint outputMapping[], - const GLuint immediateMapping[], - GLboolean indirectAccess ) + +static struct ureg_src +src_register( struct st_translate *t, + gl_register_file file, + GLuint index ) { switch( file ) { - case TGSI_FILE_INPUT: - /* inputs are mapped according to the user-defined map */ - return inputMapping[index]; + case PROGRAM_UNDEFINED: + return ureg_src_undef(); + + case PROGRAM_TEMPORARY: + if (ureg_dst_is_undef(t->temps[index])) + t->temps[index] = ureg_DECL_temporary( t->ureg ); + return ureg_src(t->temps[index]); - case TGSI_FILE_OUTPUT: - return outputMapping[index]; + case PROGRAM_STATE_VAR: + case PROGRAM_NAMED_PARAM: + case PROGRAM_UNIFORM: + case PROGRAM_CONSTANT: + return t->constants[index]; - case TGSI_FILE_IMMEDIATE: - if (indirectAccess) - return index; - assert(immediateMapping[index] != ~0); - return immediateMapping[index]; + case PROGRAM_INPUT: + return t->inputs[t->inputMapping[index]]; + + case PROGRAM_OUTPUT: + return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */ + + case PROGRAM_ADDRESS: + return ureg_src(t->address[index]); default: - return index; + assert( 0 ); + return ureg_src_undef(); } } -/* + +/** * Map mesa texture target to TGSI texture target. */ -static GLuint -map_texture_target( - GLuint textarget, - GLboolean shadow ) +static unsigned +translate_texture_target( GLuint textarget, + GLboolean shadow ) { - switch( textarget ) { - case TEXTURE_1D_INDEX: - if (shadow) - return TGSI_TEXTURE_SHADOW1D; - else - return TGSI_TEXTURE_1D; - case TEXTURE_2D_INDEX: - if (shadow) - return TGSI_TEXTURE_SHADOW2D; - else - return TGSI_TEXTURE_2D; - case TEXTURE_3D_INDEX: - return TGSI_TEXTURE_3D; - case TEXTURE_CUBE_INDEX: - return TGSI_TEXTURE_CUBE; - case TEXTURE_RECT_INDEX: - if (shadow) - return TGSI_TEXTURE_SHADOWRECT; - else - return TGSI_TEXTURE_RECT; - default: - assert( 0 ); + if (shadow) { + switch( textarget ) { + case TEXTURE_1D_INDEX: return TGSI_TEXTURE_SHADOW1D; + case TEXTURE_2D_INDEX: return TGSI_TEXTURE_SHADOW2D; + case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT; + default: break; + } } - return TGSI_TEXTURE_1D; -} - -static GLuint -convert_sat( - GLuint sat ) -{ - switch( sat ) { - case SATURATE_OFF: - return TGSI_SAT_NONE; - case SATURATE_ZERO_ONE: - return TGSI_SAT_ZERO_ONE; + switch( textarget ) { + case TEXTURE_1D_INDEX: return TGSI_TEXTURE_1D; + case TEXTURE_2D_INDEX: return TGSI_TEXTURE_2D; + case TEXTURE_3D_INDEX: return TGSI_TEXTURE_3D; + case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE; + case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT; default: assert( 0 ); - return TGSI_SAT_NONE; + return TGSI_TEXTURE_1D; } } -static GLuint -convert_writemask( - GLuint writemask ) + +static struct ureg_dst +translate_dst( struct st_translate *t, + const struct prog_dst_register *DstReg, + boolean saturate ) { - assert( WRITEMASK_X == TGSI_WRITEMASK_X ); - assert( WRITEMASK_Y == TGSI_WRITEMASK_Y ); - assert( WRITEMASK_Z == TGSI_WRITEMASK_Z ); - assert( WRITEMASK_W == TGSI_WRITEMASK_W ); - assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 ); + struct ureg_dst dst = dst_register( t, + DstReg->File, + DstReg->Index ); + + dst = ureg_writemask( dst, + DstReg->WriteMask ); + + if (saturate) + dst = ureg_saturate( dst ); + + if (DstReg->RelAddr) + dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); - return writemask; + return dst; } -static struct tgsi_full_immediate -make_immediate(const float *value, uint size) + +static struct ureg_src +translate_src( struct st_translate *t, + const struct prog_src_register *SrcReg ) { - struct tgsi_full_immediate imm; - unsigned i; + struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index ); - imm = tgsi_default_full_immediate(); - imm.Immediate.NrTokens += size; - imm.Immediate.DataType = TGSI_IMM_FLOAT32; + src = ureg_swizzle( src, + GET_SWZ( SrcReg->Swizzle, 0 ) & 0x3, + GET_SWZ( SrcReg->Swizzle, 1 ) & 0x3, + GET_SWZ( SrcReg->Swizzle, 2 ) & 0x3, + GET_SWZ( SrcReg->Swizzle, 3 ) & 0x3); - for (i = 0; i < size; i++) - imm.u[i].Float = value[i]; + if (SrcReg->Negate == NEGATE_XYZW) + src = ureg_negate(src); - return imm; + if (SrcReg->Abs) + src = ureg_abs(src); + + if (SrcReg->RelAddr) + src = ureg_src_indirect( src, ureg_src(t->address[0])); + + return src; } -static void -compile_instruction( - const struct prog_instruction *inst, - struct tgsi_full_instruction *fullinst, - const GLuint inputMapping[], - const GLuint outputMapping[], - const GLuint immediateMapping[], - GLboolean indirectAccess, - GLuint preamble_size, - GLuint procType, - GLboolean *insideSubroutine, - GLint wposTemp) + +static struct ureg_src swizzle_4v( struct ureg_src src, + const unsigned *swz ) { - GLuint i; - struct tgsi_full_dst_register *fulldst; - struct tgsi_full_src_register *fullsrc; - - *fullinst = tgsi_default_full_instruction(); - - fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode ); - fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode ); - fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode ); - - fulldst = &fullinst->FullDstRegisters[0]; - fulldst->DstRegister.File = map_register_file( inst->DstReg.File, 0, NULL, GL_FALSE ); - fulldst->DstRegister.Index = map_register_file_index( - procType, - fulldst->DstRegister.File, - inst->DstReg.Index, - NULL, - inputMapping, - outputMapping, - NULL, - GL_FALSE ); - fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask ); - if (inst->DstReg.RelAddr) { - fulldst->DstRegister.Indirect = 1; - fulldst->DstRegisterInd.File = TGSI_FILE_ADDRESS; - fulldst->DstRegisterInd.Index = 0; + return ureg_swizzle( src, swz[0], swz[1], swz[2], swz[3] ); +} + + +/** + * Translate SWZ instructions into a single MAD. EG: + * + * SWZ dst, src.x-y10 + * + * becomes: + * + * MAD dst {1,-1,0,0}, src.xyxx, {0,0,1,0} + */ +static void emit_swz( struct st_translate *t, + struct ureg_dst dst, + const struct prog_src_register *SrcReg ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index ); + + unsigned negate_mask = SrcReg->Negate; + + unsigned one_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ONE) << 0 | + (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ONE) << 1 | + (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ONE) << 2 | + (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ONE) << 3); + + unsigned zero_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ZERO) << 0 | + (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ZERO) << 1 | + (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ZERO) << 2 | + (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ZERO) << 3); + + unsigned negative_one_mask = one_mask & negate_mask; + unsigned positive_one_mask = one_mask & ~negate_mask; + + struct ureg_src imm; + unsigned i; + unsigned mul_swizzle[4] = {0,0,0,0}; + unsigned add_swizzle[4] = {0,0,0,0}; + unsigned src_swizzle[4] = {0,0,0,0}; + boolean need_add = FALSE; + boolean need_mul = FALSE; + + if (dst.WriteMask == 0) + return; + + /* Is this just a MOV? + */ + if (zero_mask == 0 && + one_mask == 0 && + (negate_mask == 0 || negate_mask == TGSI_WRITEMASK_XYZW)) + { + ureg_MOV( ureg, dst, translate_src( t, SrcReg )); + return; } - for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) { - GLuint j; - GLuint swizzle = inst->SrcReg[i].Swizzle; +#define IMM_ZERO 0 +#define IMM_ONE 1 +#define IMM_NEG_ONE 2 - fullsrc = &fullinst->FullSrcRegisters[i]; + imm = ureg_imm3f( ureg, 0, 1, -1 ); - if (procType == TGSI_PROCESSOR_FRAGMENT && - inst->SrcReg[i].File == PROGRAM_INPUT && - inst->SrcReg[i].Index == FRAG_ATTRIB_WPOS) { - /* special case of INPUT[WPOS] */ - fullsrc->SrcRegister.File = TGSI_FILE_TEMPORARY; - fullsrc->SrcRegister.Index = wposTemp; - } - else { - /* any other src register */ - fullsrc->SrcRegister.File = map_register_file( - inst->SrcReg[i].File, - inst->SrcReg[i].Index, - immediateMapping, - indirectAccess ); - fullsrc->SrcRegister.Index = map_register_file_index( - procType, - fullsrc->SrcRegister.File, - inst->SrcReg[i].Index, - &swizzle, - inputMapping, - outputMapping, - immediateMapping, - indirectAccess ); - } + for (i = 0; i < 4; i++) { + unsigned bit = 1 << i; - /* swizzle (ext swizzle also depends on negation) */ - { - GLuint swz[4]; - GLboolean extended = (inst->SrcReg[i].Negate != NEGATE_NONE && - inst->SrcReg[i].Negate != NEGATE_XYZW); - for( j = 0; j < 4; j++ ) { - swz[j] = GET_SWZ( swizzle, j ); - if (swz[j] > SWIZZLE_W) - extended = GL_TRUE; + if (dst.WriteMask & bit) { + if (positive_one_mask & bit) { + mul_swizzle[i] = IMM_ZERO; + add_swizzle[i] = IMM_ONE; + need_add = TRUE; } - if (extended) { - for (j = 0; j < 4; j++) { - tgsi_util_set_src_register_extswizzle(&fullsrc->SrcRegisterExtSwz, - swz[j], j); - } + else if (negative_one_mask & bit) { + mul_swizzle[i] = IMM_ZERO; + add_swizzle[i] = IMM_NEG_ONE; + need_add = TRUE; + } + else if (zero_mask & bit) { + mul_swizzle[i] = IMM_ZERO; + add_swizzle[i] = IMM_ZERO; + need_add = TRUE; } else { - for (j = 0; j < 4; j++) { - tgsi_util_set_src_register_swizzle(&fullsrc->SrcRegister, - swz[j], j); + add_swizzle[i] = IMM_ZERO; + src_swizzle[i] = GET_SWZ(SrcReg->Swizzle, i); + need_mul = TRUE; + if (negate_mask & bit) { + mul_swizzle[i] = IMM_NEG_ONE; + } + else { + mul_swizzle[i] = IMM_ONE; } } } + } - if( inst->SrcReg[i].Negate == NEGATE_XYZW ) { - fullsrc->SrcRegister.Negate = 1; - } - else if( inst->SrcReg[i].Negate != NEGATE_NONE ) { - if( inst->SrcReg[i].Negate & NEGATE_X ) { - fullsrc->SrcRegisterExtSwz.NegateX = 1; - } - if( inst->SrcReg[i].Negate & NEGATE_Y ) { - fullsrc->SrcRegisterExtSwz.NegateY = 1; - } - if( inst->SrcReg[i].Negate & NEGATE_Z ) { - fullsrc->SrcRegisterExtSwz.NegateZ = 1; - } - if( inst->SrcReg[i].Negate & NEGATE_W ) { - fullsrc->SrcRegisterExtSwz.NegateW = 1; - } - } + if (need_mul && need_add) { + ureg_MAD( ureg, + dst, + swizzle_4v( src, src_swizzle ), + swizzle_4v( imm, mul_swizzle ), + swizzle_4v( imm, add_swizzle ) ); + } + else if (need_mul) { + ureg_MUL( ureg, + dst, + swizzle_4v( src, src_swizzle ), + swizzle_4v( imm, mul_swizzle ) ); + } + else if (need_add) { + ureg_MOV( ureg, + dst, + swizzle_4v( imm, add_swizzle ) ); + } + else { + assert(0); + } - if( inst->SrcReg[i].Abs ) { - fullsrc->SrcRegisterExtMod.Absolute = 1; - } +#undef IMM_ZERO +#undef IMM_ONE +#undef IMM_NEG_ONE +} - if( inst->SrcReg[i].RelAddr ) { - fullsrc->SrcRegister.Indirect = 1; - fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS; - fullsrc->SrcRegisterInd.Index = 0; - } - } - switch( inst->Opcode ) { +static unsigned +translate_opcode( unsigned op ) +{ + switch( op ) { case OPCODE_ARL: - fullinst->Instruction.Opcode = TGSI_OPCODE_ARL; - break; + return TGSI_OPCODE_ARL; case OPCODE_ABS: - fullinst->Instruction.Opcode = TGSI_OPCODE_ABS; - break; + return TGSI_OPCODE_ABS; case OPCODE_ADD: - fullinst->Instruction.Opcode = TGSI_OPCODE_ADD; - break; + return TGSI_OPCODE_ADD; case OPCODE_BGNLOOP: - fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP; - fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size; - break; + return TGSI_OPCODE_BGNLOOP; case OPCODE_BGNSUB: - fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB; - *insideSubroutine = GL_TRUE; - break; + return TGSI_OPCODE_BGNSUB; case OPCODE_BRA: - fullinst->Instruction.Opcode = TGSI_OPCODE_BRA; - break; + return TGSI_OPCODE_BRA; case OPCODE_BRK: - fullinst->Instruction.Opcode = TGSI_OPCODE_BRK; - break; + return TGSI_OPCODE_BRK; case OPCODE_CAL: - fullinst->Instruction.Opcode = TGSI_OPCODE_CAL; - fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size; - break; + return TGSI_OPCODE_CAL; case OPCODE_CMP: - fullinst->Instruction.Opcode = TGSI_OPCODE_CMP; - break; + return TGSI_OPCODE_CMP; case OPCODE_CONT: - fullinst->Instruction.Opcode = TGSI_OPCODE_CONT; - break; + return TGSI_OPCODE_CONT; case OPCODE_COS: - fullinst->Instruction.Opcode = TGSI_OPCODE_COS; - break; + return TGSI_OPCODE_COS; case OPCODE_DDX: - fullinst->Instruction.Opcode = TGSI_OPCODE_DDX; - break; + return TGSI_OPCODE_DDX; case OPCODE_DDY: - fullinst->Instruction.Opcode = TGSI_OPCODE_DDY; - break; + return TGSI_OPCODE_DDY; case OPCODE_DP2: - fullinst->Instruction.Opcode = TGSI_OPCODE_DP2; - break; + return TGSI_OPCODE_DP2; case OPCODE_DP2A: - fullinst->Instruction.Opcode = TGSI_OPCODE_DP2A; - break; + return TGSI_OPCODE_DP2A; case OPCODE_DP3: - fullinst->Instruction.Opcode = TGSI_OPCODE_DP3; - break; + return TGSI_OPCODE_DP3; case OPCODE_DP4: - fullinst->Instruction.Opcode = TGSI_OPCODE_DP4; - break; + return TGSI_OPCODE_DP4; case OPCODE_DPH: - fullinst->Instruction.Opcode = TGSI_OPCODE_DPH; - break; + return TGSI_OPCODE_DPH; case OPCODE_DST: - fullinst->Instruction.Opcode = TGSI_OPCODE_DST; - break; + return TGSI_OPCODE_DST; case OPCODE_ELSE: - fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE; - fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size; - break; + return TGSI_OPCODE_ELSE; case OPCODE_ENDIF: - fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF; - break; + return TGSI_OPCODE_ENDIF; case OPCODE_ENDLOOP: - fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP; - fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size; - break; + return TGSI_OPCODE_ENDLOOP; case OPCODE_ENDSUB: - fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB; - *insideSubroutine = GL_FALSE; - break; + return TGSI_OPCODE_ENDSUB; case OPCODE_EX2: - fullinst->Instruction.Opcode = TGSI_OPCODE_EX2; - break; + return TGSI_OPCODE_EX2; case OPCODE_EXP: - fullinst->Instruction.Opcode = TGSI_OPCODE_EXP; - break; + return TGSI_OPCODE_EXP; case OPCODE_FLR: - fullinst->Instruction.Opcode = TGSI_OPCODE_FLR; - break; + return TGSI_OPCODE_FLR; case OPCODE_FRC: - fullinst->Instruction.Opcode = TGSI_OPCODE_FRC; - break; + return TGSI_OPCODE_FRC; case OPCODE_IF: - fullinst->Instruction.Opcode = TGSI_OPCODE_IF; - fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size; - break; + return TGSI_OPCODE_IF; case OPCODE_TRUNC: - fullinst->Instruction.Opcode = TGSI_OPCODE_TRUNC; - break; + return TGSI_OPCODE_TRUNC; case OPCODE_KIL: - /* conditional */ - fullinst->Instruction.Opcode = TGSI_OPCODE_KIL; - break; + return TGSI_OPCODE_KIL; case OPCODE_KIL_NV: - /* predicated */ - assert(inst->DstReg.CondMask == COND_TR); - fullinst->Instruction.Opcode = TGSI_OPCODE_KILP; - break; + return TGSI_OPCODE_KILP; case OPCODE_LG2: - fullinst->Instruction.Opcode = TGSI_OPCODE_LG2; - break; + return TGSI_OPCODE_LG2; case OPCODE_LOG: - fullinst->Instruction.Opcode = TGSI_OPCODE_LOG; - break; + return TGSI_OPCODE_LOG; case OPCODE_LIT: - fullinst->Instruction.Opcode = TGSI_OPCODE_LIT; - break; + return TGSI_OPCODE_LIT; case OPCODE_LRP: - fullinst->Instruction.Opcode = TGSI_OPCODE_LRP; - break; + return TGSI_OPCODE_LRP; case OPCODE_MAD: - fullinst->Instruction.Opcode = TGSI_OPCODE_MAD; - break; + return TGSI_OPCODE_MAD; case OPCODE_MAX: - fullinst->Instruction.Opcode = TGSI_OPCODE_MAX; - break; + return TGSI_OPCODE_MAX; case OPCODE_MIN: - fullinst->Instruction.Opcode = TGSI_OPCODE_MIN; - break; + return TGSI_OPCODE_MIN; case OPCODE_MOV: - fullinst->Instruction.Opcode = TGSI_OPCODE_MOV; - break; + return TGSI_OPCODE_MOV; case OPCODE_MUL: - fullinst->Instruction.Opcode = TGSI_OPCODE_MUL; - break; + return TGSI_OPCODE_MUL; case OPCODE_NOISE1: - fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1; - break; + return TGSI_OPCODE_NOISE1; case OPCODE_NOISE2: - fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2; - break; + return TGSI_OPCODE_NOISE2; case OPCODE_NOISE3: - fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3; - break; + return TGSI_OPCODE_NOISE3; case OPCODE_NOISE4: - fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4; - break; + return TGSI_OPCODE_NOISE4; case OPCODE_NOP: - fullinst->Instruction.Opcode = TGSI_OPCODE_NOP; - break; + return TGSI_OPCODE_NOP; case OPCODE_NRM3: - fullinst->Instruction.Opcode = TGSI_OPCODE_NRM; - break; + return TGSI_OPCODE_NRM; case OPCODE_NRM4: - fullinst->Instruction.Opcode = TGSI_OPCODE_NRM4; - break; + return TGSI_OPCODE_NRM4; case OPCODE_POW: - fullinst->Instruction.Opcode = TGSI_OPCODE_POW; - break; + return TGSI_OPCODE_POW; case OPCODE_RCP: - fullinst->Instruction.Opcode = TGSI_OPCODE_RCP; - break; + return TGSI_OPCODE_RCP; case OPCODE_RET: - /* If RET is used inside main (not a real subroutine) we may want - * to execute END instead of RET. TBD... - */ - if (1 /* *insideSubroutine */) { - fullinst->Instruction.Opcode = TGSI_OPCODE_RET; - } - else { - /* inside main() pseudo-function */ - fullinst->Instruction.Opcode = TGSI_OPCODE_END; - } - break; + return TGSI_OPCODE_RET; case OPCODE_RSQ: - fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ; - break; + return TGSI_OPCODE_RSQ; case OPCODE_SCS: - fullinst->Instruction.Opcode = TGSI_OPCODE_SCS; - fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY; - break; + return TGSI_OPCODE_SCS; case OPCODE_SEQ: - fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ; - break; + return TGSI_OPCODE_SEQ; case OPCODE_SGE: - fullinst->Instruction.Opcode = TGSI_OPCODE_SGE; - break; + return TGSI_OPCODE_SGE; case OPCODE_SGT: - fullinst->Instruction.Opcode = TGSI_OPCODE_SGT; - break; + return TGSI_OPCODE_SGT; case OPCODE_SIN: - fullinst->Instruction.Opcode = TGSI_OPCODE_SIN; - break; + return TGSI_OPCODE_SIN; case OPCODE_SLE: - fullinst->Instruction.Opcode = TGSI_OPCODE_SLE; - break; + return TGSI_OPCODE_SLE; case OPCODE_SLT: - fullinst->Instruction.Opcode = TGSI_OPCODE_SLT; - break; + return TGSI_OPCODE_SLT; case OPCODE_SNE: - fullinst->Instruction.Opcode = TGSI_OPCODE_SNE; - break; + return TGSI_OPCODE_SNE; case OPCODE_SSG: - fullinst->Instruction.Opcode = TGSI_OPCODE_SSG; - break; + return TGSI_OPCODE_SSG; case OPCODE_SUB: - fullinst->Instruction.Opcode = TGSI_OPCODE_SUB; - break; + return TGSI_OPCODE_SUB; case OPCODE_SWZ: - fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ; - break; + return TGSI_OPCODE_SWZ; case OPCODE_TEX: - /* ordinary texture lookup */ - fullinst->Instruction.Opcode = TGSI_OPCODE_TEX; - fullinst->Instruction.NumSrcRegs = 2; - fullinst->InstructionExtTexture.Texture = - map_texture_target( inst->TexSrcTarget, inst->TexShadow ); - fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit; - break; + return TGSI_OPCODE_TEX; case OPCODE_TXB: - /* texture lookup with LOD bias */ - fullinst->Instruction.Opcode = TGSI_OPCODE_TXB; - fullinst->Instruction.NumSrcRegs = 2; - fullinst->InstructionExtTexture.Texture = - map_texture_target( inst->TexSrcTarget, inst->TexShadow ); - fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit; - break; + return TGSI_OPCODE_TXB; case OPCODE_TXD: - /* texture lookup with explicit partial derivatives */ - fullinst->Instruction.Opcode = TGSI_OPCODE_TXD; - fullinst->Instruction.NumSrcRegs = 4; - fullinst->InstructionExtTexture.Texture = - map_texture_target( inst->TexSrcTarget, inst->TexShadow ); - /* src[0] = coord, src[1] = d[strq]/dx, src[2] = d[strq]/dy */ - fullinst->FullSrcRegisters[3].SrcRegister.File = TGSI_FILE_SAMPLER; - fullinst->FullSrcRegisters[3].SrcRegister.Index = inst->TexSrcUnit; - break; + return TGSI_OPCODE_TXD; case OPCODE_TXL: - /* texture lookup with explicit LOD */ - fullinst->Instruction.Opcode = TGSI_OPCODE_TXL; - fullinst->Instruction.NumSrcRegs = 2; - fullinst->InstructionExtTexture.Texture = - map_texture_target( inst->TexSrcTarget, inst->TexShadow ); - fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit; - break; + return TGSI_OPCODE_TXL; case OPCODE_TXP: - /* texture lookup with divide by Q component */ - /* convert to TEX w/ special flag for division */ - fullinst->Instruction.Opcode = TGSI_OPCODE_TXP; - fullinst->Instruction.NumSrcRegs = 2; - fullinst->InstructionExtTexture.Texture = - map_texture_target( inst->TexSrcTarget, inst->TexShadow ); - fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit; - break; + return TGSI_OPCODE_TXP; case OPCODE_XPD: - fullinst->Instruction.Opcode = TGSI_OPCODE_XPD; - fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ; - break; + return TGSI_OPCODE_XPD; case OPCODE_END: - fullinst->Instruction.Opcode = TGSI_OPCODE_END; - break; + return TGSI_OPCODE_END; default: assert( 0 ); + return TGSI_OPCODE_NOP; } } -/** - * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens - */ -static struct tgsi_full_declaration -make_input_decl( - GLuint index, - GLboolean interpolate_info, - GLuint interpolate, - GLuint usage_mask, - GLboolean semantic_info, - GLuint semantic_name, - GLbitfield semantic_index, - GLbitfield input_flags) -{ - struct tgsi_full_declaration decl; - - assert(semantic_name < TGSI_SEMANTIC_COUNT); - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.UsageMask = usage_mask; - decl.Declaration.Semantic = semantic_info; - decl.DeclarationRange.First = index; - decl.DeclarationRange.Last = index; - if (semantic_info) { - decl.Semantic.SemanticName = semantic_name; - decl.Semantic.SemanticIndex = semantic_index; - } - if (interpolate_info) { - decl.Declaration.Interpolate = interpolate; - } - if (input_flags & PROG_PARAM_BIT_CENTROID) - decl.Declaration.Centroid = 1; - if (input_flags & PROG_PARAM_BIT_INVARIANT) - decl.Declaration.Invariant = 1; - - return decl; -} - -/** - * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens - */ -static struct tgsi_full_declaration -make_output_decl( - GLuint index, - GLuint semantic_name, - GLuint semantic_index, - GLuint usage_mask, - GLbitfield output_flags) -{ - struct tgsi_full_declaration decl; - - assert(semantic_name < TGSI_SEMANTIC_COUNT); - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.UsageMask = usage_mask; - decl.Declaration.Semantic = 1; - decl.DeclarationRange.First = index; - decl.DeclarationRange.Last = index; - decl.Semantic.SemanticName = semantic_name; - decl.Semantic.SemanticIndex = semantic_index; - if (output_flags & PROG_PARAM_BIT_CENTROID) - decl.Declaration.Centroid = 1; - if (output_flags & PROG_PARAM_BIT_INVARIANT) - decl.Declaration.Invariant = 1; - - return decl; -} - -static struct tgsi_full_declaration -make_temp_decl( - GLuint start_index, - GLuint end_index ) +static void +compile_instruction( + struct st_translate *t, + const struct prog_instruction *inst ) { - struct tgsi_full_declaration decl; - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.DeclarationRange.First = start_index; - decl.DeclarationRange.Last = end_index; - return decl; -} + struct ureg_program *ureg = t->ureg; + GLuint i; + struct ureg_dst dst[1]; + struct ureg_src src[4]; + unsigned num_dst; + unsigned num_src; -static struct tgsi_full_declaration -make_addr_decl( - GLuint start_index, - GLuint end_index ) -{ - struct tgsi_full_declaration decl; + num_dst = _mesa_num_inst_dst_regs( inst->Opcode ); + num_src = _mesa_num_inst_src_regs( inst->Opcode ); - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_ADDRESS; - decl.DeclarationRange.First = start_index; - decl.DeclarationRange.Last = end_index; - return decl; -} + if (num_dst) + dst[0] = translate_dst( t, + &inst->DstReg, + inst->SaturateMode ); -static struct tgsi_full_declaration -make_sampler_decl(GLuint index) -{ - struct tgsi_full_declaration decl; - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.DeclarationRange.First = index; - decl.DeclarationRange.Last = index; - return decl; -} + for (i = 0; i < num_src; i++) + src[i] = translate_src( t, &inst->SrcReg[i] ); -/** Reference into a constant buffer */ -static struct tgsi_full_declaration -make_constant_decl(GLuint first, GLuint last) -{ - struct tgsi_full_declaration decl; - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_CONSTANT; - decl.DeclarationRange.First = first; - decl.DeclarationRange.Last = last; - return decl; -} + switch( inst->Opcode ) { + case OPCODE_SWZ: + emit_swz( t, dst[0], &inst->SrcReg[0] ); + return; + case OPCODE_BGNLOOP: + case OPCODE_CAL: + case OPCODE_ELSE: + case OPCODE_ENDLOOP: + case OPCODE_IF: + assert(num_dst == 0); + ureg_label_insn( ureg, + translate_opcode( inst->Opcode ), + src, num_src, + get_label( t, inst->BranchTarget )); + return; + case OPCODE_TEX: + case OPCODE_TXB: + case OPCODE_TXD: + case OPCODE_TXL: + case OPCODE_TXP: + src[num_src++] = t->samplers[inst->TexSrcUnit]; + ureg_tex_insn( ureg, + translate_opcode( inst->Opcode ), + dst, num_dst, + translate_texture_target( inst->TexSrcTarget, + inst->TexShadow ), + src, num_src ); + return; -/** - * Find the temporaries which are used in the given program. - */ -static void -find_temporaries(const struct gl_program *program, - GLboolean tempsUsed[MAX_PROGRAM_TEMPS]) -{ - GLuint i, j; + case OPCODE_SCS: + dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY ); + ureg_insn( ureg, + translate_opcode( inst->Opcode ), + dst, num_dst, + src, num_src ); + break; - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) - tempsUsed[i] = GL_FALSE; + case OPCODE_XPD: + dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ ); + ureg_insn( ureg, + translate_opcode( inst->Opcode ), + dst, num_dst, + src, num_src ); + break; - for (i = 0; i < program->NumInstructions; i++) { - const struct prog_instruction *inst = program->Instructions + i; - const GLuint n = _mesa_num_inst_src_regs( inst->Opcode ); - for (j = 0; j < n; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) - tempsUsed[inst->SrcReg[j].Index] = GL_TRUE; - if (inst->DstReg.File == PROGRAM_TEMPORARY) - tempsUsed[inst->DstReg.Index] = GL_TRUE; - } + default: + ureg_insn( ureg, + translate_opcode( inst->Opcode ), + dst, num_dst, + src, num_src ); + break; } } /** - * Find an unused temporary in the tempsUsed array. + * Emit the TGSI instructions for inverting the WPOS y coordinate. */ -static int -find_free_temporary(GLboolean tempsUsed[MAX_PROGRAM_TEMPS]) -{ - int i; - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - if (!tempsUsed[i]) { - tempsUsed[i] = GL_TRUE; - return i; - } - } - return -1; -} - - -/** helper for building simple TGSI instruction, one src register */ static void -build_tgsi_instruction1(struct tgsi_full_instruction *inst, - int opcode, - int dstFile, int dstIndex, int writemask, - int srcFile1, int srcIndex1) +emit_inverted_wpos( struct st_translate *t, + const struct gl_program *program ) { - *inst = tgsi_default_full_instruction(); - - inst->Instruction.Opcode = opcode; - - inst->Instruction.NumDstRegs = 1; - inst->FullDstRegisters[0].DstRegister.File = dstFile; - inst->FullDstRegisters[0].DstRegister.Index = dstIndex; - inst->FullDstRegisters[0].DstRegister.WriteMask = writemask; + struct ureg_program *ureg = t->ureg; - inst->Instruction.NumSrcRegs = 1; - inst->FullSrcRegisters[0].SrcRegister.File = srcFile1; - inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1; -} - - -/** helper for building simple TGSI instruction, two src registers */ -static void -build_tgsi_instruction2(struct tgsi_full_instruction *inst, - int opcode, - int dstFile, int dstIndex, int writemask, - int srcFile1, int srcIndex1, - int srcFile2, int srcIndex2) -{ - *inst = tgsi_default_full_instruction(); - - inst->Instruction.Opcode = opcode; + /* Fragment program uses fragment position input. + * Need to replace instances of INPUT[WPOS] with temp T + * where T = INPUT[WPOS] by y is inverted. + */ + static const gl_state_index winSizeState[STATE_LENGTH] + = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 }; + + /* XXX: note we are modifying the incoming shader here! Need to + * do this before emitting the constant decls below, or this + * will be missed: + */ + unsigned winHeightConst = _mesa_add_state_reference(program->Parameters, + winSizeState); - inst->Instruction.NumDstRegs = 1; - inst->FullDstRegisters[0].DstRegister.File = dstFile; - inst->FullDstRegisters[0].DstRegister.Index = dstIndex; - inst->FullDstRegisters[0].DstRegister.WriteMask = writemask; - - inst->Instruction.NumSrcRegs = 2; - inst->FullSrcRegisters[0].SrcRegister.File = srcFile1; - inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1; - inst->FullSrcRegisters[1].SrcRegister.File = srcFile2; - inst->FullSrcRegisters[1].SrcRegister.Index = srcIndex2; -} + struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst ); + struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); + struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; + /* MOV wpos_temp, input[wpos] + */ + ureg_MOV( ureg, wpos_temp, wpos_input ); + /* SUB wpos_temp.y, winsize_const, wpos_input + */ + ureg_SUB( ureg, + ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), + winsize, + wpos_input); -/** - * Emit the TGSI instructions for inverting the WPOS y coordinate. - */ -static int -emit_inverted_wpos(struct tgsi_token *tokens, - int wpos_temp, - int winsize_const, - int wpos_input, - struct tgsi_header *header, int maxTokens) -{ - struct tgsi_full_instruction fullinst; - int ti = 0; - - /* MOV wpos_temp.xzw, input[wpos]; */ - build_tgsi_instruction1(&fullinst, - TGSI_OPCODE_MOV, - TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_XZW, - TGSI_FILE_INPUT, 0); - - ti += tgsi_build_full_instruction(&fullinst, - &tokens[ti], - header, - maxTokens - ti); - - /* SUB wpos_temp.y, const[winsize_const] - input[wpos_input]; */ - build_tgsi_instruction2(&fullinst, - TGSI_OPCODE_SUB, - TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_Y, - TGSI_FILE_CONSTANT, winsize_const, - TGSI_FILE_INPUT, wpos_input); - - ti += tgsi_build_full_instruction(&fullinst, - &tokens[ti], - header, - maxTokens - ti); - - return ti; + /* Use wpos_temp as position input from here on: + */ + t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); } - - /** * Translate Mesa program to TGSI format. * \param program the program to translate @@ -862,20 +676,19 @@ emit_inverted_wpos(struct tgsi_token *tokens, * \param inputMapping maps Mesa fragment program inputs to TGSI generic * input indexes * \param inputSemanticName the TGSI_SEMANTIC flag for each input - * \param inputSemanticIndex the semantic index (ex: which texcoord) for each input + * \param inputSemanticIndex the semantic index (ex: which texcoord) for + * each input * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input - * \param numOutputs number of output registers used * \param outputMapping maps Mesa fragment program outputs to TGSI * generic outputs * \param outputSemanticName the TGSI_SEMANTIC flag for each output - * \param outputSemanticIndex the semantic index (ex: which texcoord) for each output - * \param tokens array to store translated tokens in - * \param maxTokens size of the tokens array + * \param outputSemanticIndex the semantic index (ex: which texcoord) for + * each output * - * \return number of tokens placed in 'tokens' buffer, or zero if error + * \return array of translated tokens, caller's responsibility to free */ -GLuint +const struct tgsi_token * st_translate_mesa_program( GLcontext *ctx, uint procType, @@ -890,252 +703,124 @@ st_translate_mesa_program( const GLuint outputMapping[], const ubyte outputSemanticName[], const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[], - struct tgsi_token *tokens, - GLuint maxTokens ) + const GLbitfield outputFlags[] ) { - GLuint i; - GLuint ti; /* token index */ - struct tgsi_header *header; - struct tgsi_processor *processor; - GLuint preamble_size = 0; - GLuint immediates[1000]; - GLuint numImmediates = 0; - GLboolean insideSubroutine = GL_FALSE; - GLboolean indirectAccess = GL_FALSE; - GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1]; - GLint wposTemp = -1, winHeightConst = -1; - - assert(procType == TGSI_PROCESSOR_FRAGMENT || - procType == TGSI_PROCESSOR_VERTEX); - - find_temporaries(program, tempsUsed); - - if (procType == TGSI_PROCESSOR_FRAGMENT) { - if (program->InputsRead & FRAG_BIT_WPOS) { - /* Fragment program uses fragment position input. - * Need to replace instances of INPUT[WPOS] with temp T - * where T = INPUT[WPOS] by y is inverted. - */ - static const gl_state_index winSizeState[STATE_LENGTH] - = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 }; - winHeightConst = _mesa_add_state_reference(program->Parameters, - winSizeState); - wposTemp = find_free_temporary(tempsUsed); - } - } - + struct st_translate translate, *t; + struct ureg_program *ureg; + const struct tgsi_token *tokens = NULL; + unsigned i; - *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + t = &translate; + memset(t, 0, sizeof *t); - header = (struct tgsi_header *) &tokens[1]; - *header = tgsi_build_header(); + t->procType = procType; + t->inputMapping = inputMapping; + t->outputMapping = outputMapping; + t->ureg = ureg_create( procType ); + if (t->ureg == NULL) + return NULL; - processor = (struct tgsi_processor *) &tokens[2]; - *processor = tgsi_build_processor( procType, header ); + ureg = t->ureg; - ti = 3; + /*_mesa_print_program(program);*/ /* * Declare input attributes. */ if (procType == TGSI_PROCESSOR_FRAGMENT) { for (i = 0; i < numInputs; i++) { - struct tgsi_full_declaration fulldecl; - fulldecl = make_input_decl(i, - GL_TRUE, interpMode[i], - TGSI_WRITEMASK_XYZW, - GL_TRUE, inputSemanticName[i], - inputSemanticIndex[i], - inputFlags[i]); - ti += tgsi_build_full_declaration(&fulldecl, - &tokens[ti], - header, - maxTokens - ti ); + t->inputs[i] = ureg_DECL_fs_input(ureg, + inputSemanticName[i], + inputSemanticIndex[i], + interpMode[i]); } - } - else { - /* vertex prog */ - /* XXX: this could probaby be merged with the clause above. - * the only difference is the semantic tags. - */ - for (i = 0; i < numInputs; i++) { - struct tgsi_full_declaration fulldecl; - fulldecl = make_input_decl(i, - GL_FALSE, 0, - TGSI_WRITEMASK_XYZW, - GL_FALSE, 0, 0, - inputFlags[i]); - ti += tgsi_build_full_declaration(&fulldecl, - &tokens[ti], - header, - maxTokens - ti ); + + if (program->InputsRead & FRAG_BIT_WPOS) { + /* Must do this after setting up t->inputs, and before + * emitting constant references, below: + */ + emit_inverted_wpos( t, program ); } - } - /* - * Declare output attributes. - */ - if (procType == TGSI_PROCESSOR_FRAGMENT) { + /* + * Declare output attributes. + */ for (i = 0; i < numOutputs; i++) { - struct tgsi_full_declaration fulldecl; switch (outputSemanticName[i]) { case TGSI_SEMANTIC_POSITION: - fulldecl = make_output_decl(i, - TGSI_SEMANTIC_POSITION, /* Z / Depth */ - outputSemanticIndex[i], - TGSI_WRITEMASK_Z, - outputFlags[i]); + t->outputs[i] = ureg_DECL_output( ureg, + TGSI_SEMANTIC_POSITION, /* Z / Depth */ + outputSemanticIndex[i] ); + + t->outputs[i] = ureg_writemask( t->outputs[i], + TGSI_WRITEMASK_Z ); break; case TGSI_SEMANTIC_COLOR: - fulldecl = make_output_decl(i, - TGSI_SEMANTIC_COLOR, - outputSemanticIndex[i], - TGSI_WRITEMASK_XYZW, - outputFlags[i]); + t->outputs[i] = ureg_DECL_output( ureg, + TGSI_SEMANTIC_COLOR, + outputSemanticIndex[i] ); break; default: assert(0); return 0; } - ti += tgsi_build_full_declaration(&fulldecl, - &tokens[ti], - header, - maxTokens - ti ); } } else { - /* vertex prog */ - for (i = 0; i < numOutputs; i++) { - struct tgsi_full_declaration fulldecl; - fulldecl = make_output_decl(i, - outputSemanticName[i], - outputSemanticIndex[i], - TGSI_WRITEMASK_XYZW, - outputFlags[i]); - ti += tgsi_build_full_declaration(&fulldecl, - &tokens[ti], - header, - maxTokens - ti ); + for (i = 0; i < numInputs; i++) { + t->inputs[i] = ureg_DECL_vs_input(ureg, i); } - } - /* temporary decls */ - { - GLboolean inside_range = GL_FALSE; - GLuint start_range = 0; - - tempsUsed[MAX_PROGRAM_TEMPS] = GL_FALSE; - for (i = 0; i < MAX_PROGRAM_TEMPS + 1; i++) { - if (tempsUsed[i] && !inside_range) { - inside_range = GL_TRUE; - start_range = i; - } - else if (!tempsUsed[i] && inside_range) { - struct tgsi_full_declaration fulldecl; - - inside_range = GL_FALSE; - fulldecl = make_temp_decl( start_range, i - 1 ); - ti += tgsi_build_full_declaration( - &fulldecl, - &tokens[ti], - header, - maxTokens - ti ); - } + for (i = 0; i < numOutputs; i++) { + t->outputs[i] = ureg_DECL_output( ureg, + outputSemanticName[i], + outputSemanticIndex[i] ); } } /* Declare address register. - */ + */ if (program->NumAddressRegs > 0) { - struct tgsi_full_declaration fulldecl; - assert( program->NumAddressRegs == 1 ); - - fulldecl = make_addr_decl( 0, 0 ); - ti += tgsi_build_full_declaration( - &fulldecl, - &tokens[ti], - header, - maxTokens - ti ); - - indirectAccess = GL_TRUE; + t->address[0] = ureg_DECL_address( ureg ); } - /* immediates/literals */ - memset(immediates, ~0, sizeof(immediates)); - /* Emit immediates only when there is no address register in use. - * FIXME: Be smarter and recognize param arrays -- indirect addressing is - * only valid within the referenced array. + /* Emit constants and immediates. Mesa uses a single index space + * for these, so we put all the translated regs in t->constants. */ - if (program->Parameters && !indirectAccess) { - for (i = 0; i < program->Parameters->NumParameters; i++) { - if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) { - struct tgsi_full_immediate fullimm; - - fullimm = make_immediate( program->Parameters->ParameterValues[i], 4 ); - ti += tgsi_build_full_immediate( - &fullimm, - &tokens[ti], - header, - maxTokens - ti ); - immediates[i] = numImmediates; - numImmediates++; - } - } - } - - /* constant buffer refs */ if (program->Parameters) { - GLint start = -1, end = -1; - + + t->constants = CALLOC( program->Parameters->NumParameters, + sizeof t->constants[0] ); + if (t->constants == NULL) + goto out; + for (i = 0; i < program->Parameters->NumParameters; i++) { - GLboolean emit = (i == program->Parameters->NumParameters - 1); - GLboolean matches; - switch (program->Parameters->Parameters[i].Type) { case PROGRAM_ENV_PARAM: case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: case PROGRAM_UNIFORM: - matches = GL_TRUE; + t->constants[i] = ureg_DECL_constant( ureg, i ); break; + + /* Emit immediates only when there is no address register + * in use. FIXME: Be smarter and recognize param arrays: + * indirect addressing is only valid within the referenced + * array. + */ case PROGRAM_CONSTANT: - matches = indirectAccess; + if (program->NumAddressRegs > 0) + t->constants[i] = ureg_DECL_constant( ureg, i ); + else + t->constants[i] = + ureg_DECL_immediate( ureg, + program->Parameters->ParameterValues[i], + 4 ); break; default: - matches = GL_FALSE; - } - - if (matches) { - if (start == -1) { - /* begin a sequence */ - start = i; - end = i; - } - else { - /* continue sequence */ - end = i; - } - } - else { - if (start != -1) { - /* end of sequence */ - emit = GL_TRUE; - } - } - - if (emit && start >= 0) { - struct tgsi_full_declaration fulldecl; - - fulldecl = make_constant_decl( start, end ); - ti += tgsi_build_full_declaration( - &fulldecl, - &tokens[ti], - header, - maxTokens - ti ); - start = end = -1; + break; } } } @@ -1143,58 +828,44 @@ st_translate_mesa_program( /* texture samplers */ for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { if (program->SamplersUsed & (1 << i)) { - struct tgsi_full_declaration fulldecl; - - fulldecl = make_sampler_decl( i ); - ti += tgsi_build_full_declaration( - &fulldecl, - &tokens[ti], - header, - maxTokens - ti ); + t->samplers[i] = ureg_DECL_sampler( ureg, i ); } } - /* invert WPOS fragment input */ - if (wposTemp >= 0) { - ti += emit_inverted_wpos(&tokens[ti], wposTemp, winHeightConst, - inputMapping[FRAG_ATTRIB_WPOS], - header, maxTokens - ti); - preamble_size = 2; /* two instructions added */ + /* Emit each instruction in turn: + */ + for (i = 0; i < program->NumInstructions; i++) { + set_insn_start( t, ureg_get_instruction_number( ureg )); + compile_instruction( t, &program->Instructions[i] ); } - for (i = 0; i < program->NumInstructions; i++) { - struct tgsi_full_instruction fullinst; - - compile_instruction( - &program->Instructions[i], - &fullinst, - inputMapping, - outputMapping, - immediates, - indirectAccess, - preamble_size, - procType, - &insideSubroutine, - wposTemp); - - ti += tgsi_build_full_instruction( - &fullinst, - &tokens[ti], - header, - maxTokens - ti ); + /* Fix up all emitted labels: + */ + for (i = 0; i < t->labels_count; i++) { + ureg_fixup_label( ureg, + t->labels[i].token, + t->insn[t->labels[i].branch_target] ); + } + + tokens = ureg_get_tokens( ureg, NULL ); + ureg_destroy( ureg ); + +out: + FREE(t->insn); + FREE(t->labels); + FREE(t->constants); + + if (t->error) { + debug_printf("%s: translate error flag set\n", __FUNCTION__); + FREE((void *)tokens); + tokens = NULL; } -#if DEBUG - if(!tgsi_sanity_check(tokens)) { - debug_printf("Due to sanity check failure(s) above the following shader program is invalid:\n"); - debug_printf("\nOriginal program:\n%s", program->String); - debug_printf("\nMesa program:\n"); + if (!tokens) { + debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__); _mesa_print_program(program); - debug_printf("\nTGSI program:\n"); - tgsi_dump(tokens, 0); assert(0); } -#endif - return ti; + return tokens; } diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h index b465b3bddcf..679d0ddd41b 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.h +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h @@ -39,7 +39,7 @@ extern "C" { struct tgsi_token; struct gl_program; -GLuint +const struct tgsi_token * st_translate_mesa_program( GLcontext *ctx, uint procType, @@ -54,9 +54,7 @@ st_translate_mesa_program( const GLuint outputMapping[], const ubyte outputSemanticName[], const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[], - struct tgsi_token *tokens, - GLuint maxTokens ); + const GLbitfield outputFlags[] ); #if defined __cplusplus diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index d2da20ae424..5f9d2a6dad9 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -49,9 +49,6 @@ #include "cso_cache/cso_context.h" -#define ST_MAX_SHADER_TOKENS (8 * 1024) - - #define TGSI_DEBUG 0 @@ -70,12 +67,9 @@ st_translate_vertex_program(struct st_context *st, const ubyte *outputSemanticIndex) { struct pipe_context *pipe = st->pipe; - struct tgsi_token *tokens; GLuint defaultOutputMapping[VERT_RESULT_MAX]; - struct pipe_shader_state vs; GLuint attr, i; GLuint num_generic = 0; - GLuint num_tokens; ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS]; ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS]; @@ -88,14 +82,7 @@ st_translate_vertex_program(struct st_context *st, GLbitfield input_flags[MAX_PROGRAM_INPUTS]; GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; - tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens); - if(!tokens) { - /* FIXME: propagate error to the caller */ - assert(0); - return; - } - - memset(&vs, 0, sizeof(vs)); +// memset(&vs, 0, sizeof(vs)); memset(input_flags, 0, sizeof(input_flags)); memset(output_flags, 0, sizeof(output_flags)); @@ -338,43 +325,32 @@ st_translate_vertex_program(struct st_context *st, stvp->driver_shader = NULL; } - /* XXX: fix static allocation of tokens: - */ - num_tokens = st_translate_mesa_program(st->ctx, - TGSI_PROCESSOR_VERTEX, - &stvp->Base.Base, - /* inputs */ - vs_num_inputs, - stvp->input_to_index, - vs_input_semantic_name, - vs_input_semantic_index, - NULL, - input_flags, - /* outputs */ - vs_num_outputs, - outputMapping, - vs_output_semantic_name, - vs_output_semantic_index, - output_flags, - /* tokenized result */ - tokens, ST_MAX_SHADER_TOKENS); - - assert(num_tokens < ST_MAX_SHADER_TOKENS); - - vs.tokens = (struct tgsi_token *) - _mesa_realloc(tokens, - ST_MAX_SHADER_TOKENS * sizeof *tokens, - num_tokens * sizeof *tokens); + stvp->state.tokens = + st_translate_mesa_program(st->ctx, + TGSI_PROCESSOR_VERTEX, + &stvp->Base.Base, + /* inputs */ + vs_num_inputs, + stvp->input_to_index, + vs_input_semantic_name, + vs_input_semantic_index, + NULL, + input_flags, + /* outputs */ + vs_num_outputs, + outputMapping, + vs_output_semantic_name, + vs_output_semantic_index, + output_flags ); stvp->num_inputs = vs_num_inputs; - stvp->state = vs; /* struct copy */ - stvp->driver_shader = pipe->create_vs_state(pipe, &vs); + stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state); if (0) _mesa_print_program(&stvp->Base.Base); if (TGSI_DEBUG) - tgsi_dump( vs.tokens, 0 ); + tgsi_dump( stvp->state.tokens, 0 ); } @@ -383,7 +359,6 @@ st_translate_vertex_program(struct st_context *st, * Translate a Mesa fragment shader into a TGSI shader. * \param inputMapping to map fragment program input registers to TGSI * input slots - * \param tokensOut destination for TGSI tokens * \return pointer to cached pipe_shader object. */ void @@ -392,16 +367,13 @@ st_translate_fragment_program(struct st_context *st, const GLuint inputMapping[]) { struct pipe_context *pipe = st->pipe; - struct tgsi_token *tokens; GLuint outputMapping[FRAG_RESULT_MAX]; GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; - struct pipe_shader_state fs; GLuint interpMode[16]; /* XXX size? */ GLuint attr; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; GLuint vslot = 0; GLuint num_generic = 0; - GLuint num_tokens; uint fs_num_inputs = 0; @@ -412,14 +384,7 @@ st_translate_fragment_program(struct st_context *st, GLbitfield input_flags[MAX_PROGRAM_INPUTS]; GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; - tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens); - if(!tokens) { - /* FIXME: propagate error to the caller */ - assert(0); - return; - } - - memset(&fs, 0, sizeof(fs)); +// memset(&fs, 0, sizeof(fs)); memset(input_flags, 0, sizeof(input_flags)); memset(output_flags, 0, sizeof(output_flags)); @@ -541,42 +506,31 @@ st_translate_fragment_program(struct st_context *st, if (!inputMapping) inputMapping = defaultInputMapping; - /* XXX: fix static allocation of tokens: - */ - num_tokens = st_translate_mesa_program(st->ctx, - TGSI_PROCESSOR_FRAGMENT, - &stfp->Base.Base, - /* inputs */ - fs_num_inputs, - inputMapping, - stfp->input_semantic_name, - stfp->input_semantic_index, - interpMode, - input_flags, - /* outputs */ - fs_num_outputs, - outputMapping, - fs_output_semantic_name, - fs_output_semantic_index, - output_flags, - /* tokenized result */ - tokens, ST_MAX_SHADER_TOKENS); - - assert(num_tokens < ST_MAX_SHADER_TOKENS); - - fs.tokens = (struct tgsi_token *) - _mesa_realloc(tokens, - ST_MAX_SHADER_TOKENS * sizeof *tokens, - num_tokens * sizeof *tokens); - - stfp->state = fs; /* struct copy */ - stfp->driver_shader = pipe->create_fs_state(pipe, &fs); + stfp->state.tokens = + st_translate_mesa_program(st->ctx, + TGSI_PROCESSOR_FRAGMENT, + &stfp->Base.Base, + /* inputs */ + fs_num_inputs, + inputMapping, + stfp->input_semantic_name, + stfp->input_semantic_index, + interpMode, + input_flags, + /* outputs */ + fs_num_outputs, + outputMapping, + fs_output_semantic_name, + fs_output_semantic_index, + output_flags ); + + stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state); if (0) _mesa_print_program(&stfp->Base.Base); if (TGSI_DEBUG) - tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ ); + tgsi_dump( stfp->state.tokens, 0/*TGSI_DUMP_VERBOSE*/ ); } diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index f9ff9ad6a42..4f19d19ab12 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -299,11 +299,6 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, &ctx->DefaultPacking, texObj, texImage); _mesa_free(image); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } @@ -375,11 +370,6 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, &ctx->DefaultPacking, texObj, texImage); _mesa_free(image); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } @@ -444,11 +434,6 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level, &ctx->DefaultPacking, texObj, texImage); _mesa_free(image); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } @@ -520,11 +505,6 @@ _swrast_copy_texsubimage2d( GLcontext *ctx, &ctx->DefaultPacking, texObj, texImage); _mesa_free(image); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } @@ -593,9 +573,4 @@ _swrast_copy_texsubimage3d( GLcontext *ctx, &ctx->DefaultPacking, texObj, texImage); _mesa_free(image); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); - } } diff --git a/src/xvmc/context.c b/src/xvmc/context.c index 273f6580292..9c2b6648bb5 100644 --- a/src/xvmc/context.c +++ b/src/xvmc/context.c @@ -1,6 +1,7 @@ #include <assert.h> #include <X11/Xlib.h> #include <X11/extensions/XvMClib.h> +#include <X11/Xlibint.h> #include <pipe/p_context.h> #include <vl_display.h> #include <vl_screen.h> @@ -137,6 +138,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i struct vlScreen *vl_scrn; struct vlContext *vl_ctx; struct pipe_context *pipe; + Display *dpy = display; assert(display); @@ -176,6 +178,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i context->port = port; context->privData = vl_ctx; + SyncHandle(); return Success; } diff --git a/src/xvmc/subpicture.c b/src/xvmc/subpicture.c index c8f70c90d0c..09e9c98e6af 100644 --- a/src/xvmc/subpicture.c +++ b/src/xvmc/subpicture.c @@ -2,6 +2,7 @@ #include <X11/Xlib.h> #include <X11/extensions/Xvlib.h> #include <X11/extensions/XvMC.h> +#include <X11/Xlibint.h> Status XvMCCreateSubpicture ( @@ -13,6 +14,7 @@ Status XvMCCreateSubpicture int xvimage_id ) { + Display *dpy = display; assert(display); if (!context) @@ -38,7 +40,8 @@ Status XvMCCreateSubpicture subpicture->component_order[2] = 0; subpicture->component_order[3] = 0; /* TODO: subpicture->privData = ;*/ - + + SyncHandle(); return Success; } diff --git a/src/xvmc/surface.c b/src/xvmc/surface.c index 7c5f45bd346..fea351b84f0 100644 --- a/src/xvmc/surface.c +++ b/src/xvmc/surface.c @@ -1,6 +1,7 @@ #include <assert.h> #include <X11/Xlib.h> #include <X11/extensions/XvMC.h> +#include <X11/Xlibint.h> #include <vl_display.h> #include <vl_screen.h> #include <vl_context.h> @@ -61,6 +62,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su { struct vlContext *vl_ctx; struct vlSurface *vl_sfc; + Display *dpy = display; assert(display); @@ -90,6 +92,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su surface->height = context->height; surface->privData = vl_sfc; + SyncHandle(); return Success; } |