mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
Merge branch 'master' into r300-compiler
This commit is contained in:
commit
6d25b9125e
460 changed files with 788562 additions and 16950 deletions
6
Makefile
6
Makefile
|
|
@ -415,6 +415,12 @@ DEMO_FILES = \
|
|||
$(DIRECTORY)/progs/demos/README \
|
||||
$(DIRECTORY)/progs/fbdev/Makefile \
|
||||
$(DIRECTORY)/progs/fbdev/glfbdevtest.c \
|
||||
$(DIRECTORY)/progs/objviewer/*.[ch] \
|
||||
$(DIRECTORY)/progs/objviewer/*.obj \
|
||||
$(DIRECTORY)/progs/objviewer/*.mtl \
|
||||
$(DIRECTORY)/progs/objviewer/*.rgb \
|
||||
$(DIRECTORY)/progs/objviewer/Makefile \
|
||||
$(DIRECTORY)/progs/objviewer/README.txt \
|
||||
$(DIRECTORY)/progs/osdemos/Makefile \
|
||||
$(DIRECTORY)/progs/osdemos/*.c \
|
||||
$(DIRECTORY)/progs/xdemos/Makefile* \
|
||||
|
|
|
|||
|
|
@ -87,14 +87,14 @@ SRC_DIRS = mesa gallium egl gallium/winsys glu glut/glx glew glw
|
|||
GLU_DIRS = sgi
|
||||
DRIVER_DIRS = x11 osmesa
|
||||
# Which subdirs under $(TOP)/progs/ to enter:
|
||||
PROGRAM_DIRS = demos redbook samples glsl xdemos
|
||||
PROGRAM_DIRS = demos redbook samples glsl objviewer xdemos
|
||||
|
||||
# EGL directories
|
||||
EGL_DRIVERS_DIRS = demo
|
||||
|
||||
# Gallium directories and
|
||||
GALLIUM_DIRS = auxiliary drivers state_trackers
|
||||
GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices
|
||||
GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices vl
|
||||
GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
|
||||
GALLIUM_DRIVERS_DIRS = softpipe i915simple failover trace identity
|
||||
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
|
||||
|
|
|
|||
|
|
@ -417,7 +417,7 @@ WINDOW_SYSTEM=""
|
|||
GALLIUM_DIRS="auxiliary drivers state_trackers"
|
||||
GALLIUM_WINSYS_DIRS=""
|
||||
GALLIUM_WINSYS_DRM_DIRS=""
|
||||
GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices"
|
||||
GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices vl"
|
||||
GALLIUM_DRIVERS_DIRS="softpipe failover trace identity"
|
||||
GALLIUM_STATE_TRACKERS_DIRS=""
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,17 @@
|
|||
|
||||
<H1>News</H1>
|
||||
|
||||
<h2>September 28, 2009</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.6.html">Mesa 7.6</a> is released. This is a new feature
|
||||
release. Those especially concerned about stability may want to wait for the
|
||||
follow-on 7.6.1 bug-fix release.
|
||||
</p>
|
||||
<p>
|
||||
<a href="relnotes-7.5.2.html">Mesa 7.5.2</a> is also released.
|
||||
This is a stable release fixing bugs since the 7.5.1 release.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>September 3, 2009</h2>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.5.2 Release Notes, (date tbd)</H1>
|
||||
<H1>Mesa 7.5.2 Release Notes, 28 September 2009</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.5.2 is a bug-fix release fixing issues found since the 7.5.1 release.
|
||||
|
|
@ -31,7 +31,15 @@ for DRI hardware acceleration.
|
|||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
tbd
|
||||
43a90191dd9f76cd65dcc1ac91f3be70 MesaLib-7.5.2.tar.gz
|
||||
94e47a499f1226803869c2e37a6a8e3a MesaLib-7.5.2.tar.bz2
|
||||
1ecb822b567ad67a0617361d45206b67 MesaLib-7.5.2.zip
|
||||
2718fdce7e075911d6147beb8f27104b MesaDemos-7.5.2.tar.gz
|
||||
4e0f5ccd58afe21eddcd94327d926e86 MesaDemos-7.5.2.tar.bz2
|
||||
f621f8c223b278d7c8e49a012d56ca25 MesaDemos-7.5.2.zip
|
||||
83c16c1d6bcfcc3f97aab5d2fe430b4c MesaGLUT-7.5.2.tar.gz
|
||||
e5d03bedae369ea3705783573bb33813 MesaGLUT-7.5.2.tar.bz2
|
||||
e82ba28e00d653e6f437d32be8ca8481 MesaGLUT-7.5.2.zip
|
||||
</pre>
|
||||
|
||||
|
||||
|
|
@ -49,8 +57,11 @@ tbd
|
|||
(such as bug 23946)
|
||||
<li>glUseProgram() is now compiled into display lists (bug 23746).
|
||||
<li>glUniform functions are now compiled into display lists
|
||||
<li>Auto mipmap generation didn't work reliably with Gallium.
|
||||
<li>Fixed random number usage in GLX code.
|
||||
<li>Fixed invalid GL_OUT_OF_MEMORY error sometimes raised by glTexSubImage2D
|
||||
when using Gallium.
|
||||
</ul>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
46
docs/relnotes-7.6.1.html
Normal file
46
docs/relnotes-7.6.1.html
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<HTML>
|
||||
|
||||
<TITLE>Mesa Release Notes</TITLE>
|
||||
|
||||
<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
|
||||
|
||||
<BODY>
|
||||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.6.1 Release Notes, (date tbd)</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.6.1 is a bug-fix release fixing issues since version 7.6.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 7.6.1 implements the OpenGL 2.1 API, but the version reported by
|
||||
glGetString(GL_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 2.1.
|
||||
</p>
|
||||
<p>
|
||||
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
|
||||
for DRI hardware acceleration.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
tbd
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>New features</h2>
|
||||
<ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
<ul>
|
||||
<li>Fixed crash caused by glXCopyContext() and glXDestroyContext(), bug 24217
|
||||
<li>glXQueryContext(GLX_RENDER_TYPE) returned wrong values (bug 24211)
|
||||
<li>GLSL sqrt(0) returned unpredictable results
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.6 Release Notes / date TBD</H1>
|
||||
<H1>Mesa 7.6 Release Notes, 28 September 2009</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.6 is a new development release.
|
||||
|
|
@ -28,7 +28,15 @@ for DRI hardware acceleration.
|
|||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
tbd
|
||||
5ffa7d7abf8973f57a1bc4f813e6dade MesaLib-7.6.tar.gz
|
||||
8c75f90cd0303cfac9e4b6d54f6759ca MesaLib-7.6.tar.bz2
|
||||
27fcfd69708599c978cb34ba5cd363e1 MesaLib-7.6.zip
|
||||
e7befb3ae604f591806194a4da445628 MesaDemos-7.6.tar.gz
|
||||
0ede7adf217951acd90dbe4551210c07 MesaDemos-7.6.tar.bz2
|
||||
ed9298409cf6613bc0964525ca4afc8a MesaDemos-7.6.zip
|
||||
666955668e44ff14acf7d15dc78407d3 MesaGLUT-7.6.tar.gz
|
||||
b8b59706f827d18d1b784a0ff98b4dc2 MesaGLUT-7.6.tar.bz2
|
||||
c49c19c2bbef4f3b7f1389974dff25f4 MesaGLUT-7.6.zip
|
||||
</pre>
|
||||
|
||||
|
||||
|
|
@ -72,10 +80,5 @@ This was written by Zack Rusin at Tungsten Graphics.
|
|||
buffers (GLSL uniforms)
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ tbd
|
|||
<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>
|
||||
<li>Wavefront .obj file loader/viewer demo (progs/demos/objviewer)
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ The release notes summarize what's new or changed in each Mesa release.
|
|||
|
||||
<UL>
|
||||
<LI><A HREF="relnotes-7.7.html">7.7 release notes</A>
|
||||
<LI><A HREF="relnotes-7.6.1.html">7.6.1 release notes</A>
|
||||
<LI><A HREF="relnotes-7.6.html">7.6 release notes</A>
|
||||
<LI><A HREF="relnotes-7.5.2.html">7.5.2 release notes</A>
|
||||
<LI><A HREF="relnotes-7.5.1.html">7.5.1 release notes</A>
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ static GLboolean supportFBO = GL_FALSE;
|
|||
static GLboolean supportSeamless = GL_FALSE;
|
||||
static GLboolean seamless = GL_FALSE;
|
||||
static GLuint TexObj = 0;
|
||||
static GLint T0 = 0;
|
||||
static GLint Frames = 0;
|
||||
|
||||
|
||||
static struct {
|
||||
|
|
@ -283,6 +285,20 @@ static void draw( void )
|
|||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
|
||||
Frames++;
|
||||
|
||||
{
|
||||
GLint t = glutGet(GLUT_ELAPSED_TIME);
|
||||
if (t - T0 >= 5000) {
|
||||
GLfloat seconds = (t - T0) / 1000.0;
|
||||
GLfloat fps = Frames / seconds;
|
||||
printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
|
||||
fflush(stdout);
|
||||
T0 = t;
|
||||
Frames = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,14 +34,9 @@ TestScreens(EGLDisplay dpy)
|
|||
* Print table of all available configurations.
|
||||
*/
|
||||
static void
|
||||
PrintConfigs(EGLDisplay d)
|
||||
PrintConfigs(EGLDisplay d, EGLConfig *configs, EGLint numConfigs)
|
||||
{
|
||||
EGLConfig *configs;
|
||||
EGLint numConfigs, i;
|
||||
|
||||
eglGetConfigs(d, NULL, 0, &numConfigs);
|
||||
configs = malloc(sizeof(*configs) *numConfigs);
|
||||
eglGetConfigs(d, configs, numConfigs, &numConfigs);
|
||||
EGLint i;
|
||||
|
||||
printf("Configurations:\n");
|
||||
printf(" bf lv d st colorbuffer dp st supported \n");
|
||||
|
|
@ -83,7 +78,6 @@ PrintConfigs(EGLDisplay d)
|
|||
red, green, blue, alpha,
|
||||
depth, stencil, surfString);
|
||||
}
|
||||
free(configs);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -94,7 +88,8 @@ main(int argc, char *argv[])
|
|||
int maj, min;
|
||||
EGLContext ctx;
|
||||
EGLSurface pbuffer;
|
||||
EGLConfig configs[10];
|
||||
EGLConfig *configs;
|
||||
EGLint numConfigs;
|
||||
EGLBoolean b;
|
||||
const EGLint pbufAttribs[] = {
|
||||
EGL_WIDTH, 500,
|
||||
|
|
@ -102,10 +97,7 @@ main(int argc, char *argv[])
|
|||
EGL_NONE
|
||||
};
|
||||
|
||||
/*
|
||||
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
*/
|
||||
EGLDisplay d = eglGetDisplay((EGLNativeDisplayType) "!EGL_i915");
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
|
|
@ -116,7 +108,11 @@ main(int argc, char *argv[])
|
|||
printf("EGL version = %d.%d\n", maj, min);
|
||||
printf("EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR));
|
||||
|
||||
PrintConfigs(d);
|
||||
eglGetConfigs(d, NULL, 0, &numConfigs);
|
||||
configs = malloc(sizeof(*configs) *numConfigs);
|
||||
eglGetConfigs(d, configs, numConfigs, &numConfigs);
|
||||
|
||||
PrintConfigs(d, configs, numConfigs);
|
||||
|
||||
ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
|
||||
if (ctx == EGL_NO_CONTEXT) {
|
||||
|
|
@ -130,6 +126,8 @@ main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
free(configs);
|
||||
|
||||
b = eglMakeCurrent(d, pbuffer, pbuffer, ctx);
|
||||
if (!b) {
|
||||
printf("make current failed\n");
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
|
@ -119,10 +120,7 @@ main(int argc, char *argv[])
|
|||
EGLScreenMESA screen;
|
||||
EGLint count;
|
||||
|
||||
/*
|
||||
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
*/
|
||||
EGLDisplay d = eglGetDisplay((EGLNativeDisplayType) "!EGL_i915");
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
|
|
@ -132,6 +130,11 @@ main(int argc, char *argv[])
|
|||
|
||||
printf("EGL version = %d.%d\n", maj, min);
|
||||
printf("EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR));
|
||||
if (!strstr(eglQueryString(d, EGL_EXTENSIONS),
|
||||
"EGL_MESA_screen_surface")) {
|
||||
printf("EGL_MESA_screen_surface is not supported\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eglGetConfigs(d, configs, 10, &numConfigs);
|
||||
printf("Got %d EGL configs:\n", numConfigs);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
|
||||
|
|
@ -551,15 +552,6 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
#include "../../src/egl/main/egldisplay.h"
|
||||
|
||||
typedef struct fb_display
|
||||
{
|
||||
_EGLDisplay Base; /* base class/object */
|
||||
void *pFB;
|
||||
} fbDisplay;
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
|
@ -571,16 +563,14 @@ main(int argc, char *argv[])
|
|||
EGLModeMESA mode;
|
||||
EGLint numConfigs, count;
|
||||
EGLBoolean b;
|
||||
const GLubyte *bitmap;
|
||||
const EGLint screenAttribs[] = {
|
||||
EGL_WIDTH, 1024,
|
||||
EGL_HEIGHT, 768,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
/*
|
||||
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
*/
|
||||
EGLDisplay d = eglGetDisplay("!EGL_i915");
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
|
|
@ -590,6 +580,11 @@ main(int argc, char *argv[])
|
|||
|
||||
printf("EGL version = %d.%d\n", maj, min);
|
||||
printf("EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR));
|
||||
if (!strstr(eglQueryString(d, EGL_EXTENSIONS),
|
||||
"EGL_MESA_screen_surface")) {
|
||||
printf("EGL_MESA_screen_surface is not supported\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eglGetConfigs(d, configs, 10, &numConfigs);
|
||||
eglGetScreensMESA(d, &screen, 1, &count);
|
||||
|
|
@ -620,17 +615,24 @@ main(int argc, char *argv[])
|
|||
Init();
|
||||
Reshape(1024, 768);
|
||||
|
||||
/* some drivers crash when rendering to front buffer */
|
||||
#if 0
|
||||
glDrawBuffer( GL_FRONT );
|
||||
glClearColor( 0, 1.0, 0, 1);
|
||||
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
#endif
|
||||
|
||||
doubleBuffer = 1;
|
||||
glDrawBuffer( GL_BACK );
|
||||
|
||||
Draw(d, screen_surf);
|
||||
sleep(2);
|
||||
|
||||
write_ppm("dump.ppm", ((struct fb_display *)_eglLookupDisplay(d))->pFB, 1024, 768);
|
||||
/* TODO EGL_KHR_lock_surface */
|
||||
bitmap = NULL;
|
||||
if (bitmap)
|
||||
write_ppm("dump.ppm", bitmap, 1024, 768);
|
||||
|
||||
eglDestroySurface(d, screen_surf);
|
||||
eglDestroyContext(d, ctx);
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* DBR : Create EGL context/surface etc */
|
||||
d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
|
||||
d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
|
|
|
|||
|
|
@ -147,8 +147,7 @@ int
|
|||
main(int argc, char *argv[])
|
||||
{
|
||||
int maj, min;
|
||||
//EGLDisplay d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
|
||||
EGLDisplay d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
|
||||
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
printf("eglinfo: eglInitialize failed\n");
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ main(int argc, char *argv[])
|
|||
EGLint count, chosenMode;
|
||||
EGLint width = 0, height = 0;
|
||||
|
||||
d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
|
||||
d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
|
|
|
|||
|
|
@ -130,9 +130,7 @@ static void run(EGLDisplay dpy, EGLSurface surf, int ttr)
|
|||
|
||||
while (ct - st < ttr)
|
||||
{
|
||||
double tt = current_time();
|
||||
double dt = tt - ct;
|
||||
ct = tt;
|
||||
ct = current_time();
|
||||
|
||||
draw();
|
||||
|
||||
|
|
@ -174,7 +172,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* DBR : Create EGL context/surface etc */
|
||||
d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
|
||||
d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &maj, &min)) {
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* DBR : Create EGL context/surface etc */
|
||||
d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
|
||||
d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert(d);
|
||||
|
||||
if (!eglInitialize(d, &major, &minor)) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) \
|
|||
|
||||
# using : to avoid APP_CC pointing to CC loop
|
||||
CC := $(APP_CC)
|
||||
CFLAGS += -I$(INCDIR)
|
||||
CFLAGS := -I$(INCDIR) $(CFLAGS)
|
||||
LDLIBS = $(LIBS)
|
||||
|
||||
PROG_SOURCES = \
|
||||
|
|
|
|||
161
progs/objviewer/GreatLakesBiplaneHP.mtl
Normal file
161
progs/objviewer/GreatLakesBiplaneHP.mtl
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Exported from Wings 3D 0.99.03
|
||||
|
||||
# Top flaps
|
||||
newmtl BottomWing
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 0.0 0.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd TopBotMap.rgb
|
||||
|
||||
newmtl CompBall_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd CompBall_auv.rgb
|
||||
|
||||
newmtl EngMat1
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.334 0.334 0.334
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl EngMat2
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.78688 0.78688 0.78688
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Fuselage_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 0.0 0.0 0.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd SidesMap.rgb
|
||||
|
||||
newmtl Glass
|
||||
Ns 100.0
|
||||
d 0.5
|
||||
illum 2
|
||||
#Kd 0.5533333333333333 1.0 1.0
|
||||
Kd 1.0 1.0 1.0
|
||||
#Ka 0.37333333333333335 0.68 1.0
|
||||
Ka 0.0 0.0 0.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Grip
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.47386 0.47386 0.47386
|
||||
Ka 0.6203799999999999 0.6203799999999999 0.6203799999999999
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Interior
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.70696 0.70696 0.70696
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Prop
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 0.6266666666666667
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd PropMap.rgb
|
||||
|
||||
# Rudder
|
||||
newmtl Sides
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 0.0 0.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd SidesMap.rgb
|
||||
|
||||
newmtl TailHoriz
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 0.0 0.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd TopBotMap.rgb
|
||||
|
||||
# Top wing, bot wing, fuselage
|
||||
newmtl TopWing
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd TopBotMap.rgb
|
||||
|
||||
newmtl Wheels
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.0 0.0 0.0
|
||||
Ka 0.0 0.0 0.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd WheelsMap.rgb
|
||||
|
||||
newmtl cylinder58_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd cylinder58_auv.rgb
|
||||
|
||||
newmtl default
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.0 1.0 1.0
|
||||
Ka 0.0 1.0 1.0
|
||||
Ks 0.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl gage_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd gage_auv.rgb
|
||||
|
||||
497539
progs/objviewer/GreatLakesBiplaneHP.obj
Normal file
497539
progs/objviewer/GreatLakesBiplaneHP.obj
Normal file
File diff suppressed because it is too large
Load diff
83
progs/objviewer/Makefile
Normal file
83
progs/objviewer/Makefile
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
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) $(CFLAGS)
|
||||
LDLIBS = $(LIBS)
|
||||
|
||||
SOURCES = \
|
||||
glm.c \
|
||||
glmdraw.c \
|
||||
objview.c \
|
||||
trackball.c \
|
||||
skybox.c \
|
||||
readtex.c \
|
||||
shaderutil.c
|
||||
|
||||
HEADERS = \
|
||||
extfuncs.h \
|
||||
readtex.h \
|
||||
shaderutil.h \
|
||||
trackball.h
|
||||
|
||||
OBJS = $(SOURCES:.c=.o)
|
||||
|
||||
PROG = objview
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
default: $(PROG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||
|
||||
$(OBJS): $(HEADERS)
|
||||
|
||||
|
||||
### Extra dependencies
|
||||
|
||||
extfuncs.h: $(TOP)/progs/util/extfuncs.h
|
||||
cp $< .
|
||||
|
||||
readtex.c: $(TOP)/progs/util/readtex.c
|
||||
cp $< .
|
||||
|
||||
readtex.h: $(TOP)/progs/util/readtex.h
|
||||
cp $< .
|
||||
|
||||
shaderutil.c: $(TOP)/progs/util/shaderutil.c
|
||||
cp $< .
|
||||
|
||||
shaderutil.h: $(TOP)/progs/util/shaderutil.h
|
||||
cp $< .
|
||||
|
||||
trackball.c: $(TOP)/progs/util/trackball.c
|
||||
cp $< .
|
||||
|
||||
trackball.h: $(TOP)/progs/util/trackball.h
|
||||
cp $< .
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f $(PROG) $(OBJS)
|
||||
-rm -f *.o *~
|
||||
-rm -f extfuncs.h
|
||||
-rm -f shaderutil.*
|
||||
-rm -f trackball.*
|
||||
-rm -f readtex.*
|
||||
|
||||
|
||||
depend: $(SOURCES)
|
||||
@$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(SOURCES) \
|
||||
> /dev/null 2>/dev/null
|
||||
|
||||
|
||||
-include depend
|
||||
23
progs/objviewer/README.txt
Normal file
23
progs/objviewer/README.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
This .obj viewer is based on the "smooth" program by Nate Robins
|
||||
found in the Kilgard GLUT package.
|
||||
|
||||
The alpine sky box textures come from http://www.hazelwhorley.com/skyboxtex3_bitmaps.html
|
||||
|
||||
The bunny.obj and buddha.obj models come from Stanford.
|
||||
|
||||
The GreatLakesBiplaneHP.obj model comes from http://www.sharecg.com/v/25978/3D-Model/Great-Lakes-Biplane-Model
|
||||
|
||||
The bobcat.obj model comes from http://www.sharecg.com/v/24771/3D-Model/Bobcat,3d-studio-and-wavefront-objects
|
||||
|
||||
The .obj file reader code in glm.c isn't perfect. Not all .obj files are
|
||||
parsed correctly. There are often mistakes in material-to-triangle assignments.
|
||||
|
||||
|
||||
Mouse:
|
||||
Left = rotate
|
||||
Middle = scale
|
||||
Right = menu
|
||||
|
||||
Keyboard:
|
||||
See pop-up menu for keyboard shortcuts, or press 'h'.
|
||||
BIN
progs/objviewer/alpine_down.rgb
Normal file
BIN
progs/objviewer/alpine_down.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_east.rgb
Normal file
BIN
progs/objviewer/alpine_east.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_north.rgb
Normal file
BIN
progs/objviewer/alpine_north.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_south.rgb
Normal file
BIN
progs/objviewer/alpine_south.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_up.rgb
Normal file
BIN
progs/objviewer/alpine_up.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_west.rgb
Normal file
BIN
progs/objviewer/alpine_west.rgb
Normal file
Binary file not shown.
72
progs/objviewer/bobcat.mtl
Normal file
72
progs/objviewer/bobcat.mtl
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Exported from Wings 3D 0.99.00b
|
||||
newmtl black
|
||||
Ns 48.6667
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 1.00000e-3 1.00000e-3 1.00000e-3
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl blanco
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 1.00000 1.00000 1.00000
|
||||
Ka 0.620380 0.620380 0.620380
|
||||
Ks 0.806860 0.806860 0.806860
|
||||
Ke 1.00000e-3 1.00000e-3 1.00000e-3
|
||||
|
||||
newmtl blue
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.105111 0.125293 0.366667
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl default
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 1.00000 1.00000 1.00000
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.10000 0.10000 0.10000
|
||||
Ks 0.50000 0.50000 0.500000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl gre
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.200800 0.200800 0.200800
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl red
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.460000 0.00000e+0 0.00000e+0
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl rojo
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.700000 0.00000e+0 0.00000e+0
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 1.00000e-3 1.00000e-3 1.00000e-3
|
||||
|
||||
9251
progs/objviewer/bobcat.obj
Normal file
9251
progs/objviewer/bobcat.obj
Normal file
File diff suppressed because it is too large
Load diff
149990
progs/objviewer/buddha.obj
Normal file
149990
progs/objviewer/buddha.obj
Normal file
File diff suppressed because it is too large
Load diff
104501
progs/objviewer/bunny.obj
Normal file
104501
progs/objviewer/bunny.obj
Normal file
File diff suppressed because it is too large
Load diff
1917
progs/objviewer/glm.c
Normal file
1917
progs/objviewer/glm.c
Normal file
File diff suppressed because it is too large
Load diff
287
progs/objviewer/glm.h
Normal file
287
progs/objviewer/glm.h
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* GLM library. Wavefront .obj file format reader/writer/manipulator.
|
||||
*
|
||||
* Written by Nate Robins, 1997.
|
||||
* email: ndr@pobox.com
|
||||
* www: http://www.pobox.com/~ndr
|
||||
*/
|
||||
|
||||
#ifndef GLM_H
|
||||
#define GLM_H
|
||||
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#endif
|
||||
|
||||
|
||||
/* defines */
|
||||
#define GLM_NONE (0) /* render with only vertices */
|
||||
#define GLM_FLAT (1 << 0) /* render with facet normals */
|
||||
#define GLM_SMOOTH (1 << 1) /* render with vertex normals */
|
||||
#define GLM_TEXTURE (1 << 2) /* render with texture coords */
|
||||
#define GLM_COLOR (1 << 3) /* render with colors */
|
||||
#define GLM_MATERIAL (1 << 4) /* render with materials */
|
||||
|
||||
|
||||
/* structs */
|
||||
|
||||
/* GLMmaterial: Structure that defines a material in a model.
|
||||
*/
|
||||
typedef struct _GLMmaterial
|
||||
{
|
||||
char* name; /* name of material */
|
||||
float diffuse[4]; /* diffuse component */
|
||||
float ambient[4]; /* ambient component */
|
||||
float specular[4]; /* specular component */
|
||||
float emmissive[4]; /* emmissive component */
|
||||
float shininess; /* specular exponent */
|
||||
char *map_kd; /* diffuse texture map file */
|
||||
uint texture_kd; /* diffuse texture map */
|
||||
uint texture_ks; /* specular texture map */
|
||||
int uDiffuse, uAmbient, uSpecular, uShininess, uDiffTex, uSpecTex;
|
||||
uint prog;
|
||||
} GLMmaterial;
|
||||
|
||||
/* GLMtriangle: Structure that defines a triangle in a model.
|
||||
*/
|
||||
typedef struct {
|
||||
uint vindices[3]; /* array of triangle vertex indices */
|
||||
uint nindices[3]; /* array of triangle normal indices */
|
||||
uint tindices[3]; /* array of triangle texcoord indices*/
|
||||
uint findex; /* index of triangle facet normal */
|
||||
} GLMtriangle;
|
||||
|
||||
/* GLMgroup: Structure that defines a group in a model.
|
||||
*/
|
||||
typedef struct _GLMgroup {
|
||||
char* name; /* name of this group */
|
||||
uint numtriangles; /* number of triangles in this group */
|
||||
uint* triangles; /* array of triangle indices */
|
||||
uint material; /* index to material for group */
|
||||
uint * triIndexes;
|
||||
uint minIndex, maxIndex;
|
||||
struct _GLMgroup* next; /* pointer to next group in model */
|
||||
} GLMgroup;
|
||||
|
||||
/* GLMmodel: Structure that defines a model.
|
||||
*/
|
||||
typedef struct {
|
||||
char* pathname; /* path to this model */
|
||||
char* mtllibname; /* name of the material library */
|
||||
|
||||
uint numvertices; /* number of vertices in model */
|
||||
float* vertices; /* array of vertices */
|
||||
|
||||
uint numnormals; /* number of normals in model */
|
||||
float* normals; /* array of normals */
|
||||
|
||||
uint numtexcoords; /* number of texcoords in model */
|
||||
float* texcoords; /* array of texture coordinates */
|
||||
|
||||
uint numfacetnorms; /* number of facetnorms in model */
|
||||
float* facetnorms; /* array of facetnorms */
|
||||
|
||||
uint numtriangles; /* number of triangles in model */
|
||||
GLMtriangle* triangles; /* array of triangles */
|
||||
|
||||
uint nummaterials; /* number of materials in model */
|
||||
GLMmaterial* materials; /* array of materials */
|
||||
|
||||
uint numgroups; /* number of groups in model */
|
||||
GLMgroup* groups; /* linked list of groups */
|
||||
|
||||
float position[3]; /* position of the model */
|
||||
float scale;
|
||||
|
||||
uint vbo; /* OpenGL VBO for vertex data */
|
||||
uint vertexSize; /* number of floats per vertex */
|
||||
uint posOffset; /* offset of position within vertex, in bytes */
|
||||
uint normOffset; /* offset of normal within vertex, in bytes */
|
||||
uint texOffset; /* offset of texcoord within vertex, in bytes */
|
||||
} GLMmodel;
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
/* glmUnitize: "unitize" a model by translating it to the origin and
|
||||
* scaling it to fit in a unit cube around the origin. Returns the
|
||||
* scalefactor used.
|
||||
*
|
||||
* model - properly initialized GLMmodel structure
|
||||
*/
|
||||
float
|
||||
glmUnitize(GLMmodel* model);
|
||||
|
||||
/* glmDimensions: Calculates the dimensions (width, height, depth) of
|
||||
* a model.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* dimensions - array of 3 floats (float dimensions[3])
|
||||
*/
|
||||
void
|
||||
glmDimensions(GLMmodel* model, float* dimensions);
|
||||
|
||||
/* glmScale: Scales a model by a given amount.
|
||||
*
|
||||
* model - properly initialized GLMmodel structure
|
||||
* scale - scalefactor (0.5 = half as large, 2.0 = twice as large)
|
||||
*/
|
||||
void
|
||||
glmScale(GLMmodel* model, float scale);
|
||||
|
||||
/* glmReverseWinding: Reverse the polygon winding for all polygons in
|
||||
* this model. Default winding is counter-clockwise. Also changes
|
||||
* the direction of the normals.
|
||||
*
|
||||
* model - properly initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmReverseWinding(GLMmodel* model);
|
||||
|
||||
/* glmFacetNormals: Generates facet normals for a model (by taking the
|
||||
* cross product of the two vectors derived from the sides of each
|
||||
* triangle). Assumes a counter-clockwise winding.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmFacetNormals(GLMmodel* model);
|
||||
|
||||
/* glmVertexNormals: Generates smooth vertex normals for a model.
|
||||
* First builds a list of all the triangles each vertex is in. Then
|
||||
* loops through each vertex in the the list averaging all the facet
|
||||
* normals of the triangles each vertex is in. Finally, sets the
|
||||
* normal index in the triangle for the vertex to the generated smooth
|
||||
* normal. If the dot product of a facet normal and the facet normal
|
||||
* associated with the first triangle in the list of triangles the
|
||||
* current vertex is in is greater than the cosine of the angle
|
||||
* parameter to the function, that facet normal is not added into the
|
||||
* average normal calculation and the corresponding vertex is given
|
||||
* the facet normal. This tends to preserve hard edges. The angle to
|
||||
* use depends on the model, but 90 degrees is usually a good start.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* angle - maximum angle (in degrees) to smooth across
|
||||
*/
|
||||
void
|
||||
glmVertexNormals(GLMmodel* model, float angle);
|
||||
|
||||
/* glmLinearTexture: Generates texture coordinates according to a
|
||||
* linear projection of the texture map. It generates these by
|
||||
* linearly mapping the vertices onto a square.
|
||||
*
|
||||
* model - pointer to initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmLinearTexture(GLMmodel* model);
|
||||
|
||||
/* glmSpheremapTexture: Generates texture coordinates according to a
|
||||
* spherical projection of the texture map. Sometimes referred to as
|
||||
* spheremap, or reflection map texture coordinates. It generates
|
||||
* these by using the normal to calculate where that vertex would map
|
||||
* onto a sphere. Since it is impossible to map something flat
|
||||
* perfectly onto something spherical, there is distortion at the
|
||||
* poles. This particular implementation causes the poles along the X
|
||||
* axis to be distorted.
|
||||
*
|
||||
* model - pointer to initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmSpheremapTexture(GLMmodel* model);
|
||||
|
||||
/* glmDelete: Deletes a GLMmodel structure.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmDelete(GLMmodel* model);
|
||||
|
||||
/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file.
|
||||
* Returns a pointer to the created object which should be free'd with
|
||||
* glmDelete().
|
||||
*
|
||||
* filename - name of the file containing the Wavefront .OBJ format data.
|
||||
*/
|
||||
GLMmodel*
|
||||
glmReadOBJ(char* filename);
|
||||
|
||||
/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to
|
||||
* a file.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* filename - name of the file to write the Wavefront .OBJ format data to
|
||||
* mode - a bitwise or of values describing what is written to the file
|
||||
* GLM_NONE - write only vertices
|
||||
* GLM_FLAT - write facet normals
|
||||
* GLM_SMOOTH - write vertex normals
|
||||
* GLM_TEXTURE - write texture coords
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
void
|
||||
glmWriteOBJ(GLMmodel* model, char* filename, uint mode);
|
||||
|
||||
/* glmDraw: Renders the model to the current OpenGL context using the
|
||||
* mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
void
|
||||
glmDraw(GLMmodel* model, uint mode);
|
||||
|
||||
/* glmList: Generates and returns a display list for the model using
|
||||
* the mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
uint
|
||||
glmList(GLMmodel* model, uint mode);
|
||||
|
||||
/* glmWeld: eliminate (weld) vectors that are within an epsilon of
|
||||
* each other.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* epsilon - maximum difference between vertices
|
||||
* ( 0.00001 is a good start for a unitized model)
|
||||
*
|
||||
*/
|
||||
void
|
||||
glmWeld(GLMmodel* model, float epsilon);
|
||||
|
||||
void
|
||||
glmReIndex(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmMakeVBOs(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmDrawVBO(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmPrint(const GLMmodel *model);
|
||||
|
||||
void
|
||||
glmShaderMaterial(GLMmaterial *mat);
|
||||
|
||||
void
|
||||
glmLoadTextures(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmSpecularTexture(GLMmodel *model, uint cubeTex);
|
||||
|
||||
#endif /* GLM_H */
|
||||
455
progs/objviewer/glmdraw.c
Normal file
455
progs/objviewer/glmdraw.c
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
/* */
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glm.h"
|
||||
#include "readtex.h"
|
||||
#include "shaderutil.h"
|
||||
|
||||
|
||||
/* defines */
|
||||
#define T(x) model->triangles[(x)]
|
||||
|
||||
|
||||
/* glmDraw: Renders the model to the current OpenGL context using the
|
||||
* mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_COLOR - render with colors (color material)
|
||||
* GLM_MATERIAL - render with materials
|
||||
* GLM_COLOR and GLM_MATERIAL should not both be specified.
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
GLvoid
|
||||
glmDraw(GLMmodel* model, GLuint mode)
|
||||
{
|
||||
GLuint i;
|
||||
GLMgroup* group;
|
||||
|
||||
assert(model);
|
||||
assert(model->vertices);
|
||||
|
||||
/* do a bit of warning */
|
||||
if (mode & GLM_FLAT && !model->facetnorms) {
|
||||
printf("glmDraw() warning: flat render mode requested "
|
||||
"with no facet normals defined.\n");
|
||||
mode &= ~GLM_FLAT;
|
||||
}
|
||||
if (mode & GLM_SMOOTH && !model->normals) {
|
||||
printf("glmDraw() warning: smooth render mode requested "
|
||||
"with no normals defined.\n");
|
||||
mode &= ~GLM_SMOOTH;
|
||||
}
|
||||
if (mode & GLM_TEXTURE && !model->texcoords) {
|
||||
printf("glmDraw() warning: texture render mode requested "
|
||||
"with no texture coordinates defined.\n");
|
||||
mode &= ~GLM_TEXTURE;
|
||||
}
|
||||
if (mode & GLM_FLAT && mode & GLM_SMOOTH) {
|
||||
printf("glmDraw() warning: flat render mode requested "
|
||||
"and smooth render mode requested (using smooth).\n");
|
||||
mode &= ~GLM_FLAT;
|
||||
}
|
||||
if (mode & GLM_COLOR && !model->materials) {
|
||||
printf("glmDraw() warning: color render mode requested "
|
||||
"with no materials defined.\n");
|
||||
mode &= ~GLM_COLOR;
|
||||
}
|
||||
if (mode & GLM_MATERIAL && !model->materials) {
|
||||
printf("glmDraw() warning: material render mode requested "
|
||||
"with no materials defined.\n");
|
||||
mode &= ~GLM_MATERIAL;
|
||||
}
|
||||
if (mode & GLM_COLOR && mode & GLM_MATERIAL) {
|
||||
printf("glmDraw() warning: color and material render mode requested "
|
||||
"using only material mode\n");
|
||||
mode &= ~GLM_COLOR;
|
||||
}
|
||||
if (mode & GLM_COLOR)
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
if (mode & GLM_MATERIAL)
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(model->position[0], model->position[1], model->position[2]);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
group = model->groups;
|
||||
while (group) {
|
||||
if (mode & GLM_MATERIAL) {
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,
|
||||
model->materials[group->material].ambient);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
|
||||
model->materials[group->material].diffuse);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
|
||||
model->materials[group->material].specular);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS,
|
||||
model->materials[group->material].shininess);
|
||||
}
|
||||
|
||||
if (mode & GLM_COLOR) {
|
||||
glColor3fv(model->materials[group->material].diffuse);
|
||||
}
|
||||
|
||||
for (i = 0; i < group->numtriangles; i++) {
|
||||
if (mode & GLM_FLAT)
|
||||
glNormal3fv(&model->facetnorms[3 * T(group->triangles[i]).findex]);
|
||||
|
||||
if (mode & GLM_SMOOTH)
|
||||
glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[0]]);
|
||||
if (mode & GLM_TEXTURE)
|
||||
glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[0]]);
|
||||
glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[0]]);
|
||||
#if 0
|
||||
printf("%f %f %f\n",
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[0] + X],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[0] + Y],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[0] + Z]);
|
||||
#endif
|
||||
|
||||
if (mode & GLM_SMOOTH)
|
||||
glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[1]]);
|
||||
if (mode & GLM_TEXTURE)
|
||||
glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[1]]);
|
||||
glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[1]]);
|
||||
#if 0
|
||||
printf("%f %f %f\n",
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[1] + X],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[1] + Y],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[1] + Z]);
|
||||
#endif
|
||||
|
||||
if (mode & GLM_SMOOTH)
|
||||
glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[2]]);
|
||||
if (mode & GLM_TEXTURE)
|
||||
glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[2]]);
|
||||
glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[2]]);
|
||||
#if 0
|
||||
printf("%f %f %f\n",
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[2] + X],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[2] + Y],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[2] + Z]);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
group = group->next;
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glmMakeVBOs(GLMmodel *model)
|
||||
{
|
||||
uint bytes, vertexFloats, i;
|
||||
float *buffer;
|
||||
|
||||
vertexFloats = 3;
|
||||
model->posOffset = 0;
|
||||
|
||||
if (model->numnormals > 0) {
|
||||
assert(model->numnormals == model->numvertices);
|
||||
model->normOffset = vertexFloats * sizeof(GLfloat);
|
||||
vertexFloats += 3;
|
||||
}
|
||||
|
||||
if (model->numtexcoords > 0) {
|
||||
assert(model->numtexcoords == model->numvertices);
|
||||
model->texOffset = vertexFloats * sizeof(GLfloat);
|
||||
vertexFloats += 2;
|
||||
}
|
||||
|
||||
model->vertexSize = vertexFloats;
|
||||
|
||||
bytes = (model->numvertices + 1) * vertexFloats * sizeof(float);
|
||||
|
||||
buffer = (float *) malloc(bytes);
|
||||
for (i = 0; i < model->numvertices; i++) {
|
||||
/* copy vertex pos */
|
||||
uint j = 0;
|
||||
buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 0];
|
||||
buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 1];
|
||||
buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 2];
|
||||
if (model->numnormals > 0) {
|
||||
buffer[i * vertexFloats + j++] = model->normals[i * 3 + 0];
|
||||
buffer[i * vertexFloats + j++] = model->normals[i * 3 + 1];
|
||||
buffer[i * vertexFloats + j++] = model->normals[i * 3 + 2];
|
||||
}
|
||||
if (model->numtexcoords > 0) {
|
||||
buffer[i * vertexFloats + j++] = model->texcoords[i * 2 + 0];
|
||||
buffer[i * vertexFloats + j++] = model->texcoords[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffersARB(1, &model->vbo);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->vbo);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, buffer, GL_STATIC_DRAW_ARB);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_glmLoadTexture(GLMmaterial *mat)
|
||||
{
|
||||
if (mat->map_kd) {
|
||||
GLint imgWidth, imgHeight;
|
||||
GLenum imgFormat;
|
||||
GLubyte *image = NULL;
|
||||
|
||||
glGenTextures(1, &mat->texture_kd);
|
||||
|
||||
image = LoadRGBImage( mat->map_kd, &imgWidth, &imgHeight, &imgFormat );
|
||||
if (!image) {
|
||||
/*fprintf(stderr, "Couldn't open texture %s\n", mat->map_kd);*/
|
||||
free(mat->map_kd);
|
||||
mat->map_kd = NULL;
|
||||
mat->texture_kd = 0;
|
||||
return;
|
||||
}
|
||||
if (0)
|
||||
printf("load texture %s %d x %d\n", mat->map_kd, imgWidth, imgHeight);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mat->texture_kd);
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight,
|
||||
imgFormat, GL_UNSIGNED_BYTE, image);
|
||||
free(image);
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glmLoadTextures(GLMmodel *model)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < model->nummaterials; i++) {
|
||||
GLMmaterial *mat = &model->materials[i];
|
||||
_glmLoadTexture(mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glmDrawVBO(GLMmodel *model)
|
||||
{
|
||||
GLMgroup* group;
|
||||
|
||||
assert(model->vbo);
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->vbo);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, model->vertexSize * sizeof(float),
|
||||
(void *) model->posOffset);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if (model->numnormals > 0) {
|
||||
glNormalPointer(GL_FLOAT, model->vertexSize * sizeof(float),
|
||||
(void *) model->normOffset);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
if (model->numtexcoords > 0) {
|
||||
glTexCoordPointer(2, GL_FLOAT, model->vertexSize * sizeof(float),
|
||||
(void *) model->texOffset);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(model->position[0], model->position[1], model->position[2]);
|
||||
glScalef(model->scale, model->scale, model->scale);
|
||||
|
||||
for (group = model->groups; group; group = group->next) {
|
||||
if (group->numtriangles > 0) {
|
||||
|
||||
glmShaderMaterial(&model->materials[group->material]);
|
||||
|
||||
glDrawRangeElements(GL_TRIANGLES,
|
||||
group->minIndex, group->maxIndex,
|
||||
3 * group->numtriangles,
|
||||
GL_UNSIGNED_INT, group->triIndexes);
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* glmList: Generates and returns a display list for the model using
|
||||
* the mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_COLOR - render with colors (color material)
|
||||
* GLM_MATERIAL - render with materials
|
||||
* GLM_COLOR and GLM_MATERIAL should not both be specified.
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
GLuint
|
||||
glmList(GLMmodel* model, GLuint mode)
|
||||
{
|
||||
GLuint list;
|
||||
|
||||
list = glGenLists(1);
|
||||
glNewList(list, GL_COMPILE);
|
||||
glmDraw(model, mode);
|
||||
glEndList();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *VertexShader =
|
||||
"varying vec3 normal; \n"
|
||||
"void main() { \n"
|
||||
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
|
||||
" normal = gl_NormalMatrix * gl_Normal; \n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
|
||||
"} \n";
|
||||
|
||||
/**
|
||||
* Two %s substitutions:
|
||||
* diffuse texture? true/false
|
||||
* specular texture? true/false
|
||||
*/
|
||||
static const char *TexFragmentShader =
|
||||
"uniform vec4 ambient, diffuse, specular; \n"
|
||||
"uniform vec4 ambientLight, diffuseLight, specularLight; \n"
|
||||
"uniform float shininess; \n"
|
||||
"uniform sampler2D diffTex; \n"
|
||||
"uniform samplerCube specTex; \n"
|
||||
"varying vec3 normal; \n"
|
||||
"\n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec4 diffTerm, specTerm; \n"
|
||||
" float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
|
||||
" normalize(normal)), 0.0);\n"
|
||||
" float dotProd2 = max(dot(-gl_LightSource[0].position.xyz, \n"
|
||||
" normalize(normal)), 0.0);\n"
|
||||
" dotProd += dotProd2; \n"
|
||||
" \n"
|
||||
" diffTerm = diffuse * diffuseLight * dotProd; \n"
|
||||
" if (%s) \n"
|
||||
" diffTerm *= texture2D(diffTex, gl_TexCoord[0].st); \n"
|
||||
" \n"
|
||||
" specTerm = specular * specularLight * pow(dotProd, shininess); \n"
|
||||
" if (%s) \n"
|
||||
" specTerm *= textureCube(specTex, normal); \n"
|
||||
" \n"
|
||||
" gl_FragColor = ambient * ambientLight + diffTerm + specTerm; \n"
|
||||
"} \n";
|
||||
|
||||
|
||||
void
|
||||
glmShaderMaterial(GLMmaterial *mat)
|
||||
{
|
||||
static const float ambientLight[4] = { 0.1, 0.1, 0.1, 0.0 };
|
||||
static const float diffuseLight[4] = { 0.75, 0.75, 0.75, 1.0 };
|
||||
static const float specularLight[4] = { 1.0, 1.0, 1.0, 0.0 };
|
||||
|
||||
if (!mat->prog) {
|
||||
/* make shader now */
|
||||
char newShader[10000];
|
||||
GLuint vs, fs;
|
||||
const char *diffuseTex = mat->texture_kd ? "true" : "false";
|
||||
const char *specularTex = mat->texture_ks ? "true" : "false";
|
||||
GLint uAmbientLight, uDiffuseLight, uSpecularLight;
|
||||
|
||||
/* replace %d with 0 or 1 */
|
||||
sprintf(newShader, TexFragmentShader, diffuseTex, specularTex);
|
||||
if (0)
|
||||
printf("===== new shader =====\n%s\n============\n", newShader);
|
||||
|
||||
vs = CompileShaderText(GL_VERTEX_SHADER, VertexShader);
|
||||
fs = CompileShaderText(GL_FRAGMENT_SHADER, newShader);
|
||||
mat->prog = LinkShaders(vs, fs);
|
||||
assert(mat->prog);
|
||||
|
||||
glUseProgram(mat->prog);
|
||||
|
||||
mat->uAmbient = glGetUniformLocation(mat->prog, "ambient");
|
||||
mat->uDiffuse = glGetUniformLocation(mat->prog, "diffuse");
|
||||
mat->uSpecular = glGetUniformLocation(mat->prog, "specular");
|
||||
mat->uShininess = glGetUniformLocation(mat->prog, "shininess");
|
||||
mat->uDiffTex = glGetUniformLocation(mat->prog, "diffTex");
|
||||
mat->uSpecTex = glGetUniformLocation(mat->prog, "specTex");
|
||||
|
||||
uAmbientLight = glGetUniformLocation(mat->prog, "ambientLight");
|
||||
uDiffuseLight = glGetUniformLocation(mat->prog, "diffuseLight");
|
||||
uSpecularLight = glGetUniformLocation(mat->prog, "specularLight");
|
||||
|
||||
glUniform4fv(mat->uAmbient, 1, mat->ambient);
|
||||
glUniform4fv(mat->uDiffuse, 1, mat->diffuse);
|
||||
glUniform4fv(mat->uSpecular, 1, mat->specular);
|
||||
glUniform1f(mat->uShininess, mat->shininess);
|
||||
glUniform1i(mat->uDiffTex, 0);
|
||||
glUniform1i(mat->uSpecTex, 1);
|
||||
|
||||
glUniform4fv(uAmbientLight, 1, ambientLight);
|
||||
glUniform4fv(uDiffuseLight, 1, diffuseLight);
|
||||
glUniform4fv(uSpecularLight, 1, specularLight);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
if (mat->texture_ks)
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, mat->texture_ks);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if (mat->texture_kd)
|
||||
glBindTexture(GL_TEXTURE_2D, mat->texture_kd);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (mat->diffuse[3] < 1.0) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
glUseProgram(mat->prog);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glmSpecularTexture(GLMmodel *model, uint cubeTex)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < model->nummaterials; i++) {
|
||||
model->materials[i].texture_ks = cubeTex;
|
||||
}
|
||||
}
|
||||
515
progs/objviewer/objview.c
Normal file
515
progs/objviewer/objview.c
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* .obj file viewer based on "smooth" by Nate Robins, 1997
|
||||
*
|
||||
* Brian Paul
|
||||
* 1 Oct 2009
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glut.h>
|
||||
#include "glm.h"
|
||||
#include "readtex.h"
|
||||
#include "skybox.h"
|
||||
#include "trackball.h"
|
||||
|
||||
|
||||
static char *Model_file = NULL; /* name of the obect file */
|
||||
static GLMmodel *Model;
|
||||
static GLfloat Scale = 4.0; /* scaling factor */
|
||||
static GLboolean Performance = GL_FALSE;
|
||||
static GLboolean Stats = GL_FALSE;
|
||||
static GLboolean Animate = GL_TRUE;
|
||||
static GLuint SkyboxTex;
|
||||
static GLboolean Skybox = GL_TRUE;
|
||||
static GLboolean Cull = GL_TRUE;
|
||||
static GLboolean WireFrame = GL_FALSE;
|
||||
static GLenum FrontFace = GL_CCW;
|
||||
static GLfloat Yrot = 0.0;
|
||||
static GLint WinWidth = 1024, WinHeight = 768;
|
||||
static GLuint NumInstances = 1;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float CurQuat[4];
|
||||
float Distance;
|
||||
/* When mouse is moving: */
|
||||
GLboolean Rotating, Translating;
|
||||
GLint StartX, StartY;
|
||||
float StartDistance;
|
||||
} ViewInfo;
|
||||
|
||||
static ViewInfo View;
|
||||
|
||||
static void
|
||||
InitViewInfo(ViewInfo *view)
|
||||
{
|
||||
view->Rotating = GL_FALSE;
|
||||
view->Translating = GL_FALSE;
|
||||
view->StartX = view->StartY = 0;
|
||||
view->Distance = 12.0;
|
||||
view->StartDistance = 0.0;
|
||||
view->CurQuat[0] = 0.0;
|
||||
view->CurQuat[1] = 1.0;
|
||||
view->CurQuat[2] = 0.0;
|
||||
view->CurQuat[3] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* text: general purpose text routine. draws a string according to
|
||||
* format in a stroke font at x, y after scaling it by the scale
|
||||
* specified (scale is in window-space (lower-left origin) pixels).
|
||||
*
|
||||
* x - position in x (in window-space)
|
||||
* y - position in y (in window-space)
|
||||
* scale - scale in pixels
|
||||
* format - as in printf()
|
||||
*/
|
||||
static void
|
||||
text(GLuint x, GLuint y, GLfloat scale, char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255], *p;
|
||||
GLfloat font_scale = 119.05 + 33.33;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glTranslatef(x, y, 0.0);
|
||||
|
||||
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
|
||||
|
||||
for(p = buffer; *p; p++)
|
||||
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
|
||||
|
||||
glPopAttrib();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
ComputeFPS(void)
|
||||
{
|
||||
static double t0 = -1.0;
|
||||
static int frames = 0;
|
||||
double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
|
||||
static float fps = 0;
|
||||
|
||||
frames++;
|
||||
|
||||
if (t0 < 0.0) {
|
||||
t0 = t;
|
||||
fps = 0.0;
|
||||
}
|
||||
else if (t - t0 >= 4.0) {
|
||||
fps = (frames / (t - t0) + 0.5);
|
||||
t0 = t;
|
||||
frames = 0;
|
||||
return fps;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_model(void)
|
||||
{
|
||||
float objScale;
|
||||
|
||||
/* read in the model */
|
||||
Model = glmReadOBJ(Model_file);
|
||||
objScale = glmUnitize(Model);
|
||||
glmFacetNormals(Model);
|
||||
if (Model->numnormals == 0) {
|
||||
GLfloat smoothing_angle = 90.0;
|
||||
printf("Generating normals.\n");
|
||||
glmVertexNormals(Model, smoothing_angle);
|
||||
}
|
||||
|
||||
glmLoadTextures(Model);
|
||||
glmReIndex(Model);
|
||||
glmMakeVBOs(Model);
|
||||
if (0)
|
||||
glmPrint(Model);
|
||||
}
|
||||
|
||||
static void
|
||||
init_skybox(void)
|
||||
{
|
||||
SkyboxTex = LoadSkyBoxCubeTexture("alpine_east.rgb",
|
||||
"alpine_west.rgb",
|
||||
"alpine_up.rgb",
|
||||
"alpine_down.rgb",
|
||||
"alpine_south.rgb",
|
||||
"alpine_north.rgb");
|
||||
glmSpecularTexture(Model, SkyboxTex);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_gfx(void)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glClearColor(0.3, 0.3, 0.9, 0.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
reshape(int width, int height)
|
||||
{
|
||||
float ar = 0.5 * (float) width / (float) height;
|
||||
|
||||
WinWidth = width;
|
||||
WinHeight = height;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-ar, ar, -0.5, 0.5, 1.0, 300.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -3.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Idle(void)
|
||||
{
|
||||
float q[4];
|
||||
trackball(q, 100, 0, 99.99, 0);
|
||||
add_quats(q, View.CurQuat, View.CurQuat);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
display(void)
|
||||
{
|
||||
GLfloat rot[4][4];
|
||||
float fps;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0, 0.0, -View.Distance);
|
||||
glRotatef(Yrot, 0, 1, 0);
|
||||
build_rotmatrix(rot, View.CurQuat);
|
||||
glMultMatrixf(&rot[0][0]);
|
||||
glScalef(Scale, Scale, Scale );
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
if (Skybox)
|
||||
DrawSkyBoxCubeTexture(SkyboxTex);
|
||||
|
||||
if (WireFrame)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
if (Cull)
|
||||
glEnable(GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (NumInstances == 1) {
|
||||
glmDrawVBO(Model);
|
||||
}
|
||||
else {
|
||||
/* draw > 1 instance */
|
||||
float dr = 360.0 / NumInstances;
|
||||
float r;
|
||||
for (r = 0.0; r < 360.0; r += dr) {
|
||||
glPushMatrix();
|
||||
glRotatef(r, 0, 1, 0);
|
||||
glTranslatef(1.4, 0.0, 0.0);
|
||||
glmDrawVBO(Model);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if (Stats) {
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*1), 20, "%s",
|
||||
Model->pathname);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*2), 20, "%d vertices",
|
||||
Model->numvertices);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*3), 20, "%d triangles",
|
||||
Model->numtriangles);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*4), 20, "%d normals",
|
||||
Model->numnormals);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*5), 20, "%d texcoords",
|
||||
Model->numtexcoords);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*6), 20, "%d groups",
|
||||
Model->numgroups);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*7), 20, "%d materials",
|
||||
Model->nummaterials);
|
||||
}
|
||||
|
||||
glutSwapBuffers();
|
||||
|
||||
fps = ComputeFPS();
|
||||
if (fps)
|
||||
printf("%f FPS\n", fps);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
keyboard(unsigned char key, int x, int y)
|
||||
{
|
||||
switch (key) {
|
||||
case 'h':
|
||||
printf("help\n\n");
|
||||
printf("a - Toggle animation\n");
|
||||
printf("d/D - Decrease/Incrase number of models\n");
|
||||
printf("w - Toggle wireframe/filled\n");
|
||||
printf("c - Toggle culling\n");
|
||||
printf("n - Toggle facet/smooth normal\n");
|
||||
printf("r - Reverse polygon winding\n");
|
||||
printf("p - Toggle performance indicator\n");
|
||||
printf("s - Toggle skybox\n");
|
||||
printf("z/Z - Scale model smaller/larger\n");
|
||||
printf("i - Show model info/stats\n");
|
||||
printf("q/escape - Quit\n\n");
|
||||
break;
|
||||
case 'a':
|
||||
Animate = !Animate;
|
||||
if (Animate)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 'd':
|
||||
if (NumInstances > 1)
|
||||
NumInstances--;
|
||||
break;
|
||||
case 'D':
|
||||
NumInstances++;
|
||||
break;
|
||||
case 'i':
|
||||
Stats = !Stats;
|
||||
break;
|
||||
case 'p':
|
||||
Performance = !Performance;
|
||||
break;
|
||||
case 'w':
|
||||
WireFrame = !WireFrame;
|
||||
break;
|
||||
case 'c':
|
||||
Cull = !Cull;
|
||||
printf("Polygon culling: %d\n", Cull);
|
||||
break;
|
||||
case 'r':
|
||||
if (FrontFace == GL_CCW)
|
||||
FrontFace = GL_CW;
|
||||
else
|
||||
FrontFace = GL_CCW;
|
||||
glFrontFace(FrontFace);
|
||||
printf("Front face:: %s\n", FrontFace == GL_CCW ? "CCW" : "CW");
|
||||
break;
|
||||
case 's':
|
||||
Skybox = !Skybox;
|
||||
if (Skybox)
|
||||
glmSpecularTexture(Model, SkyboxTex);
|
||||
else
|
||||
glmSpecularTexture(Model, 0);
|
||||
break;
|
||||
case 'z':
|
||||
Scale *= 0.9;
|
||||
break;
|
||||
case 'Z':
|
||||
Scale *= 1.1;
|
||||
break;
|
||||
case 'q':
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
menu(int item)
|
||||
{
|
||||
keyboard((unsigned char)item, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle mouse button.
|
||||
*/
|
||||
static void
|
||||
Mouse(int button, int state, int x, int y)
|
||||
{
|
||||
if (button == GLUT_LEFT_BUTTON) {
|
||||
if (state == GLUT_DOWN) {
|
||||
View.StartX = x;
|
||||
View.StartY = y;
|
||||
View.Rotating = GL_TRUE;
|
||||
}
|
||||
else if (state == GLUT_UP) {
|
||||
View.Rotating = GL_FALSE;
|
||||
}
|
||||
}
|
||||
else if (button == GLUT_MIDDLE_BUTTON) {
|
||||
if (state == GLUT_DOWN) {
|
||||
View.StartX = x;
|
||||
View.StartY = y;
|
||||
View.StartDistance = View.Distance;
|
||||
View.Translating = GL_TRUE;
|
||||
}
|
||||
else if (state == GLUT_UP) {
|
||||
View.Translating = GL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle mouse motion
|
||||
*/
|
||||
static void
|
||||
Motion(int x, int y)
|
||||
{
|
||||
int i;
|
||||
if (View.Rotating) {
|
||||
float x0 = (2.0 * View.StartX - WinWidth) / WinWidth;
|
||||
float y0 = (WinHeight - 2.0 * View.StartY) / WinHeight;
|
||||
float x1 = (2.0 * x - WinWidth) / WinWidth;
|
||||
float y1 = (WinHeight - 2.0 * y) / WinHeight;
|
||||
float q[4];
|
||||
|
||||
trackball(q, x0, y0, x1, y1);
|
||||
View.StartX = x;
|
||||
View.StartY = y;
|
||||
for (i = 0; i < 1; i++)
|
||||
add_quats(q, View.CurQuat, View.CurQuat);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
else if (View.Translating) {
|
||||
float dz = 0.02 * (y - View.StartY);
|
||||
View.Distance = View.StartDistance + dz;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DoFeatureChecks(void)
|
||||
{
|
||||
char *version = (char *) glGetString(GL_VERSION);
|
||||
if (version[0] == '1') {
|
||||
/* check for individual extensions */
|
||||
if (!glutExtensionSupported("GL_ARB_texture_cube_map")) {
|
||||
printf("Sorry, GL_ARB_texture_cube_map is required.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!glutExtensionSupported("GL_ARB_vertex_shader")) {
|
||||
printf("Sorry, GL_ARB_vertex_shader is required.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!glutExtensionSupported("GL_ARB_fragment_shader")) {
|
||||
printf("Sorry, GL_ARB_fragment_shader is required.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
|
||||
printf("Sorry, GL_ARB_vertex_buffer_object is required.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
glutInitWindowSize(WinWidth, WinHeight);
|
||||
glutInit(&argc, argv);
|
||||
|
||||
if (argc > 1) {
|
||||
Model_file = argv[1];
|
||||
}
|
||||
if (!Model_file) {
|
||||
fprintf(stderr, "usage: objview file.obj\n");
|
||||
fprintf(stderr, "(using default bunny.obj)\n");
|
||||
Model_file = "bunny.obj";
|
||||
}
|
||||
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
|
||||
glutCreateWindow("objview");
|
||||
|
||||
glewInit();
|
||||
|
||||
DoFeatureChecks();
|
||||
|
||||
glutReshapeFunc(reshape);
|
||||
glutDisplayFunc(display);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMouseFunc(Mouse);
|
||||
glutMotionFunc(Motion);
|
||||
if (Animate)
|
||||
glutIdleFunc(Idle);
|
||||
|
||||
glutCreateMenu(menu);
|
||||
glutAddMenuEntry("[a] Toggle animate", 'a');
|
||||
glutAddMenuEntry("[d] Fewer models", 'd');
|
||||
glutAddMenuEntry("[D] More models", 'D');
|
||||
glutAddMenuEntry("[w] Toggle wireframe/filled", 'w');
|
||||
glutAddMenuEntry("[c] Toggle culling on/off", 'c');
|
||||
glutAddMenuEntry("[r] Reverse polygon winding", 'r');
|
||||
glutAddMenuEntry("[z] Scale model smaller", 'z');
|
||||
glutAddMenuEntry("[Z] Scale model larger", 'Z');
|
||||
glutAddMenuEntry("[p] Toggle performance indicator", 'p');
|
||||
glutAddMenuEntry("[i] Show model stats", 'i');
|
||||
glutAddMenuEntry("", 0);
|
||||
glutAddMenuEntry("[q] Quit", 27);
|
||||
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
||||
|
||||
InitViewInfo(&View);
|
||||
|
||||
init_model();
|
||||
init_skybox();
|
||||
init_gfx();
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
187
progs/objviewer/skybox.c
Normal file
187
progs/objviewer/skybox.c
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glu.h>
|
||||
#include "readtex.h"
|
||||
#include "skybox.h"
|
||||
|
||||
|
||||
static int
|
||||
load(GLenum target, const char *filename,
|
||||
GLboolean flipTB, GLboolean flipLR)
|
||||
{
|
||||
GLint w, h;
|
||||
GLenum format;
|
||||
GLubyte *img = LoadRGBImage( filename, &w, &h, &format );
|
||||
if (!img) {
|
||||
printf("Error: couldn't load texture image %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
assert(format == GL_RGB);
|
||||
|
||||
printf("Load cube face 0x%x: %s %d x %d\n", target, filename, w, h);
|
||||
|
||||
/* <sigh> the way the texture cube mapping works, we have to flip
|
||||
* images to make things look right.
|
||||
*/
|
||||
if (flipTB) {
|
||||
const int stride = 3 * w;
|
||||
GLubyte temp[3*1024];
|
||||
int i;
|
||||
for (i = 0; i < h / 2; i++) {
|
||||
memcpy(temp, img + i * stride, stride);
|
||||
memcpy(img + i * stride, img + (h - i - 1) * stride, stride);
|
||||
memcpy(img + (h - i - 1) * stride, temp, stride);
|
||||
}
|
||||
}
|
||||
if (flipLR) {
|
||||
const int stride = 3 * w;
|
||||
GLubyte temp[3];
|
||||
GLubyte *row;
|
||||
int i, j;
|
||||
for (i = 0; i < h; i++) {
|
||||
row = img + i * stride;
|
||||
for (j = 0; j < w / 2; j++) {
|
||||
int k = w - j - 1;
|
||||
temp[0] = row[j*3+0];
|
||||
temp[1] = row[j*3+1];
|
||||
temp[2] = row[j*3+2];
|
||||
row[j*3+0] = row[k*3+0];
|
||||
row[j*3+1] = row[k*3+1];
|
||||
row[j*3+2] = row[k*3+2];
|
||||
row[k*3+0] = temp[0];
|
||||
row[k*3+1] = temp[1];
|
||||
row[k*3+2] = temp[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img);
|
||||
free(img);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
LoadSkyBoxCubeTexture(const char *filePosX,
|
||||
const char *fileNegX,
|
||||
const char *filePosY,
|
||||
const char *fileNegY,
|
||||
const char *filePosZ,
|
||||
const char *fileNegZ)
|
||||
{
|
||||
GLuint tex;
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_NEAREST);
|
||||
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_X, filePosX, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, fileNegX, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, 1+GL_FALSE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, 1+GL_FALSE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, filePosZ, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, fileNegZ, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
#define eps1 0.99
|
||||
#define br 20.0 /* box radius */
|
||||
|
||||
void
|
||||
DrawSkyBoxCubeTexture(GLuint tex)
|
||||
{
|
||||
struct vertex {
|
||||
float x, y, z, s, t, r;
|
||||
};
|
||||
|
||||
static const struct vertex verts[24] = {
|
||||
/* +X side */
|
||||
{ br, -br, -br, 1.0, -eps1, -eps1 },
|
||||
{ br, -br, br, 1.0, -eps1, eps1 },
|
||||
{ br, br, br, 1.0, eps1, eps1 },
|
||||
{ br, br, -br, 1.0, eps1, -eps1 },
|
||||
|
||||
/* -X side */
|
||||
{ -br, br, -br, -1.0, eps1, -eps1 },
|
||||
{ -br, br, br, -1.0, eps1, eps1 },
|
||||
{ -br, -br, br, -1.0, -eps1, eps1 },
|
||||
{ -br, -br, -br, -1.0, -eps1, -eps1 },
|
||||
|
||||
/* +Y side */
|
||||
{ br, br, -br, eps1, 1.0, -eps1 },
|
||||
{ br, br, br, eps1, 1.0, eps1 },
|
||||
{ -br, br, br, -eps1, 1.0, eps1 },
|
||||
{ -br, br, -br, -eps1, 1.0, -eps1 },
|
||||
|
||||
/* -Y side */
|
||||
{ -br, -br, -br, -eps1, -1.0, -eps1 },
|
||||
{ -br, -br, br, -eps1, -1.0, eps1 },
|
||||
{ br, -br, br, eps1, -1.0, eps1 },
|
||||
{ br, -br, -br, eps1, -1.0, -eps1 },
|
||||
|
||||
/* +Z side */
|
||||
{ br, -br, br, eps1, -eps1, 1.0 },
|
||||
{ -br, -br, br, -eps1, -eps1, 1.0 },
|
||||
{ -br, br, br, -eps1, eps1, 1.0 },
|
||||
{ br, br, br, eps1, eps1, 1.0 },
|
||||
|
||||
/* -Z side */
|
||||
{ br, br, -br, eps1, eps1, -1.0 },
|
||||
{ -br, br, -br, -eps1, eps1, -1.0 },
|
||||
{ -br, -br, -br, -eps1, -eps1, -1.0 },
|
||||
{ br, -br, -br, eps1, -eps1, -1.0 },
|
||||
};
|
||||
|
||||
static GLuint vbo = 0;
|
||||
|
||||
if (!vbo ) {
|
||||
glGenBuffersARB(1, &vbo);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
|
||||
GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
else {
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
}
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(struct vertex),
|
||||
(void *) offsetof(struct vertex, x));
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(struct vertex),
|
||||
(void *) offsetof(struct vertex, s));
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glDrawArrays(GL_QUADS, 0, 24);
|
||||
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
|
||||
18
progs/objviewer/skybox.h
Normal file
18
progs/objviewer/skybox.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
#ifndef SKYBOX_H
|
||||
#define SKYBOX_H
|
||||
|
||||
|
||||
extern GLuint
|
||||
LoadSkyBoxCubeTexture(const char *filePosX,
|
||||
const char *fileNegX,
|
||||
const char *filePosY,
|
||||
const char *fileNegY,
|
||||
const char *filePosZ,
|
||||
const char *fileNegZ);
|
||||
|
||||
extern void
|
||||
DrawSkyBoxCubeTexture(GLuint tex);
|
||||
|
||||
|
||||
#endif /* SKYBOX_H */
|
||||
|
|
@ -10,11 +10,17 @@ LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) \
|
|||
|
||||
# using : to avoid APP_CC pointing to CC loop
|
||||
CC := $(APP_CC)
|
||||
CFLAGS += -I$(INCDIR)
|
||||
CFLAGS := -I$(INCDIR) $(CFLAGS)
|
||||
LDLIBS = $(LIBS)
|
||||
|
||||
PROG_SOURCES = \
|
||||
copytex.c \
|
||||
drawoverhead.c \
|
||||
fbobind.c \
|
||||
fill.c \
|
||||
genmipmap.c \
|
||||
readpixels.c \
|
||||
swapbuffers.c \
|
||||
teximage.c \
|
||||
vbo.c \
|
||||
vertexrate.c \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,13 @@ env = env.Clone()
|
|||
env.Prepend(LIBS = ['$GLUT_LIB'])
|
||||
|
||||
progs = [
|
||||
'copytex',
|
||||
'drawoverhead',
|
||||
'fbobind',
|
||||
'fill',
|
||||
'genmipmap',
|
||||
'readpixels',
|
||||
'swapbuffers',
|
||||
'teximage',
|
||||
'vbo',
|
||||
'vertexrate',
|
||||
|
|
|
|||
|
|
@ -113,3 +113,21 @@ PerfMeasureRate(PerfRateFunc f)
|
|||
}
|
||||
|
||||
|
||||
/* Note static buffer, can only use once per printf.
|
||||
*/
|
||||
const char *
|
||||
PerfHumanFloat( double d )
|
||||
{
|
||||
static char buf[80];
|
||||
|
||||
if (d > 1000000000.0)
|
||||
snprintf(buf, sizeof(buf), "%.1f billion", d / 1000000000.0);
|
||||
else if (d > 1000000.0)
|
||||
snprintf(buf, sizeof(buf), "%.1f million", d / 1000000.0);
|
||||
else if (d > 1000.0)
|
||||
snprintf(buf, sizeof(buf), "%.1f thousand", d / 1000.0);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%.1f", d);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,12 +24,17 @@
|
|||
#define COMMON_H
|
||||
|
||||
|
||||
#include <stddef.h> /* for offsetof() */
|
||||
|
||||
|
||||
typedef void (*PerfRateFunc)(unsigned count);
|
||||
|
||||
|
||||
extern double
|
||||
PerfMeasureRate(PerfRateFunc f);
|
||||
|
||||
const char *
|
||||
PerfHumanFloat( double d );
|
||||
|
||||
extern void
|
||||
perf_printf(const char *format, ...);
|
||||
|
|
|
|||
214
progs/perf/copytex.c
Normal file
214
progs/perf/copytex.c
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* 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 glCopyTex[Sub]Image() rate.
|
||||
* Create a large, off-screen framebuffer object for rendering and
|
||||
* copying the texture data from it since we can't make really large
|
||||
* on-screen windows.
|
||||
*
|
||||
* Brian Paul
|
||||
* 22 Sep 2009
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
int WinWidth = 100, WinHeight = 100;
|
||||
|
||||
static GLuint VBO, FBO, RBO, Tex;
|
||||
|
||||
const GLsizei MinSize = 16, MaxSize = 4096;
|
||||
static GLsizei TexSize;
|
||||
|
||||
static const GLboolean DrawPoint = GL_TRUE;
|
||||
static const GLboolean TexSubImage4 = GL_FALSE;
|
||||
|
||||
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)
|
||||
{
|
||||
const GLenum filter = GL_LINEAR;
|
||||
GLenum stat;
|
||||
|
||||
if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
|
||||
perf_printf("copytex: GL_EXT_framebuffer_object not supported\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* setup VBO */
|
||||
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);
|
||||
|
||||
/* setup texture */
|
||||
glGenTextures(1, &Tex);
|
||||
glBindTexture(GL_TEXTURE_2D, Tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
/* setup rbo */
|
||||
glGenRenderbuffersEXT(1, &RBO);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBO);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, MaxSize, MaxSize);
|
||||
|
||||
/* setup fbo */
|
||||
glGenFramebuffersEXT(1, &FBO);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER, FBO);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RENDERBUFFER_EXT, RBO);
|
||||
|
||||
stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
perf_printf("fboswitch: Error: incomplete FBO!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* clear the FBO */
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glViewport(0, 0, MaxSize, MaxSize);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CopyTexImage(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 1; i < count; i++) {
|
||||
/* draw something */
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
/* copy whole texture */
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0,
|
||||
GL_RGBA, 0, 0, TexSize, TexSize, 0);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CopyTexSubImage(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 1; i < count; i++) {
|
||||
/* draw something */
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
/* copy sub texture */
|
||||
if (TexSubImage4) {
|
||||
/* four sub-copies */
|
||||
GLsizei half = TexSize / 2;
|
||||
/* lower-left */
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, 0, 0, 0, half, half);
|
||||
/* lower-right */
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
half, 0, half, 0, half, half);
|
||||
/* upper-left */
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, half, 0, half, half, half);
|
||||
/* upper-right */
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
half, half, half, half, half, half);
|
||||
}
|
||||
else {
|
||||
/* one big copy */
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, 0, 0, 0, TexSize, TexSize);
|
||||
}
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
double rate, mbPerSec;
|
||||
GLint sub, maxTexSize;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
|
||||
|
||||
/* loop over whole/sub tex copy */
|
||||
for (sub = 0; sub < 2; sub++) {
|
||||
|
||||
/* loop over texture sizes */
|
||||
for (TexSize = MinSize; TexSize <= MaxSize; TexSize *= 4) {
|
||||
|
||||
if (TexSize <= maxTexSize) {
|
||||
GLint bytesPerImage = 4 * TexSize * TexSize;
|
||||
|
||||
if (sub == 0)
|
||||
rate = PerfMeasureRate(CopyTexImage);
|
||||
else {
|
||||
/* setup empty dest texture */
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
TexSize, TexSize, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
rate = PerfMeasureRate(CopyTexSubImage);
|
||||
}
|
||||
|
||||
mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
|
||||
}
|
||||
else {
|
||||
rate = 0.0;
|
||||
mbPerSec = 0.0;
|
||||
}
|
||||
|
||||
perf_printf(" glCopyTex%sImage(%d x %d): %.1f copies/sec, %.1f Mpixels/sec\n",
|
||||
(sub ? "Sub" : ""), TexSize, TexSize, rate, mbPerSec);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@
|
|||
* 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
|
||||
|
|
@ -108,6 +107,10 @@ DrawStateChange(unsigned count)
|
|||
glFinish();
|
||||
}
|
||||
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
|
|
@ -116,18 +119,18 @@ PerfDraw(void)
|
|||
double rate0, rate1, rate2, overhead;
|
||||
|
||||
rate0 = PerfMeasureRate(DrawNoStateChange);
|
||||
perf_printf(" Draw only: %.1f draws/second\n", rate0);
|
||||
perf_printf(" Draw only: %s draws/second\n",
|
||||
PerfHumanFloat(rate0));
|
||||
|
||||
|
||||
rate1 = PerfMeasureRate(DrawNopStateChange);
|
||||
overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0);
|
||||
perf_printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n",
|
||||
rate1, overhead);
|
||||
perf_printf(" Draw w/ nop state change: %s draws/sec (overhead: %f ms/draw)\n",
|
||||
PerfHumanFloat(rate1), overhead);
|
||||
|
||||
rate2 = PerfMeasureRate(DrawStateChange);
|
||||
overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0);
|
||||
perf_printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n",
|
||||
rate2, overhead);
|
||||
perf_printf(" Draw w/ state change: %s draws/sec (overhead: %f ms/draw)\n",
|
||||
PerfHumanFloat(rate2), overhead);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
153
progs/perf/fbobind.c
Normal file
153
progs/perf/fbobind.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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 rate of binding/switching between FBO targets.
|
||||
* Create two framebuffer objects for rendering to two textures.
|
||||
* Ping pong between texturing from one and drawing into the other.
|
||||
*
|
||||
* Brian Paul
|
||||
* 22 Sep 2009
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
int WinWidth = 100, WinHeight = 100;
|
||||
|
||||
static GLuint VBO;
|
||||
|
||||
static GLuint FBO[2], Tex[2];
|
||||
|
||||
static const GLsizei TexSize = 512;
|
||||
|
||||
static const GLboolean DrawPoint = 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)
|
||||
{
|
||||
const GLenum filter = GL_LINEAR;
|
||||
GLenum stat;
|
||||
int i;
|
||||
|
||||
if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
|
||||
perf_printf("fboswitch: GL_EXT_framebuffer_object not supported\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* setup VBO */
|
||||
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);
|
||||
|
||||
glGenFramebuffersEXT(2, FBO);
|
||||
glGenTextures(2, Tex);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* setup texture */
|
||||
glBindTexture(GL_TEXTURE_2D, Tex[i]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
TexSize, TexSize, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
|
||||
|
||||
/* setup fbo */
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER, FBO[i]);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, Tex[i], 0/*level*/);
|
||||
stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
perf_printf("fboswitch: Error: incomplete FBO!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* clear the FBO */
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FBOBind(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 1; i < count; i++) {
|
||||
const GLuint dst = i & 1;
|
||||
const GLuint src = 1 - dst;
|
||||
|
||||
/* bind src texture */
|
||||
glBindTexture(GL_TEXTURE_2D, Tex[src]);
|
||||
|
||||
/* bind dst fbo */
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO[dst]);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
/* draw something */
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
double rate;
|
||||
|
||||
rate = PerfMeasureRate(FBOBind);
|
||||
perf_printf(" FBO Binding: %1.f binds/sec\n", rate);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
248
progs/perf/fill.c
Normal file
248
progs/perf/fill.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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 fill rates.
|
||||
*
|
||||
* Brian Paul
|
||||
* 21 Sep 2009
|
||||
*/
|
||||
|
||||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
int WinWidth = 1000, WinHeight = 1000;
|
||||
|
||||
static GLuint VBO, TexObj;
|
||||
|
||||
|
||||
struct vertex
|
||||
{
|
||||
GLfloat x, y, s, t, r, g, b, a;
|
||||
};
|
||||
|
||||
#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
|
||||
|
||||
static const struct vertex vertices[4] = {
|
||||
/* x y s t r g b a */
|
||||
{ -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5 },
|
||||
{ 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5 },
|
||||
{ 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.5 },
|
||||
{ -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.5 }
|
||||
};
|
||||
|
||||
|
||||
static const char *VertexShader =
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" gl_Position = ftransform(); \n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
|
||||
" gl_FrontColor = gl_Color; \n"
|
||||
"} \n";
|
||||
|
||||
/* simple fragment shader */
|
||||
static const char *FragmentShader1 =
|
||||
"uniform sampler2D Tex; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec4 t = texture2D(Tex, gl_TexCoord[0].xy); \n"
|
||||
" gl_FragColor = vec4(1.0) - t * gl_Color; \n"
|
||||
"} \n";
|
||||
|
||||
/**
|
||||
* A more complex fragment shader (but equivalent to first shader).
|
||||
* A good optimizer should catch some of these no-op operations, but
|
||||
* probably not all of them.
|
||||
*/
|
||||
static const char *FragmentShader2 =
|
||||
"uniform sampler2D Tex; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" // as above \n"
|
||||
" vec4 t = texture2D(Tex, gl_TexCoord[0].xy); \n"
|
||||
" t = vec4(1.0) - t * gl_Color; \n"
|
||||
|
||||
" vec4 u; \n"
|
||||
|
||||
" // no-op negate/swizzle \n"
|
||||
" u = -t.wzyx; \n"
|
||||
" t = -u.wzyx; \n"
|
||||
|
||||
" // no-op inverts \n"
|
||||
" t = vec4(1.0) - t; \n"
|
||||
" t = vec4(1.0) - t; \n"
|
||||
|
||||
" // no-op min/max \n"
|
||||
" t = min(t, t); \n"
|
||||
" t = max(t, t); \n"
|
||||
|
||||
" // no-op moves \n"
|
||||
" u = t; \n"
|
||||
" t = u; \n"
|
||||
" u = t; \n"
|
||||
" t = u; \n"
|
||||
|
||||
" // no-op add/mul \n"
|
||||
" t = (t + t + t + t) * 0.25; \n"
|
||||
|
||||
" // no-op mul/sub \n"
|
||||
" t = 3.0 * t - 2.0 * t; \n"
|
||||
|
||||
" // no-op negate/min/max \n"
|
||||
" t = -min(-t, -t); \n"
|
||||
" t = -max(-t, -t); \n"
|
||||
|
||||
" gl_FragColor = t; \n"
|
||||
"} \n";
|
||||
|
||||
static GLuint ShaderProg1, ShaderProg2;
|
||||
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfInit(void)
|
||||
{
|
||||
GLint u;
|
||||
|
||||
/* 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));
|
||||
glColorPointer(4, GL_FLOAT, sizeof(struct vertex), VOFFSET(r));
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
/* setup texture */
|
||||
TexObj = PerfCheckerTexture(128, 128);
|
||||
|
||||
/* setup shaders */
|
||||
ShaderProg1 = PerfShaderProgram(VertexShader, FragmentShader1);
|
||||
glUseProgram(ShaderProg1);
|
||||
u = glGetUniformLocation(ShaderProg1, "Tex");
|
||||
glUniform1i(u, 0); /* texture unit 0 */
|
||||
|
||||
ShaderProg2 = PerfShaderProgram(VertexShader, FragmentShader2);
|
||||
glUseProgram(ShaderProg2);
|
||||
u = glGetUniformLocation(ShaderProg2, "Tex");
|
||||
glUniform1i(u, 0); /* texture unit 0 */
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Ortho(void)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
DrawQuad(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
/* Avoid sending command buffers with huge numbers of fullscreen
|
||||
* quads. Graphics schedulers don't always cope well with
|
||||
* this...
|
||||
*/
|
||||
if (i % 128 == 0) {
|
||||
PerfSwapBuffers();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
glFinish();
|
||||
|
||||
if (1)
|
||||
PerfSwapBuffers();
|
||||
}
|
||||
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
double rate;
|
||||
double pixelsPerDraw = WinWidth * WinHeight;
|
||||
|
||||
Ortho();
|
||||
|
||||
/* simple fill */
|
||||
rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
|
||||
perf_printf(" Simple fill: %s pixels/second\n",
|
||||
PerfHumanFloat(rate));
|
||||
|
||||
/* blended fill */
|
||||
glEnable(GL_BLEND);
|
||||
rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
|
||||
glDisable(GL_BLEND);
|
||||
perf_printf(" Blended fill: %s pixels/second\n",
|
||||
PerfHumanFloat(rate));
|
||||
|
||||
/* textured fill */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
perf_printf(" Textured fill: %s pixels/second\n",
|
||||
PerfHumanFloat(rate));
|
||||
|
||||
/* shader1 fill */
|
||||
glUseProgram(ShaderProg1);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
|
||||
glUseProgram(0);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
perf_printf(" Shader1 fill: %s pixels/second\n",
|
||||
PerfHumanFloat(rate));
|
||||
|
||||
/* shader2 fill */
|
||||
glUseProgram(ShaderProg2);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
|
||||
glUseProgram(0);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
perf_printf(" Shader2 fill: %s pixels/second\n",
|
||||
PerfHumanFloat(rate));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
136
progs/perf/genmipmap.c
Normal file
136
progs/perf/genmipmap.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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 glGenerateMipmap() speed.
|
||||
*
|
||||
* Brian Paul
|
||||
* 24 Sep 2009
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
int WinWidth = 100, WinHeight = 100;
|
||||
|
||||
static GLboolean DrawPoint = GL_TRUE;
|
||||
static GLuint VBO;
|
||||
static GLuint TexObj = 0;
|
||||
static GLint BaseLevel, MaxLevel;
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
GenMipmap(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLubyte texel[4];
|
||||
texel[0] = texel[1] = texel[2] = texel[3] = i & 0xff;
|
||||
/* dirty the base image */
|
||||
glTexSubImage2D(GL_TEXTURE_2D, BaseLevel,
|
||||
0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texel);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
const GLint NumLevels = 12;
|
||||
const GLint TexWidth = 2048, TexHeight = 2048;
|
||||
GLubyte *img;
|
||||
double rate;
|
||||
|
||||
/* Make 2K x 2K texture */
|
||||
img = (GLubyte *) malloc(TexWidth * TexHeight * 4);
|
||||
memset(img, 128, TexWidth * TexHeight * 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
GL_RGBA, TexWidth, TexHeight, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, img);
|
||||
free(img);
|
||||
|
||||
perf_printf("Texture level[0] size: %d x %d, %d levels\n",
|
||||
TexWidth, TexHeight, NumLevels);
|
||||
|
||||
/* loop over base levels 0, 2, 4 */
|
||||
for (BaseLevel = 0; BaseLevel <= 4; BaseLevel += 2) {
|
||||
|
||||
/* loop over max level */
|
||||
for (MaxLevel = NumLevels; MaxLevel > BaseLevel; MaxLevel--) {
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel);
|
||||
|
||||
rate = PerfMeasureRate(GenMipmap);
|
||||
|
||||
perf_printf(" glGenerateMipmap(levels %d..%d): %.2f gens/sec\n",
|
||||
BaseLevel + 1, MaxLevel, rate);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -26,13 +26,13 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#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 */
|
||||
|
|
@ -50,13 +50,133 @@ PerfSwapBuffers(void)
|
|||
}
|
||||
|
||||
|
||||
/** make simple checkerboard texture object */
|
||||
GLuint
|
||||
PerfCheckerTexture(GLsizei width, GLsizei height)
|
||||
{
|
||||
const GLenum filter = GL_NEAREST;
|
||||
GLubyte *img = (GLubyte *) malloc(width * height * 4);
|
||||
GLint i, j, k;
|
||||
GLuint obj;
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
GLubyte color;
|
||||
if (((i / 8) ^ (j / 8)) & 1) {
|
||||
color = 0xff;
|
||||
}
|
||||
else {
|
||||
color = 0x0;
|
||||
}
|
||||
img[k++] = color;
|
||||
img[k++] = color;
|
||||
img[k++] = color;
|
||||
img[k++] = color;
|
||||
}
|
||||
}
|
||||
|
||||
glGenTextures(1, &obj);
|
||||
glBindTexture(GL_TEXTURE_2D, obj);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, img);
|
||||
free(img);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
static GLuint
|
||||
CompileShader(GLenum type, const char *shader)
|
||||
{
|
||||
GLuint sh;
|
||||
GLint stat;
|
||||
|
||||
sh = glCreateShader(type);
|
||||
glShaderSource(sh, 1, (const GLchar **) &shader, NULL);
|
||||
|
||||
glCompileShader(sh);
|
||||
|
||||
glGetShaderiv(sh, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog(sh, 1000, &len, log);
|
||||
fprintf(stderr, "Error: problem compiling shader: %s\n", log);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
|
||||
/** Make shader program from given vert/frag shader text */
|
||||
GLuint
|
||||
PerfShaderProgram(const char *vertShader, const char *fragShader)
|
||||
{
|
||||
GLuint prog;
|
||||
GLint stat;
|
||||
|
||||
{
|
||||
const char *version = (const char *) glGetString(GL_VERSION);
|
||||
if ((version[0] != '2' &&
|
||||
version[0] != '3') || version[1] != '.') {
|
||||
fprintf(stderr, "Error: GL version 2.x or better required\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
prog = glCreateProgram();
|
||||
|
||||
if (vertShader) {
|
||||
GLuint vs = CompileShader(GL_VERTEX_SHADER, vertShader);
|
||||
glAttachShader(prog, vs);
|
||||
}
|
||||
if (fragShader) {
|
||||
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragShader);
|
||||
glAttachShader(prog, fs);
|
||||
}
|
||||
|
||||
glLinkProgram(prog);
|
||||
glGetProgramiv(prog, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog(prog, 1000, &len, log);
|
||||
fprintf(stderr, "Shader link error:\n%s\n", log);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PerfReshapeWindow( unsigned w, unsigned h )
|
||||
{
|
||||
if (glutGet(GLUT_SCREEN_WIDTH) < w ||
|
||||
glutGet(GLUT_SCREEN_HEIGHT) < h)
|
||||
return 0;
|
||||
|
||||
glutReshapeWindow( w, h );
|
||||
glutPostRedisplay();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
PerfExtensionSupported(const char *ext)
|
||||
{
|
||||
return glutExtensionSupported(ext);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Idle(void)
|
||||
{
|
||||
Xrot += 3.0;
|
||||
Yrot += 4.0;
|
||||
Zrot += 2.0;
|
||||
glutPostRedisplay();
|
||||
PerfNextRound();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -90,13 +210,6 @@ Key(unsigned char key, int x, int y)
|
|||
(void) x;
|
||||
(void) y;
|
||||
switch (key) {
|
||||
case 'a':
|
||||
Anim = !Anim;
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 'z':
|
||||
Zrot -= step;
|
||||
break;
|
||||
|
|
@ -141,15 +254,14 @@ main(int argc, char *argv[])
|
|||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowSize(WinWidth, WinHeight);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
|
||||
Win = glutCreateWindow(argv[0]);
|
||||
glewInit();
|
||||
glutReshapeFunc(Reshape);
|
||||
glutKeyboardFunc(Key);
|
||||
glutSpecialFunc(SpecialKey);
|
||||
glutDisplayFunc(Draw);
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
glutIdleFunc(Idle);
|
||||
PerfInit();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -40,12 +40,27 @@ PerfGetTime(void);
|
|||
extern void
|
||||
PerfSwapBuffers(void);
|
||||
|
||||
extern GLuint
|
||||
PerfCheckerTexture(GLsizei width, GLsizei height);
|
||||
|
||||
extern GLuint
|
||||
PerfShaderProgram(const char *vertShader, const char *fragShader);
|
||||
|
||||
extern int
|
||||
PerfReshapeWindow( unsigned w, unsigned h );
|
||||
|
||||
extern GLboolean
|
||||
PerfExtensionSupported(const char *ext);
|
||||
|
||||
|
||||
/** Test programs must implement these functions **/
|
||||
|
||||
extern void
|
||||
PerfInit(void);
|
||||
|
||||
extern void
|
||||
PerfNextRound(void);
|
||||
|
||||
extern void
|
||||
PerfDraw(void);
|
||||
|
||||
|
|
|
|||
169
progs/perf/readpixels.c
Normal file
169
progs/perf/readpixels.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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 glReadPixels speed.
|
||||
* XXX also read into a PBO?
|
||||
* XXX also read from FBOs?
|
||||
*
|
||||
* Brian Paul
|
||||
* 23 Sep 2009
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
int WinWidth = 1000, WinHeight = 1000;
|
||||
|
||||
static GLuint VBO;
|
||||
|
||||
static const GLboolean DrawPoint = GL_TRUE;
|
||||
static const GLboolean BufferSubDataInHalves = GL_TRUE;
|
||||
|
||||
static const GLfloat Vertex0[2] = { 0.0, 0.0 };
|
||||
|
||||
static GLenum HaveDepthStencil;
|
||||
|
||||
static GLenum ReadFormat, ReadType;
|
||||
static GLint ReadWidth, ReadHeight;
|
||||
static GLvoid *ReadBuffer;
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfInit(void)
|
||||
{
|
||||
/* setup VBO */
|
||||
glGenBuffersARB(1, &VBO);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vertex0), Vertex0, GL_STATIC_DRAW_ARB);
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
HaveDepthStencil = PerfExtensionSupported("GL_EXT_packed_depth_stencil");
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ReadPixels(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
/* read from random pos */
|
||||
GLint x, y;
|
||||
|
||||
x = WinWidth - ReadWidth;
|
||||
y = WinHeight - ReadHeight;
|
||||
if (x > 0)
|
||||
x = rand() % x;
|
||||
if (y > 0)
|
||||
y = rand() % y;
|
||||
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
glReadPixels(x, y, ReadWidth, ReadHeight,
|
||||
ReadFormat, ReadType, ReadBuffer);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
static const GLsizei Sizes[] = {
|
||||
10,
|
||||
100,
|
||||
500,
|
||||
1000,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static const struct {
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
const char *name;
|
||||
GLuint pixel_size;
|
||||
} DstFormats[] = {
|
||||
{ GL_RGBA, GL_UNSIGNED_BYTE, "RGBA/ubyte", 4 },
|
||||
{ GL_BGRA, GL_UNSIGNED_BYTE, "BGRA/ubyte", 4 },
|
||||
{ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, "RGB/565", 2 },
|
||||
{ GL_LUMINANCE, GL_UNSIGNED_BYTE, "L/ubyte", 1 },
|
||||
{ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, "Z/uint", 4 },
|
||||
{ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, "Z+S/uint", 4 },
|
||||
{ 0, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
double rate, mbPerSec;
|
||||
int fmt, sz;
|
||||
|
||||
/* loop over formats */
|
||||
for (fmt = 0; DstFormats[fmt].format; fmt++) {
|
||||
ReadFormat = DstFormats[fmt].format;
|
||||
ReadType = DstFormats[fmt].type;
|
||||
|
||||
/* loop over sizes */
|
||||
for (sz = 0; Sizes[sz]; sz++) {
|
||||
int imgSize;
|
||||
|
||||
ReadWidth = ReadHeight = Sizes[sz];
|
||||
imgSize = ReadWidth * ReadHeight * DstFormats[fmt].pixel_size;
|
||||
ReadBuffer = malloc(imgSize);
|
||||
|
||||
if (ReadFormat == GL_DEPTH_STENCIL_EXT && !HaveDepthStencil) {
|
||||
rate = 0.0;
|
||||
mbPerSec = 0.0;
|
||||
}
|
||||
else {
|
||||
rate = PerfMeasureRate(ReadPixels);
|
||||
mbPerSec = rate * imgSize / (1024.0 * 1024.0);
|
||||
}
|
||||
|
||||
perf_printf("glReadPixels(%d x %d, %s): %.1f images/sec, %.1f Mpixels/sec\n",
|
||||
ReadWidth, ReadHeight,
|
||||
DstFormats[fmt].name, rate, mbPerSec);
|
||||
|
||||
free(ReadBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
161
progs/perf/swapbuffers.c
Normal file
161
progs/perf/swapbuffers.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* 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 SwapBuffers.
|
||||
*
|
||||
* Keith Whitwell
|
||||
* 22 Sep 2009
|
||||
*/
|
||||
|
||||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
int WinWidth = 100, WinHeight = 100;
|
||||
int real_WinWidth, real_WinHeight; /* don't know whats going on here */
|
||||
|
||||
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
|
||||
SwapNaked(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
PerfSwapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
SwapClear(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
PerfSwapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SwapClearPoint(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDrawArrays(GL_POINTS, 0, 4);
|
||||
PerfSwapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const struct {
|
||||
unsigned w;
|
||||
unsigned h;
|
||||
} sizes[] = {
|
||||
{ 320, 240 },
|
||||
{ 640, 480 },
|
||||
{ 1024, 768 },
|
||||
{ 1200, 1024 },
|
||||
{ 1600, 1200 }
|
||||
};
|
||||
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
static unsigned i;
|
||||
|
||||
if (i < sizeof(sizes) / sizeof(sizes[0]) &&
|
||||
PerfReshapeWindow( sizes[i].w, sizes[i].h ))
|
||||
{
|
||||
perf_printf("Reshape %dx%d\n", sizes[i].w, sizes[i].h);
|
||||
real_WinWidth = sizes[i].w;
|
||||
real_WinHeight = sizes[i].h;
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
double rate0;
|
||||
|
||||
rate0 = PerfMeasureRate(SwapNaked);
|
||||
perf_printf(" Swapbuffers %dx%d: %s swaps/second",
|
||||
real_WinWidth, real_WinHeight,
|
||||
PerfHumanFloat(rate0));
|
||||
perf_printf(" %s pixels/second\n",
|
||||
PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
|
||||
|
||||
|
||||
|
||||
rate0 = PerfMeasureRate(SwapClear);
|
||||
perf_printf(" Swap/Clear %dx%d: %s swaps/second",
|
||||
real_WinWidth, real_WinHeight,
|
||||
PerfHumanFloat(rate0));
|
||||
perf_printf(" %s pixels/second\n",
|
||||
PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
|
||||
|
||||
|
||||
rate0 = PerfMeasureRate(SwapClearPoint);
|
||||
perf_printf(" Swap/Clear/Draw %dx%d: %s swaps/second",
|
||||
real_WinWidth, real_WinHeight,
|
||||
PerfHumanFloat(rate0));
|
||||
perf_printf(" %s pixels/second\n",
|
||||
PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
|
||||
}
|
||||
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Measure glTexSubImage2D rate
|
||||
* Measure glTex[Sub]Image2D() and glGetTexImage() rate
|
||||
*
|
||||
* Brian Paul
|
||||
* 16 Sep 2009
|
||||
|
|
@ -36,10 +36,28 @@ static GLuint VBO;
|
|||
static GLuint TexObj = 0;
|
||||
static GLubyte *TexImage = NULL;
|
||||
static GLsizei TexSize;
|
||||
static GLenum TexSrcFormat, TexSrcType;
|
||||
static GLenum TexIntFormat, TexSrcFormat, TexSrcType;
|
||||
|
||||
static const GLboolean DrawPoint = GL_TRUE;
|
||||
static const GLboolean TexSubImage4 = GL_TRUE;
|
||||
static const GLboolean TexSubImage4 = GL_FALSE;
|
||||
|
||||
enum {
|
||||
MODE_CREATE_TEXIMAGE,
|
||||
MODE_TEXIMAGE,
|
||||
MODE_TEXSUBIMAGE,
|
||||
MODE_GETTEXIMAGE,
|
||||
MODE_COUNT
|
||||
};
|
||||
|
||||
static const char *mode_name[MODE_COUNT] =
|
||||
{
|
||||
"Create_TexImage",
|
||||
"TexImage",
|
||||
"TexSubImage",
|
||||
"GetTexImage"
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct vertex
|
||||
{
|
||||
|
|
@ -50,11 +68,8 @@ static const struct vertex vertices[1] = {
|
|||
{ 0.0, 0.0, 0.5, 0.5 },
|
||||
};
|
||||
|
||||
#if 0
|
||||
#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
|
||||
#else
|
||||
#define VOFFSET(F) ((void *) &((struct vertex *)NULL)->F)
|
||||
#endif
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
|
|
@ -79,6 +94,32 @@ PerfInit(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
CreateUploadTexImage2D(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (TexObj)
|
||||
glDeleteTextures(1, &TexObj);
|
||||
|
||||
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);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
|
||||
TexSize, TexSize, 0,
|
||||
TexSrcFormat, TexSrcType, TexImage);
|
||||
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UploadTexImage2D(unsigned count)
|
||||
{
|
||||
|
|
@ -89,7 +130,7 @@ UploadTexImage2D(unsigned count)
|
|||
* in Mesa but may be optimized in other drivers. Note sure how
|
||||
* much difference that might make.
|
||||
*/
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
|
||||
TexSize, TexSize, 0,
|
||||
TexSrcFormat, TexSrcType, TexImage);
|
||||
if (DrawPoint)
|
||||
|
|
@ -132,8 +173,8 @@ UploadTexSubImage2D(unsigned count)
|
|||
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);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
else {
|
||||
/* replace whole texture image at once */
|
||||
|
|
@ -148,17 +189,43 @@ UploadTexSubImage2D(unsigned count)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
GetTexImage2D(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
GLubyte *buf = (GLubyte *) malloc(TexSize * TexSize * 4);
|
||||
for (i = 0; i < count; i++) {
|
||||
glGetTexImage(GL_TEXTURE_2D, 0,
|
||||
TexSrcFormat, TexSrcType, buf);
|
||||
}
|
||||
glFinish();
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
/* XXX any other formats to measure? */
|
||||
static const struct {
|
||||
GLenum format, type;
|
||||
GLenum internal_format;
|
||||
const char *name;
|
||||
GLuint texel_size;
|
||||
GLboolean full_test;
|
||||
} SrcFormats[] = {
|
||||
{ GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" },
|
||||
{ GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" },
|
||||
{ 0, 0, NULL }
|
||||
{ GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, "RGBA/ubyte", 4, GL_TRUE },
|
||||
{ GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, "RGB/ubyte", 3, GL_FALSE },
|
||||
{ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, "RGB/565", 2, GL_FALSE },
|
||||
{ GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, "BGRA/ubyte", 4, GL_FALSE },
|
||||
{ GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, "L/ubyte", 1, GL_FALSE },
|
||||
{ 0, 0, 0, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
|
|
@ -166,46 +233,97 @@ PerfDraw(void)
|
|||
{
|
||||
GLint maxSize;
|
||||
double rate;
|
||||
GLint fmt, subImage;
|
||||
GLint fmt, mode;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
|
||||
|
||||
/* loop over source data formats */
|
||||
for (fmt = 0; SrcFormats[fmt].format; fmt++) {
|
||||
TexIntFormat = SrcFormats[fmt].internal_format;
|
||||
TexSrcFormat = SrcFormats[fmt].format;
|
||||
TexSrcType = SrcFormats[fmt].type;
|
||||
|
||||
/* loop over glTexImage, glTexSubImage */
|
||||
for (subImage = 0; subImage < 2; subImage++) {
|
||||
for (mode = 0; mode < MODE_COUNT; mode++) {
|
||||
GLuint minsz, maxsz;
|
||||
|
||||
/* loop over texture sizes */
|
||||
for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) {
|
||||
GLint bytesPerImage;
|
||||
if (SrcFormats[fmt].full_test) {
|
||||
minsz = 16;
|
||||
maxsz = 4096;
|
||||
}
|
||||
else {
|
||||
minsz = maxsz = 256;
|
||||
if (mode == MODE_CREATE_TEXIMAGE)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* loop over a defined range of texture sizes, test only the
|
||||
* ones which are legal for this driver.
|
||||
*/
|
||||
for (TexSize = minsz; TexSize <= maxsz; TexSize *= 4) {
|
||||
double mbPerSec;
|
||||
|
||||
bytesPerImage = TexSize * TexSize * 4;
|
||||
TexImage = malloc(bytesPerImage);
|
||||
if (TexSize <= maxSize) {
|
||||
GLint bytesPerImage;
|
||||
|
||||
bytesPerImage = TexSize * TexSize * SrcFormats[fmt].texel_size;
|
||||
TexImage = malloc(bytesPerImage);
|
||||
|
||||
switch (mode) {
|
||||
case MODE_TEXIMAGE:
|
||||
rate = PerfMeasureRate(UploadTexImage2D);
|
||||
break;
|
||||
|
||||
case MODE_CREATE_TEXIMAGE:
|
||||
rate = PerfMeasureRate(CreateUploadTexImage2D);
|
||||
break;
|
||||
|
||||
case MODE_TEXSUBIMAGE:
|
||||
/* create initial, empty texture */
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
|
||||
TexSize, TexSize, 0,
|
||||
TexSrcFormat, TexSrcType, NULL);
|
||||
rate = PerfMeasureRate(UploadTexSubImage2D);
|
||||
break;
|
||||
|
||||
case MODE_GETTEXIMAGE:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
|
||||
TexSize, TexSize, 0,
|
||||
TexSrcFormat, TexSrcType, TexImage);
|
||||
rate = PerfMeasureRate(GetTexImage2D);
|
||||
break;
|
||||
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
|
||||
free(TexImage);
|
||||
|
||||
|
||||
{
|
||||
unsigned err;
|
||||
err = glGetError();
|
||||
if (err) {
|
||||
perf_printf("non-zero glGetError() %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
rate = 0;
|
||||
mbPerSec = 0;
|
||||
}
|
||||
|
||||
mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
|
||||
|
||||
perf_printf(" glTex%sImage2D(%s %d x %d): "
|
||||
perf_printf(" %s(%s %d x %d): "
|
||||
"%.1f images/sec, %.1f MB/sec\n",
|
||||
(subImage ? "Sub" : ""),
|
||||
mode_name[mode],
|
||||
SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec);
|
||||
|
||||
free(TexImage);
|
||||
}
|
||||
|
||||
if (SrcFormats[fmt].full_test)
|
||||
perf_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
170
progs/perf/vbo.c
170
progs/perf/vbo.c
|
|
@ -31,13 +31,17 @@
|
|||
#include "glmain.h"
|
||||
#include "common.h"
|
||||
|
||||
/* Copy data out of a large array to avoid caching effects:
|
||||
*/
|
||||
#define DATA_SIZE (16*1024*1024)
|
||||
|
||||
int WinWidth = 100, WinHeight = 100;
|
||||
|
||||
static GLuint VBO;
|
||||
|
||||
static GLsizei VBOSize = 0;
|
||||
static GLubyte *VBOData = NULL;
|
||||
static GLsizei SubSize = 0;
|
||||
static GLubyte *VBOData = NULL; /* array[DATA_SIZE] */
|
||||
|
||||
static const GLboolean DrawPoint = GL_TRUE;
|
||||
static const GLboolean BufferSubDataInHalves = GL_TRUE;
|
||||
|
|
@ -61,11 +65,23 @@ static void
|
|||
UploadVBO(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
|
||||
unsigned total = 0;
|
||||
unsigned src = 0;
|
||||
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
for (i = 0; i < count; i++) {
|
||||
glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData + src, GL_STREAM_DRAW_ARB);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
/* Throw in an occasional flush to work around a driver crash:
|
||||
*/
|
||||
total += VBOSize;
|
||||
if (total >= 16*1024*1024) {
|
||||
glFlush();
|
||||
total = 0;
|
||||
}
|
||||
|
||||
src += VBOSize;
|
||||
src %= DATA_SIZE;
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
|
@ -75,18 +91,69 @@ static void
|
|||
UploadSubVBO(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned src = 0;
|
||||
|
||||
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);
|
||||
unsigned offset = (i * SubSize) % VBOSize;
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src);
|
||||
|
||||
if (DrawPoint) {
|
||||
glDrawArrays(GL_POINTS, offset / sizeof(Vertex0), 1);
|
||||
}
|
||||
|
||||
if (DrawPoint)
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
src += SubSize;
|
||||
src %= DATA_SIZE;
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
/* Do multiple small SubData uploads, then call DrawArrays. This may be a
|
||||
* fairer comparison to back-to-back BufferData calls:
|
||||
*/
|
||||
static void
|
||||
BatchUploadSubVBO(unsigned count)
|
||||
{
|
||||
unsigned i = 0, j;
|
||||
unsigned period = VBOSize / SubSize;
|
||||
unsigned src = 0;
|
||||
|
||||
while (i < count) {
|
||||
for (j = 0; j < period && i < count; j++, i++) {
|
||||
unsigned offset = j * SubSize;
|
||||
glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src);
|
||||
}
|
||||
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
src += SubSize;
|
||||
src %= DATA_SIZE;
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the sequence:
|
||||
* create/load VBO
|
||||
* draw
|
||||
* destroy VBO
|
||||
*/
|
||||
static void
|
||||
CreateDrawDestroyVBO(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLuint vbo;
|
||||
/* create/load */
|
||||
glGenBuffersARB(1, &vbo);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
|
||||
/* draw */
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
/* destroy */
|
||||
glDeleteBuffersARB(1, &vbo);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
|
|
@ -102,36 +169,77 @@ static const GLsizei Sizes[] = {
|
|||
0 /* end of list */
|
||||
};
|
||||
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
PerfDraw(void)
|
||||
{
|
||||
double rate, mbPerSec;
|
||||
int sub, sz;
|
||||
int i, sz;
|
||||
|
||||
/* loop over whole/sub buffer upload */
|
||||
for (sub = 0; sub < 2; sub++) {
|
||||
/* Load VBOData buffer with duplicated Vertex0.
|
||||
*/
|
||||
VBOData = calloc(DATA_SIZE, 1);
|
||||
|
||||
/* loop over VBO sizes */
|
||||
for (sz = 0; Sizes[sz]; sz++) {
|
||||
VBOSize = Sizes[sz];
|
||||
for (i = 0; i < DATA_SIZE / sizeof(Vertex0); i++) {
|
||||
memcpy(VBOData + i * sizeof(Vertex0),
|
||||
Vertex0,
|
||||
sizeof(Vertex0));
|
||||
}
|
||||
|
||||
VBOData = malloc(VBOSize);
|
||||
memcpy(VBOData, Vertex0, sizeof(Vertex0));
|
||||
/* glBufferDataARB()
|
||||
*/
|
||||
for (sz = 0; Sizes[sz]; sz++) {
|
||||
SubSize = VBOSize = Sizes[sz];
|
||||
rate = PerfMeasureRate(UploadVBO);
|
||||
mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
|
||||
perf_printf(" glBufferDataARB(size = %d): %.1f MB/sec\n",
|
||||
VBOSize, mbPerSec);
|
||||
}
|
||||
|
||||
if (sub)
|
||||
rate = PerfMeasureRate(UploadSubVBO);
|
||||
else
|
||||
rate = PerfMeasureRate(UploadVBO);
|
||||
/* glBufferSubDataARB()
|
||||
*/
|
||||
for (sz = 0; Sizes[sz]; sz++) {
|
||||
SubSize = VBOSize = Sizes[sz];
|
||||
rate = PerfMeasureRate(UploadSubVBO);
|
||||
mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
|
||||
perf_printf(" glBufferSubDataARB(size = %d): %.1f MB/sec\n",
|
||||
VBOSize, mbPerSec);
|
||||
}
|
||||
|
||||
mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
|
||||
/* Batch upload
|
||||
*/
|
||||
VBOSize = 1024 * 1024;
|
||||
glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
|
||||
|
||||
perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n",
|
||||
(sub ? "Sub" : ""), VBOSize, mbPerSec);
|
||||
for (sz = 0; Sizes[sz] < VBOSize; sz++) {
|
||||
SubSize = Sizes[sz];
|
||||
rate = PerfMeasureRate(UploadSubVBO);
|
||||
mbPerSec = rate * SubSize / (1024.0 * 1024.0);
|
||||
perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d): %.1f MB/sec\n",
|
||||
SubSize, VBOSize, mbPerSec);
|
||||
}
|
||||
|
||||
free(VBOData);
|
||||
}
|
||||
for (sz = 0; Sizes[sz] < VBOSize; sz++) {
|
||||
SubSize = Sizes[sz];
|
||||
rate = PerfMeasureRate(BatchUploadSubVBO);
|
||||
mbPerSec = rate * SubSize / (1024.0 * 1024.0);
|
||||
perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d), batched: %.1f MB/sec\n",
|
||||
SubSize, VBOSize, mbPerSec);
|
||||
}
|
||||
|
||||
/* Create/Draw/Destroy
|
||||
*/
|
||||
for (sz = 0; Sizes[sz]; sz++) {
|
||||
SubSize = VBOSize = Sizes[sz];
|
||||
rate = PerfMeasureRate(CreateDrawDestroyVBO);
|
||||
mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
|
||||
perf_printf(" VBO Create/Draw/Destroy(size = %d): %.1f MB/sec, %.1f draws/sec\n",
|
||||
VBOSize, mbPerSec, rate);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
|
|
|||
|
|
@ -228,6 +228,11 @@ DrawRangeElementsBO(unsigned count)
|
|||
PerfSwapBuffers();
|
||||
}
|
||||
|
||||
void
|
||||
PerfNextRound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Called from test harness/main */
|
||||
void
|
||||
|
|
@ -241,31 +246,31 @@ PerfDraw(void)
|
|||
|
||||
rate = PerfMeasureRate(DrawImmediate);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" Immediate mode: %.1f verts/sec\n", rate);
|
||||
perf_printf(" Immediate mode: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
rate = PerfMeasureRate(DrawArraysMem);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" glDrawArrays: %.1f verts/sec\n", rate);
|
||||
perf_printf(" glDrawArrays: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
rate = PerfMeasureRate(DrawArraysVBO);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" VBO glDrawArrays: %.1f verts/sec\n", rate);
|
||||
perf_printf(" VBO glDrawArrays: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
rate = PerfMeasureRate(DrawElementsMem);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" glDrawElements: %.1f verts/sec\n", rate);
|
||||
perf_printf(" glDrawElements: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
rate = PerfMeasureRate(DrawElementsBO);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" VBO glDrawElements: %.1f verts/sec\n", rate);
|
||||
perf_printf(" VBO glDrawElements: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
rate = PerfMeasureRate(DrawRangeElementsMem);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" glDrawRangeElements: %.1f verts/sec\n", rate);
|
||||
perf_printf(" glDrawRangeElements: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
rate = PerfMeasureRate(DrawRangeElementsBO);
|
||||
rate *= NumVerts;
|
||||
perf_printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate);
|
||||
perf_printf(" VBO glDrawRangeElements: %s verts/sec\n", PerfHumanFloat(rate));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,4 +45,4 @@ $(OBJECTS): %.o: %.c
|
|||
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@
|
||||
|
||||
$(PROGS): %: %.o
|
||||
$(CC) $(LDFLAGS) $< $(LINKS) -o $@
|
||||
$(CC) $(LDFLAGS) $< $(LINKS) -lm -o $@
|
||||
|
|
|
|||
|
|
@ -77,15 +77,16 @@ InitValues(void)
|
|||
}
|
||||
|
||||
|
||||
static void MakeImage(int level, int width, int height, const GLubyte color[4])
|
||||
static void
|
||||
MakeImage(int level, int width, int height, const GLubyte color[4])
|
||||
{
|
||||
const int makeStripes = 0;
|
||||
GLubyte img[512*512*3];
|
||||
GLubyte img[512 * 512 * 3];
|
||||
int i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
int k = (i * width + j) * 3;
|
||||
int p = (i/8) & makeStripes;
|
||||
int p = (i / 8) & makeStripes;
|
||||
if (p == 0) {
|
||||
img[k + 0] = color[0];
|
||||
img[k + 1] = color[1];
|
||||
|
|
@ -104,7 +105,8 @@ static void MakeImage(int level, int width, int height, const GLubyte color[4])
|
|||
}
|
||||
|
||||
|
||||
static void makeImages(int image)
|
||||
static void
|
||||
makeImages(int image)
|
||||
{
|
||||
#define WIDTH 512
|
||||
#define HEIGHT 512
|
||||
|
|
@ -121,19 +123,20 @@ static void makeImages(int image)
|
|||
if (width != WIDTH || height != HEIGHT) {
|
||||
GLubyte *newImage = malloc(WIDTH * HEIGHT * 4);
|
||||
gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
|
||||
WIDTH, HEIGHT, GL_UNSIGNED_BYTE, newImage);
|
||||
WIDTH, HEIGHT, GL_UNSIGNED_BYTE, newImage);
|
||||
free(image);
|
||||
image = newImage;
|
||||
}
|
||||
printf("Using GL_SGIS_generate_mipmap\n");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, WIDTH, HEIGHT, 0,
|
||||
format, GL_UNSIGNED_BYTE, image);
|
||||
format, GL_UNSIGNED_BYTE, image);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
|
||||
free(image);
|
||||
|
||||
/* make sure mipmap was really generated correctly */
|
||||
width = WIDTH; height = HEIGHT;
|
||||
width = WIDTH;
|
||||
height = HEIGHT;
|
||||
for (i = 0; i < 10; i++) {
|
||||
GLint w, h;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
|
||||
|
|
@ -142,18 +145,19 @@ static void makeImages(int image)
|
|||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
static const GLubyte colors[10][3] = {
|
||||
{128, 128, 128 },
|
||||
{ 0, 255, 255 },
|
||||
{ 255, 255, 0 },
|
||||
{ 255, 0, 255 },
|
||||
{ 255, 0, 0 },
|
||||
{ 0, 255, 0 },
|
||||
{ 0, 0, 255 },
|
||||
{ 0, 255, 255 },
|
||||
{ 255, 255, 0 },
|
||||
{ 255, 255, 255 }
|
||||
{128, 128, 128},
|
||||
{0, 255, 255},
|
||||
{255, 255, 0},
|
||||
{255, 0, 255},
|
||||
{255, 0, 0},
|
||||
{0, 255, 0},
|
||||
{0, 0, 255},
|
||||
{0, 255, 255},
|
||||
{255, 255, 0},
|
||||
{255, 255, 255}
|
||||
};
|
||||
int i, sz = 512;
|
||||
|
||||
|
|
@ -165,7 +169,8 @@ static void makeImages(int image)
|
|||
}
|
||||
}
|
||||
|
||||
static void myinit(void)
|
||||
static void
|
||||
myinit(void)
|
||||
{
|
||||
InitValues();
|
||||
|
||||
|
|
@ -191,14 +196,16 @@ static void myinit(void)
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
static void display(void)
|
||||
static void
|
||||
display(void)
|
||||
{
|
||||
GLfloat tcm = 1.0;
|
||||
glBindTexture(GL_TEXTURE_2D, texCurrent);
|
||||
|
||||
printf("BASE_LEVEL=%d MAX_LEVEL=%d MIN_LOD=%.2g MAX_LOD=%.2g Bias=%.2g Filter=%s\n",
|
||||
BaseLevel, MaxLevel, MinLod, MaxLod, LodBias,
|
||||
NearestFilter ? "NEAREST" : "LINEAR");
|
||||
printf
|
||||
("BASE_LEVEL=%d MAX_LEVEL=%d MIN_LOD=%.2g MAX_LOD=%.2g Bias=%.2g Filter=%s\n",
|
||||
BaseLevel, MaxLevel, MinLod, MaxLod, LodBias,
|
||||
NearestFilter ? "NEAREST" : "LINEAR");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel);
|
||||
|
||||
|
|
@ -208,103 +215,44 @@ static void display(void)
|
|||
if (NearestFilter) {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST_MIPMAP_NEAREST);
|
||||
GL_NEAREST_MIPMAP_NEAREST);
|
||||
}
|
||||
else {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, LodBias);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
|
||||
glTexCoord2f(0.0, tcm); glVertex3f(-2.0, 1.0, 0.0);
|
||||
glTexCoord2f(tcm * 3000.0, tcm); glVertex3f(3000.0, 1.0, -6000.0);
|
||||
glTexCoord2f(tcm * 3000.0, 0.0); glVertex3f(3000.0, -1.0, -6000.0);
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex3f(-2.0, -1.0, 0.0);
|
||||
glTexCoord2f(0.0, tcm);
|
||||
glVertex3f(-2.0, 1.0, 0.0);
|
||||
glTexCoord2f(tcm * 3000.0, tcm);
|
||||
glVertex3f(3000.0, 1.0, -6000.0);
|
||||
glTexCoord2f(tcm * 3000.0, 0.0);
|
||||
glVertex3f(3000.0, -1.0, -6000.0);
|
||||
glEnd();
|
||||
glFlush();
|
||||
}
|
||||
|
||||
static void myReshape(int w, int h)
|
||||
static void
|
||||
myReshape(int w, int h)
|
||||
{
|
||||
glViewport(0, 0, w, h);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30000.0);
|
||||
gluPerspective(60.0, 1.0 * (GLfloat) w / (GLfloat) h, 1.0, 30000.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
key(unsigned char k, int x, int y)
|
||||
{
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (k) {
|
||||
case 'b':
|
||||
BaseLevel--;
|
||||
if (BaseLevel < 0)
|
||||
BaseLevel = 0;
|
||||
break;
|
||||
case 'B':
|
||||
BaseLevel++;
|
||||
if (BaseLevel > 10)
|
||||
BaseLevel = 10;
|
||||
break;
|
||||
case 'm':
|
||||
MaxLevel--;
|
||||
if (MaxLevel < 0)
|
||||
MaxLevel = 0;
|
||||
break;
|
||||
case 'M':
|
||||
MaxLevel++;
|
||||
if (MaxLevel > 10)
|
||||
MaxLevel = 10;
|
||||
break;
|
||||
case 'l':
|
||||
LodBias -= 0.25;
|
||||
break;
|
||||
case 'L':
|
||||
LodBias += 0.25;
|
||||
break;
|
||||
case 'n':
|
||||
MinLod -= 0.25;
|
||||
break;
|
||||
case 'N':
|
||||
MinLod += 0.25;
|
||||
break;
|
||||
case 'x':
|
||||
MaxLod -= 0.25;
|
||||
break;
|
||||
case 'X':
|
||||
MaxLod += 0.25;
|
||||
break;
|
||||
case 'f':
|
||||
NearestFilter = !NearestFilter;
|
||||
break;
|
||||
case 't':
|
||||
if (texCurrent == texColor)
|
||||
texCurrent = texImage;
|
||||
else
|
||||
texCurrent = texColor;
|
||||
break;
|
||||
case ' ':
|
||||
InitValues();
|
||||
break;
|
||||
case 27: /* Escape */
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void usage(void)
|
||||
usage(void)
|
||||
{
|
||||
printf("usage:\n");
|
||||
printf(" b/B decrease/increase GL_TEXTURE_BASE_LEVEL\n");
|
||||
|
|
@ -317,19 +265,88 @@ static void usage(void)
|
|||
printf(" SPACE reset values\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
static void
|
||||
key(unsigned char k, int x, int y)
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
|
||||
glutInitWindowSize (600, 600);
|
||||
glutCreateWindow (argv[0]);
|
||||
glewInit();
|
||||
myinit();
|
||||
glutReshapeFunc (myReshape);
|
||||
glutDisplayFunc(display);
|
||||
glutKeyboardFunc(key);
|
||||
usage();
|
||||
glutMainLoop();
|
||||
return 0; /* ANSI C requires main to return int. */
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (k) {
|
||||
case 'b':
|
||||
BaseLevel--;
|
||||
if (BaseLevel < 0)
|
||||
BaseLevel = 0;
|
||||
break;
|
||||
case 'B':
|
||||
BaseLevel++;
|
||||
if (BaseLevel > 10)
|
||||
BaseLevel = 10;
|
||||
break;
|
||||
case 'm':
|
||||
MaxLevel--;
|
||||
if (MaxLevel < 0)
|
||||
MaxLevel = 0;
|
||||
break;
|
||||
case 'M':
|
||||
MaxLevel++;
|
||||
if (MaxLevel > 10)
|
||||
MaxLevel = 10;
|
||||
break;
|
||||
case 'l':
|
||||
LodBias -= 0.25;
|
||||
break;
|
||||
case 'L':
|
||||
LodBias += 0.25;
|
||||
break;
|
||||
case 'n':
|
||||
MinLod -= 0.25;
|
||||
break;
|
||||
case 'N':
|
||||
MinLod += 0.25;
|
||||
break;
|
||||
case 'x':
|
||||
MaxLod -= 0.25;
|
||||
break;
|
||||
case 'X':
|
||||
MaxLod += 0.25;
|
||||
break;
|
||||
case 'f':
|
||||
NearestFilter = !NearestFilter;
|
||||
break;
|
||||
case 't':
|
||||
if (texCurrent == texColor)
|
||||
texCurrent = texImage;
|
||||
else
|
||||
texCurrent = texColor;
|
||||
break;
|
||||
case ' ':
|
||||
InitValues();
|
||||
/* fall-through */
|
||||
case 'u':
|
||||
usage();
|
||||
break;
|
||||
case 27: /* Escape */
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
|
||||
glutInitWindowSize(600, 600);
|
||||
glutCreateWindow(argv[0]);
|
||||
glewInit();
|
||||
myinit();
|
||||
glutReshapeFunc(myReshape);
|
||||
glutDisplayFunc(display);
|
||||
glutKeyboardFunc(key);
|
||||
usage();
|
||||
glutMainLoop();
|
||||
return 0; /* ANSI C requires main to return int. */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ def generate(env):
|
|||
# default in recent gcc versions
|
||||
env.AppendUnique(CFLAGS = ['-gstabs'])
|
||||
|
||||
env.AppendUnique(LIBS = ['iberty'])
|
||||
#env.AppendUnique(LIBS = ['iberty'])
|
||||
env.AppendUnique(SHLINKFLAGS = ['-Wl,--enable-stdcall-fixup'])
|
||||
#env.AppendUnique(SHLINKFLAGS = ['-Wl,--kill-at'])
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, Nat
|
|||
}
|
||||
}
|
||||
|
||||
if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
|
||||
if (GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) == 0) {
|
||||
_eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "glapi/glapi.h" /* for glapi functions */
|
||||
|
||||
#include "eglconfig.h"
|
||||
#include "eglconfigutil.h"
|
||||
#include "eglcontext.h"
|
||||
#include "egldisplay.h"
|
||||
#include "egldriver.h"
|
||||
|
|
@ -104,6 +105,7 @@ struct xdri_egl_config
|
|||
_EGLConfig Base; /**< base class */
|
||||
|
||||
const __GLcontextModes *mode; /**< corresponding GLX mode */
|
||||
EGLint window_render_buffer;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -162,46 +164,76 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
|
|||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m)
|
||||
{
|
||||
static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
|
||||
EGL_OPENGL_ES2_BIT |
|
||||
EGL_OPENVG_BIT |
|
||||
EGL_OPENGL_BIT);
|
||||
EGLint val;
|
||||
|
||||
_eglInitConfig(conf, id);
|
||||
if (!_eglConfigFromContextModesRec(conf, m, all_apis, all_apis))
|
||||
return EGL_FALSE;
|
||||
|
||||
if (m->doubleBufferMode) {
|
||||
/* pixmap and pbuffer surfaces are always single-buffered */
|
||||
val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
|
||||
val &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, val);
|
||||
}
|
||||
else {
|
||||
/* EGL requires OpenGL ES context to be double-buffered */
|
||||
val = GET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE);
|
||||
val &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, val);
|
||||
}
|
||||
/* skip "empty" config */
|
||||
if (!val)
|
||||
return EGL_FALSE;
|
||||
|
||||
val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
|
||||
if (!(val & EGL_PBUFFER_BIT)) {
|
||||
/* bind-to-texture cannot be EGL_TRUE without pbuffer bit */
|
||||
SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
|
||||
}
|
||||
|
||||
/* EGL_NATIVE_RENDERABLE is a boolean */
|
||||
val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE);
|
||||
if (val != EGL_TRUE)
|
||||
SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_FALSE);
|
||||
|
||||
return _eglValidateConfig(conf, EGL_FALSE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Produce a set of EGL configs.
|
||||
*/
|
||||
static EGLint
|
||||
create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id)
|
||||
{
|
||||
static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
|
||||
EGL_OPENGL_ES2_BIT |
|
||||
EGL_OPENVG_BIT |
|
||||
EGL_OPENGL_BIT);
|
||||
int id = first_id;
|
||||
|
||||
for (; m; m = m->next) {
|
||||
/* add double buffered visual */
|
||||
if (m->doubleBufferMode) {
|
||||
struct xdri_egl_config *config = CALLOC_STRUCT(xdri_egl_config);
|
||||
struct xdri_egl_config *xdri_conf;
|
||||
_EGLConfig conf;
|
||||
EGLint rb;
|
||||
|
||||
_eglInitConfig(&config->Base, id++);
|
||||
if (!convert_config(&conf, id, m))
|
||||
continue;
|
||||
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, m->rgbBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, m->redBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_GREEN_SIZE, m->greenBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_BLUE_SIZE, m->blueBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_ALPHA_SIZE, m->alphaBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_DEPTH_SIZE, m->depthBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_STENCIL_SIZE, m->stencilBits);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLES, m->samples);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLE_BUFFERS, m->sampleBuffers);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, m->visualID);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_TYPE, m->visualType);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis);
|
||||
SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
|
||||
rb = (m->doubleBufferMode) ? EGL_BACK_BUFFER : EGL_SINGLE_BUFFER;
|
||||
|
||||
/* XXX possibly other things to init... */
|
||||
|
||||
/* Ptr from EGL config to GLcontextMode. Used in CreateContext(). */
|
||||
config->mode = m;
|
||||
|
||||
_eglAddConfig(disp, &config->Base);
|
||||
xdri_conf = CALLOC_STRUCT(xdri_egl_config);
|
||||
if (xdri_conf) {
|
||||
memcpy(&xdri_conf->Base, &conf, sizeof(conf));
|
||||
xdri_conf->mode = m;
|
||||
xdri_conf->window_render_buffer = rb;
|
||||
_eglAddConfig(disp, &xdri_conf->Base);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,6 +395,9 @@ xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* the config decides the render buffer for the context */
|
||||
xdri_ctx->Base.WindowRenderBuffer = xdri_config->window_render_buffer;
|
||||
|
||||
xdri_ctx->driContext =
|
||||
psc->driScreen->createContext(psc,
|
||||
xdri_config->mode,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2,27 +2,93 @@
|
|||
#define EGLCONFIG_INCLUDED
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include "egltypedefs.h"
|
||||
#include <GLES/gl.h>
|
||||
|
||||
|
||||
#define MAX_ATTRIBS 128
|
||||
#define FIRST_ATTRIB EGL_BUFFER_SIZE
|
||||
#define _EGL_CONFIG_FIRST_ATTRIB EGL_BUFFER_SIZE
|
||||
#define _EGL_CONFIG_LAST_ATTRIB EGL_CONFORMANT
|
||||
#define _EGL_CONFIG_NUM_ATTRIBS \
|
||||
(_EGL_CONFIG_LAST_ATTRIB - _EGL_CONFIG_FIRST_ATTRIB + 1)
|
||||
|
||||
#define _EGL_CONFIG_STORAGE_SIZE _EGL_CONFIG_NUM_ATTRIBS
|
||||
|
||||
|
||||
struct _egl_config
|
||||
{
|
||||
EGLConfig Handle; /* the public/opaque handle which names this config */
|
||||
EGLint Attrib[MAX_ATTRIBS];
|
||||
_EGLDisplay *Display;
|
||||
EGLint Storage[_EGL_CONFIG_STORAGE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) \
|
||||
assert((ATTR) - FIRST_ATTRIB < MAX_ATTRIBS); \
|
||||
((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL)
|
||||
#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) _eglSetConfigKey(CONF, ATTR, VAL)
|
||||
#define GET_CONFIG_ATTRIB(CONF, ATTR) _eglGetConfigKey(CONF, ATTR)
|
||||
|
||||
|
||||
#define GET_CONFIG_ATTRIB(CONF, ATTR) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB])
|
||||
/**
|
||||
* Given a key, return an index into the storage of the config.
|
||||
* Return -1 if the key is invalid.
|
||||
*/
|
||||
static INLINE EGLint
|
||||
_eglIndexConfig(const _EGLConfig *conf, EGLint key)
|
||||
{
|
||||
(void) conf;
|
||||
if (key >= _EGL_CONFIG_FIRST_ATTRIB &&
|
||||
key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_ATTRIBS)
|
||||
return key - _EGL_CONFIG_FIRST_ATTRIB;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset all keys in the config to a given value.
|
||||
*/
|
||||
static INLINE void
|
||||
_eglResetConfigKeys(_EGLConfig *conf, EGLint val)
|
||||
{
|
||||
EGLint i;
|
||||
for (i = 0; i < _EGL_CONFIG_NUM_ATTRIBS; i++)
|
||||
conf->Storage[i] = val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a config for a given key.
|
||||
*/
|
||||
static INLINE void
|
||||
_eglSetConfigKey(_EGLConfig *conf, EGLint key, EGLint val)
|
||||
{
|
||||
EGLint idx = _eglIndexConfig(conf, key);
|
||||
assert(idx >= 0);
|
||||
conf->Storage[idx] = val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the value for a given key.
|
||||
*/
|
||||
static INLINE EGLint
|
||||
_eglGetConfigKey(const _EGLConfig *conf, EGLint key)
|
||||
{
|
||||
EGLint idx = _eglIndexConfig(conf, key);
|
||||
assert(idx >= 0);
|
||||
return conf->Storage[idx];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a given attribute.
|
||||
*
|
||||
* Because _eglGetConfigAttrib is already used as a fallback driver
|
||||
* function, this function is not considered to have a good name.
|
||||
* SET_CONFIG_ATTRIB is preferred over this function.
|
||||
*/
|
||||
static INLINE void
|
||||
_eglSetConfigAttrib(_EGLConfig *conf, EGLint attr, EGLint val)
|
||||
{
|
||||
SET_CONFIG_ATTRIB(conf, attr, val);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
|
|
@ -30,19 +96,76 @@ _eglInitConfig(_EGLConfig *config, EGLint id);
|
|||
|
||||
|
||||
extern EGLConfig
|
||||
_eglGetConfigHandle(_EGLConfig *config);
|
||||
_eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf);
|
||||
|
||||
|
||||
extern _EGLConfig *
|
||||
_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy);
|
||||
|
||||
|
||||
extern _EGLConfig *
|
||||
_eglAddConfig(_EGLDisplay *display, _EGLConfig *config);
|
||||
#ifndef _EGL_SKIP_HANDLE_CHECK
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list);
|
||||
_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy);
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
static INLINE EGLBoolean
|
||||
_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy)
|
||||
{
|
||||
_EGLConfig *conf = (_EGLConfig *) config;
|
||||
return (dpy && conf && conf->Display == dpy);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _EGL_SKIP_HANDLE_CHECK */
|
||||
|
||||
|
||||
/**
|
||||
* Lookup a handle to find the linked config.
|
||||
* Return NULL if the handle has no corresponding linked config.
|
||||
*/
|
||||
static INLINE _EGLConfig *
|
||||
_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy)
|
||||
{
|
||||
_EGLConfig *conf = (_EGLConfig *) config;
|
||||
if (!_eglCheckConfigHandle(config, dpy))
|
||||
conf = NULL;
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the handle of a linked config, or NULL.
|
||||
*/
|
||||
static INLINE EGLConfig
|
||||
_eglGetConfigHandle(_EGLConfig *conf)
|
||||
{
|
||||
return (EGLConfig) ((conf && conf->Display) ? conf : NULL);
|
||||
}
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list);
|
||||
|
||||
|
||||
extern EGLint
|
||||
_eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
|
||||
const _EGLConfig *criteria, EGLBoolean compare_id);
|
||||
|
||||
|
||||
extern void
|
||||
_eglSortConfigs(const _EGLConfig **configs, EGLint count,
|
||||
EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
|
||||
void *),
|
||||
void *priv_data);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
|
|
@ -57,8 +180,4 @@ extern EGLBoolean
|
|||
_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
|
||||
|
||||
extern void
|
||||
_eglSetConfigAttrib(_EGLConfig *config, EGLint attr, EGLint val);
|
||||
|
||||
|
||||
#endif /* EGLCONFIG_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -52,6 +52,78 @@ _eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a __GLcontextModes object to an _EGLConfig.
|
||||
*/
|
||||
EGLBoolean
|
||||
_eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m,
|
||||
EGLint conformant, EGLint renderable_type)
|
||||
{
|
||||
EGLint config_caveat, surface_type;
|
||||
|
||||
/* must be RGBA */
|
||||
if (!m->rgbMode || !(m->renderType & GLX_RGBA_BIT))
|
||||
return EGL_FALSE;
|
||||
|
||||
config_caveat = EGL_NONE;
|
||||
if (m->visualRating == GLX_SLOW_CONFIG)
|
||||
config_caveat = EGL_SLOW_CONFIG;
|
||||
|
||||
if (m->visualRating == GLX_NON_CONFORMANT_CONFIG)
|
||||
conformant &= ~EGL_OPENGL_BIT;
|
||||
if (!(conformant & EGL_OPENGL_ES_BIT))
|
||||
config_caveat = EGL_NON_CONFORMANT_CONFIG;
|
||||
|
||||
surface_type = 0;
|
||||
if (m->drawableType & GLX_WINDOW_BIT)
|
||||
surface_type |= EGL_WINDOW_BIT;
|
||||
if (m->drawableType & GLX_PIXMAP_BIT)
|
||||
surface_type |= EGL_PIXMAP_BIT;
|
||||
if (m->drawableType & GLX_PBUFFER_BIT)
|
||||
surface_type |= EGL_PBUFFER_BIT;
|
||||
|
||||
SET_CONFIG_ATTRIB(conf, EGL_BUFFER_SIZE, m->rgbBits);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_RED_SIZE, m->redBits);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_GREEN_SIZE, m->greenBits);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_BLUE_SIZE, m->blueBits);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_ALPHA_SIZE, m->alphaBits);
|
||||
|
||||
SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, m->bindToTextureRgb);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, m->bindToTextureRgba);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_CONFIG_CAVEAT, config_caveat);
|
||||
|
||||
SET_CONFIG_ATTRIB(conf, EGL_CONFORMANT, conformant);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_DEPTH_SIZE, m->depthBits);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_LEVEL, m->level);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_WIDTH, m->maxPbufferWidth);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_HEIGHT, m->maxPbufferHeight);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_PIXELS, m->maxPbufferPixels);
|
||||
|
||||
SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, m->xRenderable);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_ID, m->visualID);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, m->visualType);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, renderable_type);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS, m->sampleBuffers);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_SAMPLES, m->samples);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_STENCIL_SIZE, m->stencilBits);
|
||||
|
||||
SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, surface_type);
|
||||
|
||||
/* what to do with GLX_TRANSPARENT_INDEX? */
|
||||
if (m->transparentPixel == GLX_TRANSPARENT_RGB) {
|
||||
SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RGB);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_RED_VALUE, m->transparentRed);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_GREEN_VALUE, m->transparentGreen);
|
||||
SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_BLUE_VALUE, m->transparentBlue);
|
||||
}
|
||||
else {
|
||||
SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_TYPE, EGL_NONE);
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a set of \c _EGLConfigs that a driver will expose.
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
|
||||
#ifndef EGLCONFIGUTIL_INCLUDED
|
||||
#define EGLCONFIGUTIL_INCLUDED
|
||||
|
||||
#include "eglconfig.h"
|
||||
|
||||
#include "GLES/gl.h"
|
||||
#include "GL/internal/glcore.h"
|
||||
#if (!defined(WIN32) && !defined(_WIN32_WCE))
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
#include "eglconfig.h"
|
||||
|
||||
|
||||
extern void
|
||||
_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m,
|
||||
EGLint conformant, EGLint renderable_type);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglFillInConfigs( _EGLConfig *configs,
|
||||
EGLenum fb_format, EGLenum fb_type,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
|
|||
ctx->DrawSurface = EGL_NO_SURFACE;
|
||||
ctx->ReadSurface = EGL_NO_SURFACE;
|
||||
ctx->ClientAPI = api;
|
||||
ctx->WindowRenderBuffer = EGL_NONE;
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
|
@ -87,6 +88,24 @@ _eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
|
|||
}
|
||||
|
||||
|
||||
#ifdef EGL_VERSION_1_2
|
||||
static EGLint
|
||||
_eglQueryContextRenderBuffer(_EGLContext *ctx)
|
||||
{
|
||||
_EGLSurface *surf = ctx->DrawSurface;
|
||||
EGLint rb;
|
||||
|
||||
if (!surf)
|
||||
return EGL_NONE;
|
||||
if (surf->Type == EGL_WINDOW_BIT && ctx->WindowRenderBuffer != EGL_NONE)
|
||||
rb = ctx->WindowRenderBuffer;
|
||||
else
|
||||
rb = surf->RenderBuffer;
|
||||
return rb;
|
||||
}
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
|
||||
EGLint attribute, EGLint *value)
|
||||
|
|
@ -94,22 +113,29 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
|
|||
(void) drv;
|
||||
(void) dpy;
|
||||
|
||||
if (!value)
|
||||
return _eglError(EGL_BAD_PARAMETER, "eglQueryContext");
|
||||
|
||||
switch (attribute) {
|
||||
case EGL_CONFIG_ID:
|
||||
*value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
|
||||
return EGL_TRUE;
|
||||
break;
|
||||
case EGL_CONTEXT_CLIENT_VERSION:
|
||||
*value = c->ClientVersion;
|
||||
break;
|
||||
#ifdef EGL_VERSION_1_2
|
||||
case EGL_CONTEXT_CLIENT_TYPE:
|
||||
*value = c->ClientAPI;
|
||||
return EGL_TRUE;
|
||||
break;
|
||||
case EGL_RENDER_BUFFER:
|
||||
*value = _eglQueryContextRenderBuffer(c);
|
||||
break;
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
case EGL_CONTEXT_CLIENT_VERSION:
|
||||
*value = c->ClientVersion;
|
||||
return EGL_TRUE;
|
||||
default:
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
|
||||
return EGL_FALSE;
|
||||
return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ struct _egl_context
|
|||
|
||||
EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */
|
||||
EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */
|
||||
|
||||
/* The real render buffer when a window surface is bound */
|
||||
EGLint WindowRenderBuffer;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ struct _egl_display
|
|||
EGLint NumScreens;
|
||||
_EGLScreen **Screens; /* array [NumScreens] */
|
||||
|
||||
EGLint MaxConfigs;
|
||||
EGLint NumConfigs;
|
||||
_EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ SConscript([
|
|||
'auxiliary/pipebuffer/SConscript',
|
||||
'auxiliary/indices/SConscript',
|
||||
'auxiliary/rbug/SConscript',
|
||||
'auxiliary/vl/SConscript',
|
||||
])
|
||||
|
||||
for driver in env['drivers']:
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
|
|||
unsigned clipped = 0;
|
||||
unsigned j;
|
||||
|
||||
if (0) debug_printf("%s\n");
|
||||
if (0) debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
for (j = 0; j < count; j++) {
|
||||
float *position = out->data[pos];
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
|
|||
debug_printf("%10p %7u %7u\n",
|
||||
fenced_buf,
|
||||
fenced_buf->base.base.size,
|
||||
fenced_buf->base.base.reference.count);
|
||||
p_atomic_read(&fenced_buf->base.base.reference.count));
|
||||
curr = next;
|
||||
next = curr->next;
|
||||
}
|
||||
|
|
@ -556,7 +556,7 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
|
|||
debug_printf("%10p %7u %7u %10p %s\n",
|
||||
fenced_buf,
|
||||
fenced_buf->base.base.size,
|
||||
fenced_buf->base.base.reference.count,
|
||||
p_atomic_read(&fenced_buf->base.base.reference.count),
|
||||
fenced_buf->fence,
|
||||
signaled == 0 ? "y" : "n");
|
||||
curr = next;
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ pb_debug_manager_dump(struct pb_debug_manager *mgr)
|
|||
buf = LIST_ENTRY(struct pb_debug_buffer, curr, head);
|
||||
|
||||
debug_printf("buffer = %p\n", buf);
|
||||
debug_printf(" .size = %p\n", buf->base.base.size);
|
||||
debug_printf(" .size = 0x%x\n", buf->base.base.size);
|
||||
debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
|
||||
|
||||
curr = next;
|
||||
|
|
|
|||
|
|
@ -1445,11 +1445,11 @@ fetch_texel( struct tgsi_sampler **sampler,
|
|||
{
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE];
|
||||
(*sampler)->get_samples(*sampler,
|
||||
&store[0],
|
||||
&store[4],
|
||||
&store[8],
|
||||
0.0f, /*store[12], lodbias */
|
||||
rgba);
|
||||
&store[0], /* s */
|
||||
&store[4], /* t */
|
||||
&store[8], /* r */
|
||||
store[12], /* lodbias */
|
||||
rgba); /* results */
|
||||
|
||||
memcpy( store, rgba, 16 * sizeof(float));
|
||||
}
|
||||
|
|
@ -1855,7 +1855,6 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_RCP:
|
||||
/* TGSI_OPCODE_RECIP */
|
||||
FETCH( func, *inst, 0, 0, CHAN_X );
|
||||
emit_rcp( func, 0, 0 );
|
||||
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
|
|
@ -1864,7 +1863,6 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_RSQ:
|
||||
/* TGSI_OPCODE_RECIPSQRT */
|
||||
FETCH( func, *inst, 0, 0, CHAN_X );
|
||||
emit_abs( func, 0 );
|
||||
emit_rsqrt( func, 1, 0 );
|
||||
|
|
@ -1962,7 +1960,6 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_DP3:
|
||||
/* TGSI_OPCODE_DOT3 */
|
||||
FETCH( func, *inst, 0, 0, CHAN_X );
|
||||
FETCH( func, *inst, 1, 1, CHAN_X );
|
||||
emit_mul( func, 0, 1 );
|
||||
|
|
@ -1980,7 +1977,6 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_DP4:
|
||||
/* TGSI_OPCODE_DOT4 */
|
||||
FETCH( func, *inst, 0, 0, CHAN_X );
|
||||
FETCH( func, *inst, 1, 1, CHAN_X );
|
||||
emit_mul( func, 0, 1 );
|
||||
|
|
@ -2051,17 +2047,14 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_SLT:
|
||||
/* TGSI_OPCODE_SETLT */
|
||||
emit_setcc( func, inst, cc_LessThan );
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_SGE:
|
||||
/* TGSI_OPCODE_SETGE */
|
||||
emit_setcc( func, inst, cc_NotLessThan );
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_MAD:
|
||||
/* TGSI_OPCODE_MADD */
|
||||
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
FETCH( func, *inst, 0, 0, chan_index );
|
||||
FETCH( func, *inst, 1, 1, chan_index );
|
||||
|
|
@ -2291,7 +2284,7 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_SEQ:
|
||||
return 0;
|
||||
emit_setcc( func, inst, cc_Equal );
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_SFL:
|
||||
|
|
@ -2299,7 +2292,7 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_SGT:
|
||||
return 0;
|
||||
emit_setcc( func, inst, cc_NotLessThanEqual );
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_SIN:
|
||||
|
|
@ -2311,11 +2304,11 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_SLE:
|
||||
return 0;
|
||||
emit_setcc( func, inst, cc_LessThanEqual );
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_SNE:
|
||||
return 0;
|
||||
emit_setcc( func, inst, cc_NotEqual );
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_STR:
|
||||
|
|
@ -2379,7 +2372,6 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_SSG:
|
||||
/* TGSI_OPCODE_SGN */
|
||||
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
FETCH( func, *inst, 0, 0, chan_index );
|
||||
emit_sgn( func, 0, 0 );
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ C_SOURCES = \
|
|||
u_debug_stack.c \
|
||||
u_blit.c \
|
||||
u_cache.c \
|
||||
u_cpu_detect.c \
|
||||
u_draw_quad.c \
|
||||
u_format.c \
|
||||
u_format_access.c \
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ util = env.ConvenienceLibrary(
|
|||
'u_bitmask.c',
|
||||
'u_blit.c',
|
||||
'u_cache.c',
|
||||
'u_cpu_detect.c',
|
||||
'u_debug.c',
|
||||
'u_debug_dump.c',
|
||||
'u_debug_memory.c',
|
||||
|
|
|
|||
|
|
@ -24,23 +24,21 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Based on the work of Eric Anholt <anholt@FreeBSD.org>
|
||||
/**
|
||||
* @file
|
||||
* CPU feature detection.
|
||||
*
|
||||
* @author Dennis Smit
|
||||
* @author Based on the work of Eric Anholt <anholt@FreeBSD.org>
|
||||
*/
|
||||
|
||||
/* FIXME: clean this entire file up */
|
||||
#include "pipe/p_config.h"
|
||||
|
||||
#include "u_debug.h"
|
||||
#include "u_cpu_detect.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define OS_LINUX
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
#define OS_WIN32
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_POWERPC)
|
||||
#if defined(OS_DARWIN)
|
||||
#if defined(PIPE_ARCH_PPC)
|
||||
#if defined(PIPE_OS_DARWIN)
|
||||
#include <sys/sysctl.h>
|
||||
#else
|
||||
#include <signal.h>
|
||||
|
|
@ -48,137 +46,140 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(OS_NETBSD) || defined(OS_OPENBSD)
|
||||
#if defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_FREEBSD)
|
||||
#if defined(PIPE_OS_FREEBSD)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#if defined(PIPE_OS_LINUX)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN32)
|
||||
#ifdef PIPE_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(PIPE_OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static struct cpu_detect_caps __cpu_detect_caps;
|
||||
static int __cpu_detect_initialized = 0;
|
||||
struct util_cpu_caps util_cpu_caps;
|
||||
|
||||
static int has_cpuid(void);
|
||||
static int cpuid(unsigned int ax, unsigned int *p);
|
||||
|
||||
#if defined(PIPE_ARCH_X86)
|
||||
|
||||
/* The sigill handlers */
|
||||
#if defined(ARCH_X86) /* x86 (linux katmai handler check thing) */
|
||||
#if defined(OS_LINUX) && defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)
|
||||
static void sigill_handler_sse(int signal, struct sigcontext sc)
|
||||
#if defined(PIPE_OS_LINUX) //&& defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)
|
||||
static void
|
||||
sigill_handler_sse(int signal, struct sigcontext sc)
|
||||
{
|
||||
/* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1"
|
||||
* instructions are 3 bytes long. We must increment the instruction
|
||||
* pointer manually to avoid repeated execution of the offending
|
||||
* instruction.
|
||||
*
|
||||
* If the SIGILL is caused by a divide-by-zero when unmasked
|
||||
* exceptions aren't supported, the SIMD FPU status and control
|
||||
* word will be restored at the end of the test, so we don't need
|
||||
* to worry about doing it here. Besides, we may not be able to...
|
||||
*/
|
||||
sc.eip += 3;
|
||||
/* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1"
|
||||
* instructions are 3 bytes long. We must increment the instruction
|
||||
* pointer manually to avoid repeated execution of the offending
|
||||
* instruction.
|
||||
*
|
||||
* If the SIGILL is caused by a divide-by-zero when unmasked
|
||||
* exceptions aren't supported, the SIMD FPU status and control
|
||||
* word will be restored at the end of the test, so we don't need
|
||||
* to worry about doing it here. Besides, we may not be able to...
|
||||
*/
|
||||
sc.eip += 3;
|
||||
|
||||
__cpu_detect_caps.hasSSE=0;
|
||||
util_cpu_caps.has_sse=0;
|
||||
}
|
||||
|
||||
static void sigfpe_handler_sse(int signal, struct sigcontext sc)
|
||||
static void
|
||||
sigfpe_handler_sse(int signal, struct sigcontext sc)
|
||||
{
|
||||
if (sc.fpstate->magic != 0xffff) {
|
||||
/* Our signal context has the extended FPU state, so reset the
|
||||
* divide-by-zero exception mask and clear the divide-by-zero
|
||||
* exception bit.
|
||||
*/
|
||||
sc.fpstate->mxcsr |= 0x00000200;
|
||||
sc.fpstate->mxcsr &= 0xfffffffb;
|
||||
} else {
|
||||
/* If we ever get here, we're completely hosed.
|
||||
*/
|
||||
}
|
||||
if (sc.fpstate->magic != 0xffff) {
|
||||
/* Our signal context has the extended FPU state, so reset the
|
||||
* divide-by-zero exception mask and clear the divide-by-zero
|
||||
* exception bit.
|
||||
*/
|
||||
sc.fpstate->mxcsr |= 0x00000200;
|
||||
sc.fpstate->mxcsr &= 0xfffffffb;
|
||||
} else {
|
||||
/* If we ever get here, we're completely hosed.
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* OS_LINUX && _POSIX_SOURCE && X86_FXSR_MAGIC */
|
||||
#endif /* PIPE_OS_LINUX && _POSIX_SOURCE && X86_FXSR_MAGIC */
|
||||
|
||||
#if defined(OS_WIN32)
|
||||
LONG CALLBACK win32_sig_handler_sse(EXCEPTION_POINTERS* ep)
|
||||
#if defined(PIPE_OS_WINDOWS)
|
||||
static LONG CALLBACK
|
||||
win32_sig_handler_sse(EXCEPTION_POINTERS* ep)
|
||||
{
|
||||
if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||
ep->ContextRecord->Eip +=3;
|
||||
__cpu_detect_caps.hasSSE=0;
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||
ep->ContextRecord->Eip +=3;
|
||||
util_cpu_caps.has_sse=0;
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif /* OS_WIN32 */
|
||||
#endif /* PIPE_OS_WINDOWS */
|
||||
|
||||
#endif /* PIPE_ARCH_X86 */
|
||||
|
||||
|
||||
#if defined(ARCH_POWERPC) && !defined(OS_DARWIN)
|
||||
#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_DARWIN)
|
||||
static sigjmp_buf __lv_powerpc_jmpbuf;
|
||||
static volatile sig_atomic_t __lv_powerpc_canjump = 0;
|
||||
|
||||
static void sigill_handler (int sig);
|
||||
|
||||
static void sigill_handler (int sig)
|
||||
static void
|
||||
sigill_handler(int sig)
|
||||
{
|
||||
if (!__lv_powerpc_canjump) {
|
||||
signal (sig, SIG_DFL);
|
||||
raise (sig);
|
||||
}
|
||||
if (!__lv_powerpc_canjump) {
|
||||
signal (sig, SIG_DFL);
|
||||
raise (sig);
|
||||
}
|
||||
|
||||
__lv_powerpc_canjump = 0;
|
||||
siglongjmp(__lv_powerpc_jmpbuf, 1);
|
||||
__lv_powerpc_canjump = 0;
|
||||
siglongjmp(__lv_powerpc_jmpbuf, 1);
|
||||
}
|
||||
|
||||
static void check_os_altivec_support(void)
|
||||
static void
|
||||
check_os_altivec_support(void)
|
||||
{
|
||||
#if defined(OS_DARWIN)
|
||||
int sels[2] = {CTL_HW, HW_VECTORUNIT};
|
||||
int has_vu = 0;
|
||||
int len = sizeof (has_vu);
|
||||
int err;
|
||||
#if defined(PIPE_OS_DARWIN)
|
||||
int sels[2] = {CTL_HW, HW_VECTORUNIT};
|
||||
int has_vu = 0;
|
||||
int len = sizeof (has_vu);
|
||||
int err;
|
||||
|
||||
err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
|
||||
err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
|
||||
|
||||
if (err == 0) {
|
||||
if (has_vu != 0) {
|
||||
__cpu_detect_caps.hasAltiVec = 1;
|
||||
}
|
||||
}
|
||||
#else /* !OS_DARWIN */
|
||||
/* no Darwin, do it the brute-force way */
|
||||
/* this is borrowed from the libmpeg2 library */
|
||||
signal(SIGILL, sigill_handler);
|
||||
if (sigsetjmp(__lv_powerpc_jmpbuf, 1)) {
|
||||
signal(SIGILL, SIG_DFL);
|
||||
} else {
|
||||
__lv_powerpc_canjump = 1;
|
||||
if (err == 0) {
|
||||
if (has_vu != 0) {
|
||||
util_cpu_caps.has_altivec = 1;
|
||||
}
|
||||
}
|
||||
#else /* !PIPE_OS_DARWIN */
|
||||
/* no Darwin, do it the brute-force way */
|
||||
/* this is borrowed from the libmpeg2 library */
|
||||
signal(SIGILL, sigill_handler);
|
||||
if (sigsetjmp(__lv_powerpc_jmpbuf, 1)) {
|
||||
signal(SIGILL, SIG_DFL);
|
||||
} else {
|
||||
__lv_powerpc_canjump = 1;
|
||||
|
||||
__asm __volatile
|
||||
("mtspr 256, %0\n\t"
|
||||
"vand %%v0, %%v0, %%v0"
|
||||
:
|
||||
: "r" (-1));
|
||||
__asm __volatile
|
||||
("mtspr 256, %0\n\t"
|
||||
"vand %%v0, %%v0, %%v0"
|
||||
:
|
||||
: "r" (-1));
|
||||
|
||||
signal(SIGILL, SIG_DFL);
|
||||
__cpu_detect_caps.hasAltiVec = 1;
|
||||
}
|
||||
signal(SIGILL, SIG_DFL);
|
||||
util_cpu_caps.has_altivec = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -189,318 +190,312 @@ static void check_os_altivec_support(void)
|
|||
* and RedHat patched 2.2 kernels that have broken exception handling
|
||||
* support for user space apps that do SSE.
|
||||
*/
|
||||
static void check_os_katmai_support(void)
|
||||
static void
|
||||
check_os_katmai_support(void)
|
||||
{
|
||||
#if defined(ARCH_X86)
|
||||
#if defined(OS_FREEBSD)
|
||||
int has_sse=0, ret;
|
||||
int len = sizeof (has_sse);
|
||||
#if defined(PIPE_ARCH_X86)
|
||||
#if defined(PIPE_OS_FREEBSD)
|
||||
int has_sse=0, ret;
|
||||
int len = sizeof (has_sse);
|
||||
|
||||
ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0);
|
||||
if (ret || !has_sse)
|
||||
__cpu_detect_caps.hasSSE=0;
|
||||
ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0);
|
||||
if (ret || !has_sse)
|
||||
util_cpu_caps.has_sse=0;
|
||||
|
||||
#elif defined(OS_NETBSD) || defined(OS_OPENBSD)
|
||||
int has_sse, has_sse2, ret, mib[2];
|
||||
int varlen;
|
||||
#elif defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD)
|
||||
int has_sse, has_sse2, ret, mib[2];
|
||||
int varlen;
|
||||
|
||||
mib[0] = CTL_MACHDEP;
|
||||
mib[1] = CPU_SSE;
|
||||
varlen = sizeof (has_sse);
|
||||
mib[0] = CTL_MACHDEP;
|
||||
mib[1] = CPU_SSE;
|
||||
varlen = sizeof (has_sse);
|
||||
|
||||
ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0);
|
||||
if (ret < 0 || !has_sse) {
|
||||
__cpu_detect_caps.hasSSE = 0;
|
||||
} else {
|
||||
__cpu_detect_caps.hasSSE = 1;
|
||||
}
|
||||
ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0);
|
||||
if (ret < 0 || !has_sse) {
|
||||
util_cpu_caps.has_sse = 0;
|
||||
} else {
|
||||
util_cpu_caps.has_sse = 1;
|
||||
}
|
||||
|
||||
mib[1] = CPU_SSE2;
|
||||
varlen = sizeof (has_sse2);
|
||||
ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0);
|
||||
if (ret < 0 || !has_sse2) {
|
||||
__cpu_detect_caps.hasSSE2 = 0;
|
||||
} else {
|
||||
__cpu_detect_caps.hasSSE2 = 1;
|
||||
}
|
||||
__cpu_detect_caps.hasSSE = 0; /* FIXME ?!?!? */
|
||||
mib[1] = CPU_SSE2;
|
||||
varlen = sizeof (has_sse2);
|
||||
ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0);
|
||||
if (ret < 0 || !has_sse2) {
|
||||
util_cpu_caps.has_sse2 = 0;
|
||||
} else {
|
||||
util_cpu_caps.has_sse2 = 1;
|
||||
}
|
||||
util_cpu_caps.has_sse = 0; /* FIXME ?!?!? */
|
||||
|
||||
#elif defined(OS_WIN32)
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER exc_fil;
|
||||
if (__cpu_detect_caps.hasSSE) {
|
||||
exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse);
|
||||
__asm __volatile ("xorps %xmm0, %xmm0");
|
||||
SetUnhandledExceptionFilter(exc_fil);
|
||||
}
|
||||
#elif defined(OS_LINUX)
|
||||
struct sigaction saved_sigill;
|
||||
struct sigaction saved_sigfpe;
|
||||
#elif defined(PIPE_OS_WINDOWS)
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER exc_fil;
|
||||
if (util_cpu_caps.has_sse) {
|
||||
exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse);
|
||||
#if defined(PIPE_CC_GCC)
|
||||
__asm __volatile ("xorps %xmm0, %xmm0");
|
||||
#elif defined(PIPE_CC_MSVC)
|
||||
__asm {
|
||||
xorps xmm0, xmm0 // executing SSE instruction
|
||||
}
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
SetUnhandledExceptionFilter(exc_fil);
|
||||
}
|
||||
#elif defined(PIPE_OS_LINUX)
|
||||
struct sigaction saved_sigill;
|
||||
struct sigaction saved_sigfpe;
|
||||
|
||||
/* Save the original signal handlers.
|
||||
*/
|
||||
sigaction(SIGILL, NULL, &saved_sigill);
|
||||
sigaction(SIGFPE, NULL, &saved_sigfpe);
|
||||
/* Save the original signal handlers.
|
||||
*/
|
||||
sigaction(SIGILL, NULL, &saved_sigill);
|
||||
sigaction(SIGFPE, NULL, &saved_sigfpe);
|
||||
|
||||
signal(SIGILL, (void (*)(int))sigill_handler_sse);
|
||||
signal(SIGFPE, (void (*)(int))sigfpe_handler_sse);
|
||||
signal(SIGILL, (void (*)(int))sigill_handler_sse);
|
||||
signal(SIGFPE, (void (*)(int))sigfpe_handler_sse);
|
||||
|
||||
/* Emulate test for OSFXSR in CR4. The OS will set this bit if it
|
||||
* supports the extended FPU save and restore required for SSE. If
|
||||
* we execute an SSE instruction on a PIII and get a SIGILL, the OS
|
||||
* doesn't support Streaming SIMD Exceptions, even if the processor
|
||||
* does.
|
||||
*/
|
||||
if (__cpu_detect_caps.hasSSE) {
|
||||
__asm __volatile ("xorps %xmm1, %xmm0");
|
||||
}
|
||||
/* Emulate test for OSFXSR in CR4. The OS will set this bit if it
|
||||
* supports the extended FPU save and restore required for SSE. If
|
||||
* we execute an SSE instruction on a PIII and get a SIGILL, the OS
|
||||
* doesn't support Streaming SIMD Exceptions, even if the processor
|
||||
* does.
|
||||
*/
|
||||
if (util_cpu_caps.has_sse) {
|
||||
__asm __volatile ("xorps %xmm1, %xmm0");
|
||||
}
|
||||
|
||||
/* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if
|
||||
* it supports unmasked SIMD FPU exceptions. If we unmask the
|
||||
* exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS
|
||||
* doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE
|
||||
* as expected, we're okay but we need to clean up after it.
|
||||
*
|
||||
* Are we being too stringent in our requirement that the OS support
|
||||
* unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by
|
||||
* setting CR4.OSFXSR but don't support unmasked exceptions. Win98
|
||||
* doesn't even support them. We at least know the user-space SSE
|
||||
* support is good in kernels that do support unmasked exceptions,
|
||||
* and therefore to be safe I'm going to leave this test in here.
|
||||
*/
|
||||
if (__cpu_detect_caps.hasSSE) {
|
||||
// test_os_katmai_exception_support();
|
||||
}
|
||||
/* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if
|
||||
* it supports unmasked SIMD FPU exceptions. If we unmask the
|
||||
* exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS
|
||||
* doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE
|
||||
* as expected, we're okay but we need to clean up after it.
|
||||
*
|
||||
* Are we being too stringent in our requirement that the OS support
|
||||
* unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by
|
||||
* setting CR4.OSFXSR but don't support unmasked exceptions. Win98
|
||||
* doesn't even support them. We at least know the user-space SSE
|
||||
* support is good in kernels that do support unmasked exceptions,
|
||||
* and therefore to be safe I'm going to leave this test in here.
|
||||
*/
|
||||
if (util_cpu_caps.has_sse) {
|
||||
// test_os_katmai_exception_support();
|
||||
}
|
||||
|
||||
/* Restore the original signal handlers.
|
||||
*/
|
||||
sigaction(SIGILL, &saved_sigill, NULL);
|
||||
sigaction(SIGFPE, &saved_sigfpe, NULL);
|
||||
/* Restore the original signal handlers.
|
||||
*/
|
||||
sigaction(SIGILL, &saved_sigill, NULL);
|
||||
sigaction(SIGFPE, &saved_sigfpe, NULL);
|
||||
|
||||
#else
|
||||
/* We can't use POSIX signal handling to test the availability of
|
||||
* SSE, so we disable it by default.
|
||||
*/
|
||||
__cpu_detect_caps.hasSSE = 0;
|
||||
/* We can't use POSIX signal handling to test the availability of
|
||||
* SSE, so we disable it by default.
|
||||
*/
|
||||
util_cpu_caps.has_sse = 0;
|
||||
#endif /* __linux__ */
|
||||
#endif
|
||||
|
||||
#if defined(PIPE_ARCH_X86_64)
|
||||
util_cpu_caps.has_sse = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int has_cpuid(void)
|
||||
{
|
||||
#if defined(ARCH_X86)
|
||||
int a, c;
|
||||
#if defined(PIPE_ARCH_X86)
|
||||
#if defined(PIPE_OS_GCC)
|
||||
int a, c;
|
||||
|
||||
__asm __volatile
|
||||
("pushf\n"
|
||||
"popl %0\n"
|
||||
"movl %0, %1\n"
|
||||
"xorl $0x200000, %0\n"
|
||||
"push %0\n"
|
||||
"popf\n"
|
||||
"pushf\n"
|
||||
"popl %0\n"
|
||||
: "=a" (a), "=c" (c)
|
||||
:
|
||||
: "cc");
|
||||
__asm __volatile
|
||||
("pushf\n"
|
||||
"popl %0\n"
|
||||
"movl %0, %1\n"
|
||||
"xorl $0x200000, %0\n"
|
||||
"push %0\n"
|
||||
"popf\n"
|
||||
"pushf\n"
|
||||
"popl %0\n"
|
||||
: "=a" (a), "=c" (c)
|
||||
:
|
||||
: "cc");
|
||||
|
||||
return a != c;
|
||||
return a != c;
|
||||
#else
|
||||
return 0;
|
||||
/* FIXME */
|
||||
return 1;
|
||||
#endif
|
||||
#elif defined(PIPE_ARCH_X86_64)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int cpuid(unsigned int ax, unsigned int *p)
|
||||
static INLINE int
|
||||
cpuid(unsigned int ax, unsigned int *p)
|
||||
{
|
||||
#if defined(ARCH_X86)
|
||||
unsigned int flags;
|
||||
int ret = -1;
|
||||
|
||||
__asm __volatile
|
||||
("movl %%ebx, %%esi\n\t"
|
||||
"cpuid\n\t"
|
||||
"xchgl %%ebx, %%esi"
|
||||
: "=a" (p[0]), "=S" (p[1]),
|
||||
"=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax));
|
||||
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
|
||||
#if defined(PIPE_CC_GCC)
|
||||
__asm __volatile
|
||||
("movl %%ebx, %%esi\n\t"
|
||||
"cpuid\n\t"
|
||||
"xchgl %%ebx, %%esi"
|
||||
: "=a" (p[0]), "=S" (p[1]),
|
||||
"=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax));
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
ret = 0;
|
||||
#elif defined(PIPE_CC_MSVC)
|
||||
__cpuid(ax, p);
|
||||
|
||||
ret = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cpu_detect_initialize()
|
||||
{
|
||||
unsigned int regs[4];
|
||||
unsigned int regs2[4];
|
||||
|
||||
int mib[2], ncpu;
|
||||
int len;
|
||||
|
||||
memset(&__cpu_detect_caps, 0, sizeof (struct cpu_detect_caps));
|
||||
|
||||
/* Check for arch type */
|
||||
#if defined(ARCH_MIPS)
|
||||
__cpu_detect_caps.type = CPU_DETECT_TYPE_MIPS;
|
||||
#elif defined(ARCH_ALPHA)
|
||||
__cpu_detect_caps.type = CPU_DETECT_TYPE_ALPHA;
|
||||
#elif defined(ARCH_SPARC)
|
||||
__cpu_detect_caps.type = CPU_DETECT_TYPE_SPARC;
|
||||
#elif defined(ARCH_X86)
|
||||
__cpu_detect_caps.type = CPU_DETECT_TYPE_X86;
|
||||
#elif defined(ARCH_POWERPC)
|
||||
__cpu_detect_caps.type = CPU_DETECT_TYPE_POWERPC;
|
||||
#else
|
||||
__cpu_detect_caps.type = CPU_DETECT_TYPE_OTHER;
|
||||
#endif
|
||||
|
||||
/* Count the number of CPUs in system */
|
||||
#if !defined(OS_WIN32) && !defined(OS_UNKNOWN) && defined(_SC_NPROCESSORS_ONLN)
|
||||
__cpu_detect_caps.nrcpu = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (__cpu_detect_caps.nrcpu == -1)
|
||||
__cpu_detect_caps.nrcpu = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(OS_NETBSD) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
|
||||
void
|
||||
util_cpu_detect(void)
|
||||
{
|
||||
static boolean util_cpu_detect_initialized = FALSE;
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_NCPU;
|
||||
if(util_cpu_detect_initialized)
|
||||
return;
|
||||
|
||||
len = sizeof (ncpu);
|
||||
sysctl(mib, 2, &ncpu, &len, NULL, 0);
|
||||
__cpu_detect_caps.nrcpu = ncpu;
|
||||
memset(&util_cpu_caps, 0, sizeof util_cpu_caps);
|
||||
|
||||
/* Check for arch type */
|
||||
#if defined(PIPE_ARCH_MIPS)
|
||||
util_cpu_caps.arch = UTIL_CPU_ARCH_MIPS;
|
||||
#elif defined(PIPE_ARCH_ALPHA)
|
||||
util_cpu_caps.arch = UTIL_CPU_ARCH_ALPHA;
|
||||
#elif defined(PIPE_ARCH_SPARC)
|
||||
util_cpu_caps.arch = UTIL_CPU_ARCH_SPARC;
|
||||
#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
|
||||
util_cpu_caps.arch = UTIL_CPU_ARCH_X86;
|
||||
#elif defined(PIPE_ARCH_PPC)
|
||||
util_cpu_caps.arch = UTIL_CPU_ARCH_POWERPC;
|
||||
#else
|
||||
__cpu_detect_caps.nrcpu = 1;
|
||||
util_cpu_caps.arch = UTIL_CPU_ARCH_UNKNOWN;
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_X86)
|
||||
/* No cpuid, old 486 or lower */
|
||||
if (has_cpuid() == 0)
|
||||
return;
|
||||
/* Count the number of CPUs in system */
|
||||
#if !defined(PIPE_OS_WINDOWS) && !defined(PIPE_OS_UNKNOWN) && defined(_SC_NPROCESSORS_ONLN)
|
||||
util_cpu_caps.nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (util_cpu_caps.nr_cpus == -1)
|
||||
util_cpu_caps.nr_cpus = 1;
|
||||
|
||||
__cpu_detect_caps.cacheline = 32;
|
||||
#elif defined(PIPE_OS_NETBSD) || defined(PIPE_OS_FREEBSD) || defined(PIPE_OS_OPENBSD)
|
||||
{
|
||||
int mib[2], ncpu;
|
||||
int len;
|
||||
|
||||
/* Get max cpuid level */
|
||||
cpuid(0x00000000, regs);
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_NCPU;
|
||||
|
||||
if (regs[0] >= 0x00000001) {
|
||||
unsigned int cacheline;
|
||||
|
||||
cpuid (0x00000001, regs2);
|
||||
|
||||
__cpu_detect_caps.x86cpuType = (regs2[0] >> 8) & 0xf;
|
||||
if (__cpu_detect_caps.x86cpuType == 0xf)
|
||||
__cpu_detect_caps.x86cpuType = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */
|
||||
|
||||
/* general feature flags */
|
||||
__cpu_detect_caps.hasTSC = (regs2[3] & (1 << 8 )) >> 8; /* 0x0000010 */
|
||||
__cpu_detect_caps.hasMMX = (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */
|
||||
__cpu_detect_caps.hasSSE = (regs2[3] & (1 << 25 )) >> 25; /* 0x2000000 */
|
||||
__cpu_detect_caps.hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; /* 0x4000000 */
|
||||
__cpu_detect_caps.hasSSE3 = (regs2[2] & (1)); /* 0x0000001 */
|
||||
__cpu_detect_caps.hasSSSE3 = (regs2[2] & (1 << 9 )) >> 9; /* 0x0000020 */
|
||||
__cpu_detect_caps.hasMMX2 = __cpu_detect_caps.hasSSE; /* SSE cpus supports mmxext too */
|
||||
|
||||
cacheline = ((regs2[1] >> 8) & 0xFF) * 8;
|
||||
if (cacheline > 0)
|
||||
__cpu_detect_caps.cacheline = cacheline;
|
||||
}
|
||||
|
||||
cpuid(0x80000000, regs);
|
||||
|
||||
if (regs[0] >= 0x80000001) {
|
||||
|
||||
cpuid(0x80000001, regs2);
|
||||
|
||||
__cpu_detect_caps.hasMMX |= (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */
|
||||
__cpu_detect_caps.hasMMX2 |= (regs2[3] & (1 << 22 )) >> 22; /* 0x400000 */
|
||||
__cpu_detect_caps.has3DNow = (regs2[3] & (1 << 31 )) >> 31; /* 0x80000000 */
|
||||
__cpu_detect_caps.has3DNowExt = (regs2[3] & (1 << 30 )) >> 30;
|
||||
}
|
||||
|
||||
if (regs[0] >= 0x80000006) {
|
||||
cpuid(0x80000006, regs2);
|
||||
__cpu_detect_caps.cacheline = regs2[2] & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_CYGWIN) || defined(OS_OPENBSD)
|
||||
if (__cpu_detect_caps.hasSSE)
|
||||
check_os_katmai_support();
|
||||
|
||||
if (!__cpu_detect_caps.hasSSE) {
|
||||
__cpu_detect_caps.hasSSE2 = 0;
|
||||
__cpu_detect_caps.hasSSE3 = 0;
|
||||
__cpu_detect_caps.hasSSSE3 = 0;
|
||||
}
|
||||
len = sizeof (ncpu);
|
||||
sysctl(mib, 2, &ncpu, &len, NULL, 0);
|
||||
util_cpu_caps.nr_cpus = ncpu;
|
||||
}
|
||||
#else
|
||||
__cpu_detect_caps.hasSSE = 0;
|
||||
__cpu_detect_caps.hasSSE2 = 0;
|
||||
__cpu_detect_caps.hasSSE3 = 0;
|
||||
__cpu_detect_caps.hasSSSE3 = 0;
|
||||
util_cpu_caps.nr_cpus = 1;
|
||||
#endif
|
||||
#endif /* ARCH_X86 */
|
||||
|
||||
#if defined(ARCH_POWERPC)
|
||||
check_os_altivec_support();
|
||||
#endif /* ARCH_POWERPC */
|
||||
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
|
||||
if (has_cpuid()) {
|
||||
unsigned int regs[4];
|
||||
unsigned int regs2[4];
|
||||
|
||||
__cpu_detect_initialized = 1;
|
||||
util_cpu_caps.cacheline = 32;
|
||||
|
||||
/* Get max cpuid level */
|
||||
cpuid(0x00000000, regs);
|
||||
|
||||
if (regs[0] >= 0x00000001) {
|
||||
unsigned int cacheline;
|
||||
|
||||
cpuid (0x00000001, regs2);
|
||||
|
||||
util_cpu_caps.x86_cpu_type = (regs2[0] >> 8) & 0xf;
|
||||
if (util_cpu_caps.x86_cpu_type == 0xf)
|
||||
util_cpu_caps.x86_cpu_type = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */
|
||||
|
||||
/* general feature flags */
|
||||
util_cpu_caps.has_tsc = (regs2[3] & (1 << 8 )) >> 8; /* 0x0000010 */
|
||||
util_cpu_caps.has_mmx = (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */
|
||||
util_cpu_caps.has_sse = (regs2[3] & (1 << 25 )) >> 25; /* 0x2000000 */
|
||||
util_cpu_caps.has_sse2 = (regs2[3] & (1 << 26 )) >> 26; /* 0x4000000 */
|
||||
util_cpu_caps.has_sse3 = (regs2[2] & (1)); /* 0x0000001 */
|
||||
util_cpu_caps.has_ssse3 = (regs2[2] & (1 << 9 )) >> 9; /* 0x0000020 */
|
||||
util_cpu_caps.has_sse4_1 = (regs2[2] & (1 << 19)) >> 19;
|
||||
util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */
|
||||
|
||||
cacheline = ((regs2[1] >> 8) & 0xFF) * 8;
|
||||
if (cacheline > 0)
|
||||
util_cpu_caps.cacheline = cacheline;
|
||||
}
|
||||
|
||||
cpuid(0x80000000, regs);
|
||||
|
||||
if (regs[0] >= 0x80000001) {
|
||||
|
||||
cpuid(0x80000001, regs2);
|
||||
|
||||
util_cpu_caps.has_mmx |= (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */
|
||||
util_cpu_caps.has_mmx2 |= (regs2[3] & (1 << 22 )) >> 22; /* 0x400000 */
|
||||
util_cpu_caps.has_3dnow = (regs2[3] & (1 << 31 )) >> 31; /* 0x80000000 */
|
||||
util_cpu_caps.has_3dnow_ext = (regs2[3] & (1 << 30 )) >> 30;
|
||||
}
|
||||
|
||||
if (regs[0] >= 0x80000006) {
|
||||
cpuid(0x80000006, regs2);
|
||||
util_cpu_caps.cacheline = regs2[2] & 0xFF;
|
||||
}
|
||||
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_FREEBSD) || defined(PIPE_OS_NETBSD) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_OPENBSD)
|
||||
if (util_cpu_caps.has_sse)
|
||||
check_os_katmai_support();
|
||||
|
||||
if (!util_cpu_caps.has_sse) {
|
||||
util_cpu_caps.has_sse2 = 0;
|
||||
util_cpu_caps.has_sse3 = 0;
|
||||
util_cpu_caps.has_ssse3 = 0;
|
||||
}
|
||||
#else
|
||||
util_cpu_caps.has_sse = 0;
|
||||
util_cpu_caps.has_sse2 = 0;
|
||||
util_cpu_caps.has_sse3 = 0;
|
||||
util_cpu_caps.has_ssse3 = 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* PIPE_ARCH_X86 || PIPE_ARCH_X86_64 */
|
||||
|
||||
#if defined(PIPE_ARCH_PPC)
|
||||
check_os_altivec_support();
|
||||
#endif /* PIPE_ARCH_PPC */
|
||||
|
||||
#ifdef DEBUG
|
||||
debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch);
|
||||
debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus);
|
||||
|
||||
debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type);
|
||||
debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline);
|
||||
|
||||
debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc);
|
||||
debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx);
|
||||
debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2);
|
||||
debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse);
|
||||
debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2);
|
||||
debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3);
|
||||
debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3);
|
||||
debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1);
|
||||
debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow);
|
||||
debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext);
|
||||
debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec);
|
||||
#endif
|
||||
|
||||
util_cpu_detect_initialized = TRUE;
|
||||
}
|
||||
|
||||
struct cpu_detect_caps *cpu_detect_get_caps()
|
||||
{
|
||||
return &__cpu_detect_caps;
|
||||
}
|
||||
|
||||
/* The getters and setters for feature flags */
|
||||
int cpu_detect_get_tsc()
|
||||
{
|
||||
return __cpu_detect_caps.hasTSC;
|
||||
}
|
||||
|
||||
int cpu_detect_get_mmx()
|
||||
{
|
||||
return __cpu_detect_caps.hasMMX;
|
||||
}
|
||||
|
||||
int cpu_detect_get_mmx2()
|
||||
{
|
||||
return __cpu_detect_caps.hasMMX2;
|
||||
}
|
||||
|
||||
int cpu_detect_get_sse()
|
||||
{
|
||||
return __cpu_detect_caps.hasSSE;
|
||||
}
|
||||
|
||||
int cpu_detect_get_sse2()
|
||||
{
|
||||
return __cpu_detect_caps.hasSSE2;
|
||||
}
|
||||
|
||||
int cpu_detect_get_sse3()
|
||||
{
|
||||
return __cpu_detect_caps.hasSSE3;
|
||||
}
|
||||
|
||||
int cpu_detect_get_ssse3()
|
||||
{
|
||||
return __cpu_detect_caps.hasSSSE3;
|
||||
}
|
||||
|
||||
int cpu_detect_get_3dnow()
|
||||
{
|
||||
return __cpu_detect_caps.has3DNow;
|
||||
}
|
||||
|
||||
int cpu_detect_get_3dnow2()
|
||||
{
|
||||
return __cpu_detect_caps.has3DNowExt;
|
||||
}
|
||||
|
||||
int cpu_detect_get_altivec()
|
||||
{
|
||||
return __cpu_detect_caps.hasAltiVec;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,55 +24,53 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Based on the work of Eric Anholt <anholt@FreeBSD.org>
|
||||
/**
|
||||
* @file
|
||||
* CPU feature detection.
|
||||
*
|
||||
* @author Dennis Smit
|
||||
* @author Based on the work of Eric Anholt <anholt@FreeBSD.org>
|
||||
*/
|
||||
|
||||
#ifndef _CPU_DETECT_H
|
||||
#define _CPU_DETECT_H
|
||||
#ifndef _UTIL_CPU_DETECT_H
|
||||
#define _UTIL_CPU_DETECT_H
|
||||
|
||||
typedef enum {
|
||||
CPU_DETECT_TYPE_MIPS,
|
||||
CPU_DETECT_TYPE_ALPHA,
|
||||
CPU_DETECT_TYPE_SPARC,
|
||||
CPU_DETECT_TYPE_X86,
|
||||
CPU_DETECT_TYPE_POWERPC,
|
||||
CPU_DETECT_TYPE_OTHER
|
||||
} cpu_detect_type;
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct cpu_detect_caps {
|
||||
cpu_detect_type type;
|
||||
int nrcpu;
|
||||
|
||||
/* Feature flags */
|
||||
int x86cpuType;
|
||||
int cacheline;
|
||||
|
||||
int hasTSC;
|
||||
int hasMMX;
|
||||
int hasMMX2;
|
||||
int hasSSE;
|
||||
int hasSSE2;
|
||||
int hasSSE3;
|
||||
int hasSSSE3;
|
||||
int has3DNow;
|
||||
int has3DNowExt;
|
||||
int hasAltiVec;
|
||||
enum util_cpu_arch {
|
||||
UTIL_CPU_ARCH_UNKNOWN = 0,
|
||||
UTIL_CPU_ARCH_MIPS,
|
||||
UTIL_CPU_ARCH_ALPHA,
|
||||
UTIL_CPU_ARCH_SPARC,
|
||||
UTIL_CPU_ARCH_X86,
|
||||
UTIL_CPU_ARCH_POWERPC
|
||||
};
|
||||
|
||||
/* prototypes */
|
||||
void cpu_detect_initialize(void);
|
||||
struct cpu_detect_caps *cpu_detect_get_caps(void);
|
||||
struct util_cpu_caps {
|
||||
enum util_cpu_arch arch;
|
||||
unsigned nr_cpus;
|
||||
|
||||
int cpu_detect_get_tsc(void);
|
||||
int cpu_detect_get_mmx(void);
|
||||
int cpu_detect_get_mmx2(void);
|
||||
int cpu_detect_get_sse(void);
|
||||
int cpu_detect_get_sse2(void);
|
||||
int cpu_detect_get_sse3(void);
|
||||
int cpu_detect_get_ssse3(void);
|
||||
int cpu_detect_get_3dnow(void);
|
||||
int cpu_detect_get_3dnow2(void);
|
||||
int cpu_detect_get_altivec(void);
|
||||
/* Feature flags */
|
||||
int x86_cpu_type;
|
||||
unsigned cacheline;
|
||||
|
||||
#endif /* _CPU_DETECT_H */
|
||||
unsigned has_tsc:1;
|
||||
unsigned has_mmx:1;
|
||||
unsigned has_mmx2:1;
|
||||
unsigned has_sse:1;
|
||||
unsigned has_sse2:1;
|
||||
unsigned has_sse3:1;
|
||||
unsigned has_ssse3:1;
|
||||
unsigned has_sse4_1:1;
|
||||
unsigned has_3dnow:1;
|
||||
unsigned has_3dnow_ext:1;
|
||||
unsigned has_altivec:1;
|
||||
};
|
||||
|
||||
extern struct util_cpu_caps
|
||||
util_cpu_caps;
|
||||
|
||||
void util_cpu_detect(void);
|
||||
|
||||
|
||||
#endif /* _UTIL_CPU_DETECT_H */
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ extern "C" {
|
|||
#define __FUNCTION__ "???"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list)))
|
||||
#else
|
||||
#define _util_printf_format(fmt, list)
|
||||
#endif
|
||||
|
||||
void _debug_vprintf(const char *format, va_list ap);
|
||||
|
||||
|
|
@ -82,13 +87,16 @@ _debug_printf(const char *format, ...)
|
|||
/**
|
||||
* Print debug messages.
|
||||
*
|
||||
* The actual channel used to output debug message is platform specific. To
|
||||
* avoid misformating or truncation, follow these rules of thumb:
|
||||
* The actual channel used to output debug message is platform specific. To
|
||||
* avoid misformating or truncation, follow these rules of thumb:
|
||||
* - output whole lines
|
||||
* - avoid outputing large strings (512 bytes is the current maximum length
|
||||
* - avoid outputing large strings (512 bytes is the current maximum length
|
||||
* that is guaranteed to be printed in all platforms)
|
||||
*/
|
||||
#if !defined(PIPE_OS_HAIKU)
|
||||
static INLINE void
|
||||
debug_printf(const char *format, ...) _util_printf_format(1,2);
|
||||
|
||||
static INLINE void
|
||||
debug_printf(const char *format, ...)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1515,6 +1515,17 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
|
|||
uint zslice = 0;
|
||||
uint offset;
|
||||
|
||||
/* The texture object should have room for the levels which we're
|
||||
* about to generate.
|
||||
*/
|
||||
assert(lastLevel <= pt->last_level);
|
||||
|
||||
/* If this fails, why are we here? */
|
||||
assert(lastLevel > baseLevel);
|
||||
|
||||
assert(filter == PIPE_TEX_FILTER_LINEAR ||
|
||||
filter == PIPE_TEX_FILTER_NEAREST);
|
||||
|
||||
/* check if we can render in the texture's format */
|
||||
if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
|
||||
|
|
|
|||
|
|
@ -283,6 +283,14 @@ util_fast_pow(float x, float y)
|
|||
return util_fast_exp2(util_fast_log2(x) * y);
|
||||
}
|
||||
|
||||
/* Note that this counts zero as a power of two.
|
||||
*/
|
||||
static INLINE boolean
|
||||
util_is_power_of_two( unsigned v )
|
||||
{
|
||||
return (v & (v-1)) == 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Floor(x), returned as int.
|
||||
|
|
@ -462,6 +470,26 @@ util_logbase2(unsigned n)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the smallest power of two >= x
|
||||
*/
|
||||
static INLINE unsigned
|
||||
util_next_power_of_two(unsigned x)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (x == 0)
|
||||
return 1;
|
||||
|
||||
--x;
|
||||
|
||||
for (i = 1; i < sizeof(unsigned) * 8; i <<= 1)
|
||||
x |= x >> i;
|
||||
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamp X to [MIN, MAX].
|
||||
* This is a macro to allow float, int, uint, etc. types.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
|
||||
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <unistd.h>
|
||||
|
|
@ -54,7 +54,7 @@ u_socket_close(int s)
|
|||
if (s < 0)
|
||||
return;
|
||||
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
|
||||
shutdown(s, SHUT_RDWR);
|
||||
close(s);
|
||||
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
||||
|
|
@ -169,7 +169,7 @@ u_socket_listen_on_port(uint16_t portnum)
|
|||
void
|
||||
u_socket_block(int s, boolean block)
|
||||
{
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
|
||||
int old = fcntl(s, F_GETFL, 0);
|
||||
if (old == -1)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
||||
# define PIPE_HAVE_SOCKETS
|
||||
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
|
||||
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
|
||||
# define PIPE_HAVE_SOCKETS
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1452,7 +1452,7 @@ pipe_put_tile_z(struct pipe_transfer *pt,
|
|||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
{
|
||||
uint *pDest = (uint *) (map + y * pt->stride + x*4);
|
||||
assert(pt->usage == PIPE_TRANSFER_READ_WRITE);
|
||||
assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
/* convert 32-bit Z to 24-bit Z, preserve stencil */
|
||||
|
|
@ -1479,7 +1479,7 @@ pipe_put_tile_z(struct pipe_transfer *pt,
|
|||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
{
|
||||
uint *pDest = (uint *) (map + y * pt->stride + x*4);
|
||||
assert(pt->usage == PIPE_TRANSFER_READ_WRITE);
|
||||
assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
/* convert 32-bit Z to 24-bit Z, preserve stencil */
|
||||
|
|
|
|||
13
src/gallium/auxiliary/vl/Makefile
Normal file
13
src/gallium/auxiliary/vl/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = vl
|
||||
|
||||
C_SOURCES = \
|
||||
vl_bitstream_parser.c \
|
||||
vl_mpeg12_mc_renderer.c \
|
||||
vl_compositor.c \
|
||||
vl_csc.c \
|
||||
vl_shader_build.c
|
||||
|
||||
include ../../Makefile.template
|
||||
13
src/gallium/auxiliary/vl/SConscript
Normal file
13
src/gallium/auxiliary/vl/SConscript
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Import('*')
|
||||
|
||||
vl = env.ConvenienceLibrary(
|
||||
target = 'vl',
|
||||
source = [
|
||||
'vl_bitstream_parser.c',
|
||||
'vl_mpeg12_mc_renderer.c',
|
||||
'vl_compositor.c',
|
||||
'vl_csc.c',
|
||||
'vl_shader_build.c',
|
||||
])
|
||||
|
||||
auxiliaries.insert(0, vl)
|
||||
167
src/gallium/auxiliary/vl/vl_bitstream_parser.c
Normal file
167
src/gallium/auxiliary/vl/vl_bitstream_parser.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "vl_bitstream_parser.h"
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <util/u_memory.h>
|
||||
|
||||
static unsigned
|
||||
grab_bits(unsigned cursor, unsigned how_many_bits, unsigned bitstream_elt)
|
||||
{
|
||||
unsigned excess_bits = sizeof(unsigned) * CHAR_BIT - how_many_bits - cursor;
|
||||
|
||||
assert(cursor < sizeof(unsigned) * CHAR_BIT);
|
||||
assert(how_many_bits > 0 && how_many_bits <= sizeof(unsigned) * CHAR_BIT);
|
||||
assert(cursor + how_many_bits <= sizeof(unsigned) * CHAR_BIT);
|
||||
|
||||
return (bitstream_elt << excess_bits) >> (excess_bits + cursor);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
show_bits(unsigned cursor, unsigned how_many_bits, const unsigned *bitstream)
|
||||
{
|
||||
unsigned cur_int = cursor / (sizeof(unsigned) * CHAR_BIT);
|
||||
unsigned cur_bit = cursor % (sizeof(unsigned) * CHAR_BIT);
|
||||
|
||||
assert(bitstream);
|
||||
|
||||
if (cur_bit + how_many_bits > sizeof(unsigned) * CHAR_BIT) {
|
||||
unsigned lower = grab_bits(cur_bit, sizeof(unsigned) * CHAR_BIT - cur_bit,
|
||||
bitstream[cur_int]);
|
||||
unsigned upper = grab_bits(0, cur_bit + how_many_bits - sizeof(unsigned) * CHAR_BIT,
|
||||
bitstream[cur_int + 1]);
|
||||
return lower | upper << (sizeof(unsigned) * CHAR_BIT - cur_bit);
|
||||
}
|
||||
else
|
||||
return grab_bits(cur_bit, how_many_bits, bitstream[cur_int]);
|
||||
}
|
||||
|
||||
bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser,
|
||||
unsigned num_bitstreams,
|
||||
const void **bitstreams,
|
||||
const unsigned *sizes)
|
||||
{
|
||||
assert(parser);
|
||||
assert(num_bitstreams);
|
||||
assert(bitstreams);
|
||||
assert(sizes);
|
||||
|
||||
parser->num_bitstreams = num_bitstreams;
|
||||
parser->bitstreams = (const unsigned**)bitstreams;
|
||||
parser->sizes = sizes;
|
||||
parser->cur_bitstream = 0;
|
||||
parser->cursor = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser)
|
||||
{
|
||||
assert(parser);
|
||||
}
|
||||
|
||||
unsigned
|
||||
vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits)
|
||||
{
|
||||
unsigned bits;
|
||||
|
||||
assert(parser);
|
||||
|
||||
bits = vl_bitstream_parser_show_bits(parser, how_many_bits);
|
||||
|
||||
vl_bitstream_parser_forward(parser, how_many_bits);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
unsigned
|
||||
vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits)
|
||||
{
|
||||
unsigned bits = 0;
|
||||
unsigned shift = 0;
|
||||
unsigned cursor;
|
||||
unsigned cur_bitstream;
|
||||
|
||||
assert(parser);
|
||||
|
||||
cursor = parser->cursor;
|
||||
cur_bitstream = parser->cur_bitstream;
|
||||
|
||||
while (1) {
|
||||
unsigned bits_left = parser->sizes[cur_bitstream] * CHAR_BIT - cursor;
|
||||
unsigned bits_to_show = how_many_bits > bits_left ? bits_left : how_many_bits;
|
||||
|
||||
bits |= show_bits(cursor, bits_to_show,
|
||||
parser->bitstreams[cur_bitstream]) << shift;
|
||||
|
||||
if (how_many_bits > bits_to_show) {
|
||||
how_many_bits -= bits_to_show;
|
||||
cursor = 0;
|
||||
++cur_bitstream;
|
||||
shift += bits_to_show;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits)
|
||||
{
|
||||
assert(parser);
|
||||
assert(how_many_bits);
|
||||
|
||||
parser->cursor += how_many_bits;
|
||||
|
||||
while (parser->cursor > parser->sizes[parser->cur_bitstream] * CHAR_BIT) {
|
||||
parser->cursor -= parser->sizes[parser->cur_bitstream++] * CHAR_BIT;
|
||||
assert(parser->cur_bitstream < parser->num_bitstreams);
|
||||
}
|
||||
}
|
||||
|
||||
void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits)
|
||||
{
|
||||
signed c;
|
||||
|
||||
assert(parser);
|
||||
assert(how_many_bits);
|
||||
|
||||
c = parser->cursor - how_many_bits;
|
||||
|
||||
while (c < 0) {
|
||||
c += parser->sizes[parser->cur_bitstream--] * CHAR_BIT;
|
||||
assert(parser->cur_bitstream < parser->num_bitstreams);
|
||||
}
|
||||
|
||||
parser->cursor = (unsigned)c;
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* 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
|
||||
|
|
@ -10,11 +10,11 @@
|
|||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
|
|
@ -22,52 +22,42 @@
|
|||
* 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 STW_PUBLIC_H
|
||||
#define STW_PUBLIC_H
|
||||
#ifndef vl_bitstream_parser_h
|
||||
#define vl_bitstream_parser_h
|
||||
|
||||
#include <windows.h>
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
BOOL stw_copy_context( UINT_PTR hglrcSrc,
|
||||
UINT_PTR hglrcDst,
|
||||
UINT mask );
|
||||
struct vl_bitstream_parser
|
||||
{
|
||||
unsigned num_bitstreams;
|
||||
const unsigned **bitstreams;
|
||||
const unsigned *sizes;
|
||||
unsigned cur_bitstream;
|
||||
unsigned cursor;
|
||||
};
|
||||
|
||||
UINT_PTR stw_create_layer_context( HDC hdc,
|
||||
int iLayerPlane );
|
||||
bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser,
|
||||
unsigned num_bitstreams,
|
||||
const void **bitstreams,
|
||||
const unsigned *sizes);
|
||||
|
||||
BOOL stw_share_lists( UINT_PTR hglrc1, UINT_PTR hglrc2 );
|
||||
void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser);
|
||||
|
||||
BOOL stw_delete_context( UINT_PTR hglrc );
|
||||
unsigned
|
||||
vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits);
|
||||
|
||||
BOOL
|
||||
stw_release_context( UINT_PTR dhglrc );
|
||||
unsigned
|
||||
vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits);
|
||||
|
||||
UINT_PTR stw_get_current_context( void );
|
||||
void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits);
|
||||
|
||||
HDC stw_get_current_dc( void );
|
||||
void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser,
|
||||
unsigned how_many_bits);
|
||||
|
||||
BOOL stw_make_current( HDC hdc, UINT_PTR hglrc );
|
||||
|
||||
BOOL stw_swap_buffers( HDC hdc );
|
||||
|
||||
BOOL
|
||||
stw_swap_layer_buffers( HDC hdc, UINT fuPlanes );
|
||||
|
||||
PROC stw_get_proc_address( LPCSTR lpszProc );
|
||||
|
||||
int stw_pixelformat_describe( HDC hdc,
|
||||
int iPixelFormat,
|
||||
UINT nBytes,
|
||||
LPPIXELFORMATDESCRIPTOR ppfd );
|
||||
|
||||
int stw_pixelformat_get( HDC hdc );
|
||||
|
||||
BOOL stw_pixelformat_set( HDC hdc,
|
||||
int iPixelFormat );
|
||||
|
||||
int stw_pixelformat_choose( HDC hdc,
|
||||
CONST PIXELFORMATDESCRIPTOR *ppfd );
|
||||
|
||||
#endif
|
||||
#endif /* vl_bitstream_parser_h */
|
||||
532
src/gallium/auxiliary/vl/vl_compositor.c
Normal file
532
src/gallium/auxiliary/vl/vl_compositor.c
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "vl_compositor.h"
|
||||
#include <assert.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <tgsi/tgsi_parse.h>
|
||||
#include <tgsi/tgsi_build.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "vl_csc.h"
|
||||
#include "vl_shader_build.h"
|
||||
|
||||
struct vertex2f
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
|
||||
struct vertex4f
|
||||
{
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
struct vertex_shader_consts
|
||||
{
|
||||
struct vertex4f dst_scale;
|
||||
struct vertex4f dst_trans;
|
||||
struct vertex4f src_scale;
|
||||
struct vertex4f src_trans;
|
||||
};
|
||||
|
||||
struct fragment_shader_consts
|
||||
{
|
||||
float matrix[16];
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents 2 triangles in a strip in normalized coords.
|
||||
* Used to render the surface onto the frame buffer.
|
||||
*/
|
||||
static const struct vertex2f surface_verts[4] =
|
||||
{
|
||||
{0.0f, 0.0f},
|
||||
{0.0f, 1.0f},
|
||||
{1.0f, 0.0f},
|
||||
{1.0f, 1.0f}
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above. We can use the position values directly.
|
||||
* TODO: Duplicate these in the shader, no need to create a buffer.
|
||||
*/
|
||||
static const struct vertex2f *surface_texcoords = surface_verts;
|
||||
|
||||
static void
|
||||
create_vert_shader(struct vl_compositor *c)
|
||||
{
|
||||
const unsigned max_tokens = 50;
|
||||
|
||||
struct pipe_shader_state vs;
|
||||
struct tgsi_token *tokens;
|
||||
struct tgsi_header *header;
|
||||
|
||||
struct tgsi_full_declaration decl;
|
||||
struct tgsi_full_instruction inst;
|
||||
|
||||
unsigned ti;
|
||||
|
||||
unsigned i;
|
||||
|
||||
assert(c);
|
||||
|
||||
tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
|
||||
*(struct tgsi_version*)&tokens[0] = tgsi_build_version();
|
||||
header = (struct tgsi_header*)&tokens[1];
|
||||
*header = tgsi_build_header();
|
||||
*(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
|
||||
|
||||
ti = 3;
|
||||
|
||||
/*
|
||||
* decl i0 ; Vertex pos
|
||||
* decl i1 ; Vertex texcoords
|
||||
*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
}
|
||||
|
||||
/*
|
||||
* decl c0 ; Scaling vector to scale vertex pos rect to destination size
|
||||
* decl c1 ; Translation vector to move vertex pos rect into position
|
||||
* decl c2 ; Scaling vector to scale texcoord rect to source size
|
||||
* decl c3 ; Translation vector to move texcoord rect into position
|
||||
*/
|
||||
decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/*
|
||||
* decl o0 ; Vertex pos
|
||||
* decl o1 ; Vertex texcoords
|
||||
*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
}
|
||||
|
||||
/* decl t0, t1 */
|
||||
decl = vl_decl_temps(0, 1);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/*
|
||||
* mad o0, i0, c0, c1 ; Scale and translate unit output rect to destination size and pos
|
||||
* mad o1, i1, c2, c3 ; Scale and translate unit texcoord rect to source size and pos
|
||||
*/
|
||||
for (i = 0; i < 2; ++i) {
|
||||
inst = vl_inst4(TGSI_OPCODE_MAD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1);
|
||||
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
|
||||
}
|
||||
|
||||
/* end */
|
||||
inst = vl_end();
|
||||
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
assert(ti <= max_tokens);
|
||||
|
||||
vs.tokens = tokens;
|
||||
c->vertex_shader = c->pipe->create_vs_state(c->pipe, &vs);
|
||||
FREE(tokens);
|
||||
}
|
||||
|
||||
static void
|
||||
create_frag_shader(struct vl_compositor *c)
|
||||
{
|
||||
const unsigned max_tokens = 50;
|
||||
|
||||
struct pipe_shader_state fs;
|
||||
struct tgsi_token *tokens;
|
||||
struct tgsi_header *header;
|
||||
|
||||
struct tgsi_full_declaration decl;
|
||||
struct tgsi_full_instruction inst;
|
||||
|
||||
unsigned ti;
|
||||
|
||||
unsigned i;
|
||||
|
||||
assert(c);
|
||||
|
||||
tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
|
||||
*(struct tgsi_version*)&tokens[0] = tgsi_build_version();
|
||||
header = (struct tgsi_header*)&tokens[1];
|
||||
*header = tgsi_build_header();
|
||||
*(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
|
||||
|
||||
ti = 3;
|
||||
|
||||
/* decl i0 ; Texcoords for s0 */
|
||||
decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/*
|
||||
* decl c0-c3 ; CSC matrix c0-c3
|
||||
*/
|
||||
decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/* decl o0 ; Fragment color */
|
||||
decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/* decl t0 */
|
||||
decl = vl_decl_temps(0, 0);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/* decl s0 ; Sampler for tex containing picture to display */
|
||||
decl = vl_decl_samplers(0, 0);
|
||||
ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/* tex2d t0, i0, s0 ; Read src pixel */
|
||||
inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0);
|
||||
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
/*
|
||||
* dp4 o0.x, t0, c0 ; Multiply pixel by the color conversion matrix
|
||||
* dp4 o0.y, t0, c1
|
||||
* dp4 o0.z, t0, c2
|
||||
* dp4 o0.w, t0, c3
|
||||
*/
|
||||
for (i = 0; i < 4; ++i) {
|
||||
inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i);
|
||||
inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
|
||||
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
|
||||
}
|
||||
|
||||
/* end */
|
||||
inst = vl_end();
|
||||
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
|
||||
|
||||
assert(ti <= max_tokens);
|
||||
|
||||
fs.tokens = tokens;
|
||||
c->fragment_shader = c->pipe->create_fs_state(c->pipe, &fs);
|
||||
FREE(tokens);
|
||||
}
|
||||
|
||||
static bool
|
||||
init_pipe_state(struct vl_compositor *c)
|
||||
{
|
||||
struct pipe_sampler_state sampler;
|
||||
|
||||
assert(c);
|
||||
|
||||
c->fb_state.nr_cbufs = 1;
|
||||
c->fb_state.zsbuf = NULL;
|
||||
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
|
||||
sampler.compare_func = PIPE_FUNC_ALWAYS;
|
||||
sampler.normalized_coords = 1;
|
||||
/*sampler.prefilter = ;*/
|
||||
/*sampler.lod_bias = ;*/
|
||||
/*sampler.min_lod = ;*/
|
||||
/*sampler.max_lod = ;*/
|
||||
/*sampler.border_color[i] = ;*/
|
||||
/*sampler.max_anisotropy = ;*/
|
||||
c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cleanup_pipe_state(struct vl_compositor *c)
|
||||
{
|
||||
assert(c);
|
||||
|
||||
c->pipe->delete_sampler_state(c->pipe, c->sampler);
|
||||
}
|
||||
|
||||
static bool
|
||||
init_shaders(struct vl_compositor *c)
|
||||
{
|
||||
assert(c);
|
||||
|
||||
create_vert_shader(c);
|
||||
create_frag_shader(c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cleanup_shaders(struct vl_compositor *c)
|
||||
{
|
||||
assert(c);
|
||||
|
||||
c->pipe->delete_vs_state(c->pipe, c->vertex_shader);
|
||||
c->pipe->delete_fs_state(c->pipe, c->fragment_shader);
|
||||
}
|
||||
|
||||
static bool
|
||||
init_buffers(struct vl_compositor *c)
|
||||
{
|
||||
struct fragment_shader_consts fsc;
|
||||
|
||||
assert(c);
|
||||
|
||||
/*
|
||||
* Create our vertex buffer and vertex buffer element
|
||||
* VB contains 4 vertices that render a quad covering the entire window
|
||||
* to display a rendered surface
|
||||
* Quad is rendered as a tri strip
|
||||
*/
|
||||
c->vertex_bufs[0].stride = sizeof(struct vertex2f);
|
||||
c->vertex_bufs[0].max_index = 3;
|
||||
c->vertex_bufs[0].buffer_offset = 0;
|
||||
c->vertex_bufs[0].buffer = pipe_buffer_create
|
||||
(
|
||||
c->pipe->screen,
|
||||
1,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
sizeof(struct vertex2f) * 4
|
||||
);
|
||||
|
||||
memcpy
|
||||
(
|
||||
pipe_buffer_map(c->pipe->screen, c->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
|
||||
surface_verts,
|
||||
sizeof(struct vertex2f) * 4
|
||||
);
|
||||
|
||||
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer);
|
||||
|
||||
c->vertex_elems[0].src_offset = 0;
|
||||
c->vertex_elems[0].vertex_buffer_index = 0;
|
||||
c->vertex_elems[0].nr_components = 2;
|
||||
c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
|
||||
|
||||
/*
|
||||
* Create our texcoord buffer and texcoord buffer element
|
||||
* Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices
|
||||
*/
|
||||
c->vertex_bufs[1].stride = sizeof(struct vertex2f);
|
||||
c->vertex_bufs[1].max_index = 3;
|
||||
c->vertex_bufs[1].buffer_offset = 0;
|
||||
c->vertex_bufs[1].buffer = pipe_buffer_create
|
||||
(
|
||||
c->pipe->screen,
|
||||
1,
|
||||
PIPE_BUFFER_USAGE_VERTEX,
|
||||
sizeof(struct vertex2f) * 4
|
||||
);
|
||||
|
||||
memcpy
|
||||
(
|
||||
pipe_buffer_map(c->pipe->screen, c->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
|
||||
surface_texcoords,
|
||||
sizeof(struct vertex2f) * 4
|
||||
);
|
||||
|
||||
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer);
|
||||
|
||||
c->vertex_elems[1].src_offset = 0;
|
||||
c->vertex_elems[1].vertex_buffer_index = 1;
|
||||
c->vertex_elems[1].nr_components = 2;
|
||||
c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
|
||||
|
||||
/*
|
||||
* Create our vertex shader's constant buffer
|
||||
* Const buffer contains scaling and translation vectors
|
||||
*/
|
||||
c->vs_const_buf.buffer = pipe_buffer_create
|
||||
(
|
||||
c->pipe->screen,
|
||||
1,
|
||||
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
|
||||
sizeof(struct vertex_shader_consts)
|
||||
);
|
||||
|
||||
/*
|
||||
* Create our fragment shader's constant buffer
|
||||
* Const buffer contains the color conversion matrix and bias vectors
|
||||
*/
|
||||
c->fs_const_buf.buffer = pipe_buffer_create
|
||||
(
|
||||
c->pipe->screen,
|
||||
1,
|
||||
PIPE_BUFFER_USAGE_CONSTANT,
|
||||
sizeof(struct fragment_shader_consts)
|
||||
);
|
||||
|
||||
vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix);
|
||||
|
||||
vl_compositor_set_csc_matrix(c, fsc.matrix);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_buffers(struct vl_compositor *c)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
assert(c);
|
||||
|
||||
for (i = 0; i < 2; ++i)
|
||||
pipe_buffer_reference(&c->vertex_bufs[i].buffer, NULL);
|
||||
|
||||
pipe_buffer_reference(&c->vs_const_buf.buffer, NULL);
|
||||
pipe_buffer_reference(&c->fs_const_buf.buffer, NULL);
|
||||
}
|
||||
|
||||
bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe)
|
||||
{
|
||||
assert(compositor);
|
||||
|
||||
memset(compositor, 0, sizeof(struct vl_compositor));
|
||||
|
||||
compositor->pipe = pipe;
|
||||
|
||||
if (!init_pipe_state(compositor))
|
||||
return false;
|
||||
if (!init_shaders(compositor)) {
|
||||
cleanup_pipe_state(compositor);
|
||||
return false;
|
||||
}
|
||||
if (!init_buffers(compositor)) {
|
||||
cleanup_shaders(compositor);
|
||||
cleanup_pipe_state(compositor);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vl_compositor_cleanup(struct vl_compositor *compositor)
|
||||
{
|
||||
assert(compositor);
|
||||
|
||||
cleanup_buffers(compositor);
|
||||
cleanup_shaders(compositor);
|
||||
cleanup_pipe_state(compositor);
|
||||
}
|
||||
|
||||
void vl_compositor_render(struct vl_compositor *compositor,
|
||||
/*struct pipe_texture *backround,
|
||||
struct pipe_video_rect *backround_area,*/
|
||||
struct pipe_texture *src_surface,
|
||||
enum pipe_mpeg12_picture_type picture_type,
|
||||
/*unsigned num_past_surfaces,
|
||||
struct pipe_texture *past_surfaces,
|
||||
unsigned num_future_surfaces,
|
||||
struct pipe_texture *future_surfaces,*/
|
||||
struct pipe_video_rect *src_area,
|
||||
struct pipe_texture *dst_surface,
|
||||
struct pipe_video_rect *dst_area,
|
||||
/*unsigned num_layers,
|
||||
struct pipe_texture *layers,
|
||||
struct pipe_video_rect *layer_src_areas,
|
||||
struct pipe_video_rect *layer_dst_areas*/
|
||||
struct pipe_fence_handle **fence)
|
||||
{
|
||||
struct vertex_shader_consts *vs_consts;
|
||||
|
||||
assert(compositor);
|
||||
assert(src_surface);
|
||||
assert(src_area);
|
||||
assert(dst_surface);
|
||||
assert(dst_area);
|
||||
assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME);
|
||||
|
||||
compositor->fb_state.width = dst_surface->width[0];
|
||||
compositor->fb_state.height = dst_surface->height[0];
|
||||
compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface
|
||||
(
|
||||
compositor->pipe->screen,
|
||||
dst_surface,
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE
|
||||
);
|
||||
|
||||
compositor->viewport.scale[0] = compositor->fb_state.width;
|
||||
compositor->viewport.scale[1] = compositor->fb_state.height;
|
||||
compositor->viewport.scale[2] = 1;
|
||||
compositor->viewport.scale[3] = 1;
|
||||
compositor->viewport.translate[0] = 0;
|
||||
compositor->viewport.translate[1] = 0;
|
||||
compositor->viewport.translate[2] = 0;
|
||||
compositor->viewport.translate[3] = 0;
|
||||
|
||||
compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
|
||||
compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
|
||||
compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler);
|
||||
compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface);
|
||||
compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
|
||||
compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
|
||||
compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
|
||||
compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems);
|
||||
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, &compositor->vs_const_buf);
|
||||
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf);
|
||||
|
||||
vs_consts = pipe_buffer_map
|
||||
(
|
||||
compositor->pipe->screen,
|
||||
compositor->vs_const_buf.buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
|
||||
);
|
||||
|
||||
vs_consts->dst_scale.x = dst_area->w / (float)compositor->fb_state.cbufs[0]->width;
|
||||
vs_consts->dst_scale.y = dst_area->h / (float)compositor->fb_state.cbufs[0]->height;
|
||||
vs_consts->dst_scale.z = 1;
|
||||
vs_consts->dst_scale.w = 1;
|
||||
vs_consts->dst_trans.x = dst_area->x / (float)compositor->fb_state.cbufs[0]->width;
|
||||
vs_consts->dst_trans.y = dst_area->y / (float)compositor->fb_state.cbufs[0]->height;
|
||||
vs_consts->dst_trans.z = 0;
|
||||
vs_consts->dst_trans.w = 0;
|
||||
|
||||
vs_consts->src_scale.x = src_area->w / (float)src_surface->width[0];
|
||||
vs_consts->src_scale.y = src_area->h / (float)src_surface->height[0];
|
||||
vs_consts->src_scale.z = 1;
|
||||
vs_consts->src_scale.w = 1;
|
||||
vs_consts->src_trans.x = src_area->x / (float)src_surface->width[0];
|
||||
vs_consts->src_trans.y = src_area->y / (float)src_surface->height[0];
|
||||
vs_consts->src_trans.z = 0;
|
||||
vs_consts->src_trans.w = 0;
|
||||
|
||||
pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf.buffer);
|
||||
|
||||
compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
|
||||
compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence);
|
||||
|
||||
pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL);
|
||||
}
|
||||
|
||||
void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat)
|
||||
{
|
||||
assert(compositor);
|
||||
|
||||
memcpy
|
||||
(
|
||||
pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
|
||||
mat,
|
||||
sizeof(struct fragment_shader_consts)
|
||||
);
|
||||
|
||||
pipe_buffer_unmap(compositor->pipe->screen, compositor->fs_const_buf.buffer);
|
||||
}
|
||||
76
src/gallium/auxiliary/vl/vl_compositor.h
Normal file
76
src/gallium/auxiliary/vl/vl_compositor.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef vl_compositor_h
|
||||
#define vl_compositor_h
|
||||
|
||||
#include <pipe/p_compiler.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_video_state.h>
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_texture;
|
||||
|
||||
struct vl_compositor
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
|
||||
struct pipe_framebuffer_state fb_state;
|
||||
void *sampler;
|
||||
void *vertex_shader;
|
||||
void *fragment_shader;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_vertex_buffer vertex_bufs[2];
|
||||
struct pipe_vertex_element vertex_elems[2];
|
||||
struct pipe_constant_buffer vs_const_buf, fs_const_buf;
|
||||
};
|
||||
|
||||
bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe);
|
||||
|
||||
void vl_compositor_cleanup(struct vl_compositor *compositor);
|
||||
|
||||
void vl_compositor_render(struct vl_compositor *compositor,
|
||||
/*struct pipe_texture *backround,
|
||||
struct pipe_video_rect *backround_area,*/
|
||||
struct pipe_texture *src_surface,
|
||||
enum pipe_mpeg12_picture_type picture_type,
|
||||
/*unsigned num_past_surfaces,
|
||||
struct pipe_texture *past_surfaces,
|
||||
unsigned num_future_surfaces,
|
||||
struct pipe_texture *future_surfaces,*/
|
||||
struct pipe_video_rect *src_area,
|
||||
struct pipe_texture *dst_surface,
|
||||
struct pipe_video_rect *dst_area,
|
||||
/*unsigned num_layers,
|
||||
struct pipe_texture *layers,
|
||||
struct pipe_video_rect *layer_src_areas,
|
||||
struct pipe_video_rect *layer_dst_areas,*/
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat);
|
||||
|
||||
#endif /* vl_compositor_h */
|
||||
206
src/gallium/auxiliary/vl/vl_csc.c
Normal file
206
src/gallium/auxiliary/vl/vl_csc.c
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "vl_csc.h"
|
||||
#include <util/u_math.h>
|
||||
#include <util/u_debug.h>
|
||||
|
||||
/*
|
||||
* Color space conversion formulas
|
||||
*
|
||||
* To convert YCbCr to RGB,
|
||||
* vec4 ycbcr, rgb
|
||||
* mat44 csc
|
||||
* rgb = csc * ycbcr
|
||||
*
|
||||
* To calculate the color space conversion matrix csc with ProcAmp adjustments,
|
||||
* mat44 csc, cstd, procamp, bias
|
||||
* csc = cstd * (procamp * bias)
|
||||
*
|
||||
* Where cstd is a matrix corresponding to one of the color standards (BT.601, BT.709, etc)
|
||||
* adjusted for the kind of YCbCr -> RGB mapping wanted (1:1, full),
|
||||
* bias is a matrix corresponding to the kind of YCbCr -> RGB mapping wanted (1:1, full)
|
||||
*
|
||||
* To calculate procamp,
|
||||
* mat44 procamp, hue, saturation, brightness, contrast
|
||||
* procamp = brightness * (saturation * (contrast * hue))
|
||||
* Alternatively,
|
||||
* procamp = saturation * (brightness * (contrast * hue))
|
||||
*
|
||||
* contrast
|
||||
* [ c, 0, 0, 0]
|
||||
* [ 0, c, 0, 0]
|
||||
* [ 0, 0, c, 0]
|
||||
* [ 0, 0, 0, 1]
|
||||
*
|
||||
* brightness
|
||||
* [ 1, 0, 0, b]
|
||||
* [ 0, 1, 0, 0]
|
||||
* [ 0, 0, 1, 0]
|
||||
* [ 0, 0, 0, 1]
|
||||
*
|
||||
* saturation
|
||||
* [ 1, 0, 0, 0]
|
||||
* [ 0, s, 0, 0]
|
||||
* [ 0, 0, s, 0]
|
||||
* [ 0, 0, 0, 1]
|
||||
*
|
||||
* hue
|
||||
* [ 1, 0, 0, 0]
|
||||
* [ 0, cos(h), sin(h), 0]
|
||||
* [ 0, -sin(h), cos(h), 0]
|
||||
* [ 0, 0, 0, 1]
|
||||
*
|
||||
* procamp
|
||||
* [ c, 0, 0, b]
|
||||
* [ 0, c*s*cos(h), c*s*sin(h), 0]
|
||||
* [ 0, -c*s*sin(h), c*s*cos(h), 0]
|
||||
* [ 0, 0, 0, 1]
|
||||
*
|
||||
* bias
|
||||
* [ 1, 0, 0, ybias]
|
||||
* [ 0, 1, 0, cbbias]
|
||||
* [ 0, 0, 1, crbias]
|
||||
* [ 0, 0, 0, 1]
|
||||
*
|
||||
* csc
|
||||
* [ c*cstd[ 0], c*cstd[ 1]*s*cos(h) - c*cstd[ 2]*s*sin(h), c*cstd[ 2]*s*cos(h) + c*cstd[ 1]*s*sin(h), cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 2]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
|
||||
* [ c*cstd[ 4], c*cstd[ 5]*s*cos(h) - c*cstd[ 6]*s*sin(h), c*cstd[ 6]*s*cos(h) + c*cstd[ 5]*s*sin(h), cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 6]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
|
||||
* [ c*cstd[ 8], c*cstd[ 9]*s*cos(h) - c*cstd[10]*s*sin(h), c*cstd[10]*s*cos(h) + c*cstd[ 9]*s*sin(h), cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[10]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
|
||||
* [ c*cstd[12], c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h), c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h), cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
|
||||
*/
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [16,235]
|
||||
*/
|
||||
static const float bt_601[16] =
|
||||
{
|
||||
1.0f, 0.0f, 1.371f, 0.0f,
|
||||
1.0f, -0.336f, -0.698f, 0.0f,
|
||||
1.0f, 1.732f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [0,255]
|
||||
*/
|
||||
static const float bt_601_full[16] =
|
||||
{
|
||||
1.164f, 0.0f, 1.596f, 0.0f,
|
||||
1.164f, -0.391f, -0.813f, 0.0f,
|
||||
1.164f, 2.018f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [16,235]
|
||||
*/
|
||||
static const float bt_709[16] =
|
||||
{
|
||||
1.0f, 0.0f, 1.540f, 0.0f,
|
||||
1.0f, -0.183f, -0.459f, 0.0f,
|
||||
1.0f, 1.816f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [0,255]
|
||||
*/
|
||||
static const float bt_709_full[16] =
|
||||
{
|
||||
1.164f, 0.0f, 1.793f, 0.0f,
|
||||
1.164f, -0.213f, -0.534f, 0.0f,
|
||||
1.164f, 2.115f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
static const float identity[16] =
|
||||
{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs,
|
||||
struct vl_procamp *procamp,
|
||||
bool full_range,
|
||||
float *matrix)
|
||||
{
|
||||
float ybias = full_range ? -16.0f/255.0f : 0.0f;
|
||||
float cbbias = -128.0f/255.0f;
|
||||
float crbias = -128.0f/255.0f;
|
||||
float c = procamp ? procamp->contrast : 1.0f;
|
||||
float s = procamp ? procamp->saturation : 1.0f;
|
||||
float b = procamp ? procamp->brightness : 0.0f;
|
||||
float h = procamp ? procamp->hue : 0.0f;
|
||||
const float *cstd;
|
||||
|
||||
assert(matrix);
|
||||
|
||||
switch (cs) {
|
||||
case VL_CSC_COLOR_STANDARD_BT_601:
|
||||
cstd = full_range ? &bt_601_full[0] : &bt_601[0];
|
||||
break;
|
||||
case VL_CSC_COLOR_STANDARD_BT_709:
|
||||
cstd = full_range ? &bt_709_full[0] : &bt_709[0];
|
||||
break;
|
||||
case VL_CSC_COLOR_STANDARD_IDENTITY:
|
||||
default:
|
||||
assert(cs == VL_CSC_COLOR_STANDARD_IDENTITY);
|
||||
memcpy(matrix, &identity[0], sizeof(float) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
matrix[ 0] = c*cstd[ 0];
|
||||
matrix[ 1] = c*cstd[ 1]*s*cosf(h) - c*cstd[ 2]*s*sinf(h);
|
||||
matrix[ 2] = c*cstd[ 2]*s*cosf(h) + c*cstd[ 1]*s*sinf(h);
|
||||
matrix[ 3] = cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[ 2]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h));
|
||||
|
||||
matrix[ 4] = c*cstd[ 4];
|
||||
matrix[ 5] = c*cstd[ 5]*s*cosf(h) - c*cstd[ 6]*s*sinf(h);
|
||||
matrix[ 6] = c*cstd[ 6]*s*cosf(h) + c*cstd[ 5]*s*sinf(h);
|
||||
matrix[ 7] = cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[ 6]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h));
|
||||
|
||||
matrix[ 8] = c*cstd[ 8];
|
||||
matrix[ 9] = c*cstd[ 9]*s*cosf(h) - c*cstd[10]*s*sinf(h);
|
||||
matrix[10] = c*cstd[10]*s*cosf(h) + c*cstd[ 9]*s*sinf(h);
|
||||
matrix[11] = cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[10]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h));
|
||||
|
||||
matrix[12] = c*cstd[12];
|
||||
matrix[13] = c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h);
|
||||
matrix[14] = c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h);
|
||||
matrix[15] = cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h));
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* 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
|
||||
|
|
@ -10,11 +10,11 @@
|
|||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
|
|
@ -22,44 +22,32 @@
|
|||
* 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 STW_WINSYS_H
|
||||
#define STW_WINSYS_H
|
||||
#ifndef vl_csc_h
|
||||
#define vl_csc_h
|
||||
|
||||
#include <windows.h> /* for HDC */
|
||||
#include <pipe/p_compiler.h>
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct pipe_screen;
|
||||
struct pipe_context;
|
||||
struct pipe_surface;
|
||||
|
||||
struct stw_winsys
|
||||
struct vl_procamp
|
||||
{
|
||||
struct pipe_screen *
|
||||
(*create_screen)( void );
|
||||
|
||||
struct pipe_context *
|
||||
(*create_context)( struct pipe_screen *screen );
|
||||
|
||||
void
|
||||
(*flush_frontbuffer)( struct pipe_screen *screen,
|
||||
struct pipe_surface *surf,
|
||||
HDC hDC );
|
||||
float brightness;
|
||||
float contrast;
|
||||
float saturation;
|
||||
float hue;
|
||||
};
|
||||
|
||||
boolean
|
||||
stw_init(const struct stw_winsys *stw_winsys);
|
||||
enum VL_CSC_COLOR_STANDARD
|
||||
{
|
||||
VL_CSC_COLOR_STANDARD_IDENTITY,
|
||||
VL_CSC_COLOR_STANDARD_BT_601,
|
||||
VL_CSC_COLOR_STANDARD_BT_709
|
||||
};
|
||||
|
||||
boolean
|
||||
stw_init_thread(void);
|
||||
void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs,
|
||||
struct vl_procamp *procamp,
|
||||
bool full_range,
|
||||
float *matrix);
|
||||
|
||||
void
|
||||
stw_cleanup_thread(void);
|
||||
|
||||
void
|
||||
stw_cleanup(void);
|
||||
|
||||
#endif /* STW_WINSYS_H */
|
||||
#endif /* vl_csc_h */
|
||||
1654
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
Normal file
1654
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
Normal file
File diff suppressed because it is too large
Load diff
120
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
Normal file
120
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef vl_mpeg12_mc_renderer_h
|
||||
#define vl_mpeg12_mc_renderer_h
|
||||
|
||||
#include <pipe/p_compiler.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_video_state.h>
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_video_surface;
|
||||
struct pipe_macroblock;
|
||||
|
||||
/* A slice is video-width (rounded up to a multiple of macroblock width) x macroblock height */
|
||||
enum VL_MPEG12_MC_RENDERER_BUFFER_MODE
|
||||
{
|
||||
VL_MPEG12_MC_RENDERER_BUFFER_SLICE, /* Saves memory at the cost of smaller batches */
|
||||
VL_MPEG12_MC_RENDERER_BUFFER_PICTURE /* Larger batches, more memory */
|
||||
};
|
||||
|
||||
enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK
|
||||
{
|
||||
VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL, /* Waste of memory bandwidth */
|
||||
VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, /* Can only do point-filtering when interpolating subsampled chroma channels */
|
||||
VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE /* Needs conditional texel fetch! */
|
||||
};
|
||||
|
||||
struct vl_mpeg12_mc_renderer
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
unsigned picture_width;
|
||||
unsigned picture_height;
|
||||
enum pipe_video_chroma_format chroma_format;
|
||||
enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode;
|
||||
enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling;
|
||||
bool pot_buffers;
|
||||
unsigned macroblocks_per_batch;
|
||||
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_constant_buffer vs_const_buf;
|
||||
struct pipe_constant_buffer fs_const_buf;
|
||||
struct pipe_framebuffer_state fb_state;
|
||||
struct pipe_vertex_element vertex_elems[8];
|
||||
|
||||
union
|
||||
{
|
||||
void *all[5];
|
||||
struct { void *y, *cb, *cr, *ref[2]; } individual;
|
||||
} samplers;
|
||||
|
||||
void *i_vs, *p_vs[2], *b_vs[2];
|
||||
void *i_fs, *p_fs[2], *b_fs[2];
|
||||
|
||||
union
|
||||
{
|
||||
struct pipe_texture *all[5];
|
||||
struct { struct pipe_texture *y, *cb, *cr, *ref[2]; } individual;
|
||||
} textures;
|
||||
|
||||
union
|
||||
{
|
||||
struct pipe_vertex_buffer all[3];
|
||||
struct { struct pipe_vertex_buffer ycbcr, ref[2]; } individual;
|
||||
} vertex_bufs;
|
||||
|
||||
struct pipe_texture *surface, *past, *future;
|
||||
struct pipe_fence_handle **fence;
|
||||
unsigned num_macroblocks;
|
||||
struct pipe_mpeg12_macroblock *macroblock_buf;
|
||||
struct pipe_transfer *tex_transfer[3];
|
||||
short *texels[3];
|
||||
struct { float x, y; } surface_tex_inv_size;
|
||||
struct { float x, y; } zero_block[3];
|
||||
};
|
||||
|
||||
bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
|
||||
struct pipe_context *pipe,
|
||||
unsigned picture_width,
|
||||
unsigned picture_height,
|
||||
enum pipe_video_chroma_format chroma_format,
|
||||
enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
|
||||
enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
|
||||
bool pot_buffers);
|
||||
|
||||
void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
|
||||
|
||||
void vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
|
||||
struct pipe_texture *surface,
|
||||
struct pipe_texture *past,
|
||||
struct pipe_texture *future,
|
||||
unsigned num_macroblocks,
|
||||
struct pipe_mpeg12_macroblock *mpeg12_macroblocks,
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
#endif /* vl_mpeg12_mc_renderer_h */
|
||||
242
src/gallium/auxiliary/vl/vl_shader_build.c
Normal file
242
src/gallium/auxiliary/vl/vl_shader_build.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "vl_shader_build.h"
|
||||
#include <assert.h>
|
||||
#include <tgsi/tgsi_parse.h>
|
||||
#include <tgsi/tgsi_build.h>
|
||||
|
||||
struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last)
|
||||
{
|
||||
struct tgsi_full_declaration decl = tgsi_default_full_declaration();
|
||||
|
||||
decl.Declaration.File = TGSI_FILE_INPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = name;
|
||||
decl.Semantic.SemanticIndex = index;
|
||||
decl.DeclarationRange.First = first;
|
||||
decl.DeclarationRange.Last = last;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
struct tgsi_full_declaration vl_decl_interpolated_input
|
||||
(
|
||||
unsigned int name,
|
||||
unsigned int index,
|
||||
unsigned int first,
|
||||
unsigned int last,
|
||||
int interpolation
|
||||
)
|
||||
{
|
||||
struct tgsi_full_declaration decl = tgsi_default_full_declaration();
|
||||
|
||||
assert
|
||||
(
|
||||
interpolation == TGSI_INTERPOLATE_CONSTANT ||
|
||||
interpolation == TGSI_INTERPOLATE_LINEAR ||
|
||||
interpolation == TGSI_INTERPOLATE_PERSPECTIVE
|
||||
);
|
||||
|
||||
decl.Declaration.File = TGSI_FILE_INPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = name;
|
||||
decl.Semantic.SemanticIndex = index;
|
||||
decl.Declaration.Interpolate = interpolation;;
|
||||
decl.DeclarationRange.First = first;
|
||||
decl.DeclarationRange.Last = last;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last)
|
||||
{
|
||||
struct tgsi_full_declaration decl = tgsi_default_full_declaration();
|
||||
|
||||
decl.Declaration.File = TGSI_FILE_CONSTANT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = name;
|
||||
decl.Semantic.SemanticIndex = index;
|
||||
decl.DeclarationRange.First = first;
|
||||
decl.DeclarationRange.Last = last;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last)
|
||||
{
|
||||
struct tgsi_full_declaration decl = tgsi_default_full_declaration();
|
||||
|
||||
decl.Declaration.File = TGSI_FILE_OUTPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = name;
|
||||
decl.Semantic.SemanticIndex = index;
|
||||
decl.DeclarationRange.First = first;
|
||||
decl.DeclarationRange.Last = last;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last)
|
||||
{
|
||||
struct tgsi_full_declaration decl = tgsi_default_full_declaration();
|
||||
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_TEMPORARY;
|
||||
decl.DeclarationRange.First = first;
|
||||
decl.DeclarationRange.Last = last;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last)
|
||||
{
|
||||
struct tgsi_full_declaration decl = tgsi_default_full_declaration();
|
||||
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_SAMPLER;
|
||||
decl.DeclarationRange.First = first;
|
||||
decl.DeclarationRange.Last = last;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
struct tgsi_full_instruction vl_inst2
|
||||
(
|
||||
int opcode,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src_file,
|
||||
unsigned int src_index
|
||||
)
|
||||
{
|
||||
struct tgsi_full_instruction inst = tgsi_default_full_instruction();
|
||||
|
||||
inst.Instruction.Opcode = opcode;
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.FullDstRegisters[0].DstRegister.File = dst_file;
|
||||
inst.FullDstRegisters[0].DstRegister.Index = dst_index;
|
||||
inst.Instruction.NumSrcRegs = 1;
|
||||
inst.FullSrcRegisters[0].SrcRegister.File = src_file;
|
||||
inst.FullSrcRegisters[0].SrcRegister.Index = src_index;
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
struct tgsi_full_instruction vl_inst3
|
||||
(
|
||||
int opcode,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src1_file,
|
||||
unsigned int src1_index,
|
||||
enum tgsi_file_type src2_file,
|
||||
unsigned int src2_index
|
||||
)
|
||||
{
|
||||
struct tgsi_full_instruction inst = tgsi_default_full_instruction();
|
||||
|
||||
inst.Instruction.Opcode = opcode;
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.FullDstRegisters[0].DstRegister.File = dst_file;
|
||||
inst.FullDstRegisters[0].DstRegister.Index = dst_index;
|
||||
inst.Instruction.NumSrcRegs = 2;
|
||||
inst.FullSrcRegisters[0].SrcRegister.File = src1_file;
|
||||
inst.FullSrcRegisters[0].SrcRegister.Index = src1_index;
|
||||
inst.FullSrcRegisters[1].SrcRegister.File = src2_file;
|
||||
inst.FullSrcRegisters[1].SrcRegister.Index = src2_index;
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
struct tgsi_full_instruction vl_tex
|
||||
(
|
||||
int tex,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src1_file,
|
||||
unsigned int src1_index,
|
||||
enum tgsi_file_type src2_file,
|
||||
unsigned int src2_index
|
||||
)
|
||||
{
|
||||
struct tgsi_full_instruction inst = tgsi_default_full_instruction();
|
||||
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_TEX;
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.FullDstRegisters[0].DstRegister.File = dst_file;
|
||||
inst.FullDstRegisters[0].DstRegister.Index = dst_index;
|
||||
inst.Instruction.NumSrcRegs = 2;
|
||||
inst.InstructionExtTexture.Texture = tex;
|
||||
inst.FullSrcRegisters[0].SrcRegister.File = src1_file;
|
||||
inst.FullSrcRegisters[0].SrcRegister.Index = src1_index;
|
||||
inst.FullSrcRegisters[1].SrcRegister.File = src2_file;
|
||||
inst.FullSrcRegisters[1].SrcRegister.Index = src2_index;
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
struct tgsi_full_instruction vl_inst4
|
||||
(
|
||||
int opcode,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src1_file,
|
||||
unsigned int src1_index,
|
||||
enum tgsi_file_type src2_file,
|
||||
unsigned int src2_index,
|
||||
enum tgsi_file_type src3_file,
|
||||
unsigned int src3_index
|
||||
)
|
||||
{
|
||||
struct tgsi_full_instruction inst = tgsi_default_full_instruction();
|
||||
|
||||
inst.Instruction.Opcode = opcode;
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.FullDstRegisters[0].DstRegister.File = dst_file;
|
||||
inst.FullDstRegisters[0].DstRegister.Index = dst_index;
|
||||
inst.Instruction.NumSrcRegs = 3;
|
||||
inst.FullSrcRegisters[0].SrcRegister.File = src1_file;
|
||||
inst.FullSrcRegisters[0].SrcRegister.Index = src1_index;
|
||||
inst.FullSrcRegisters[1].SrcRegister.File = src2_file;
|
||||
inst.FullSrcRegisters[1].SrcRegister.Index = src2_index;
|
||||
inst.FullSrcRegisters[2].SrcRegister.File = src3_file;
|
||||
inst.FullSrcRegisters[2].SrcRegister.Index = src3_index;
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
struct tgsi_full_instruction vl_end(void)
|
||||
{
|
||||
struct tgsi_full_instruction inst = tgsi_default_full_instruction();
|
||||
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_END;
|
||||
inst.Instruction.NumDstRegs = 0;
|
||||
inst.Instruction.NumSrcRegs = 0;
|
||||
|
||||
return inst;
|
||||
}
|
||||
88
src/gallium/auxiliary/vl/vl_shader_build.h
Normal file
88
src/gallium/auxiliary/vl/vl_shader_build.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 Younes Manton.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef vl_shader_build_h
|
||||
#define vl_shader_build_h
|
||||
|
||||
#include <pipe/p_shader_tokens.h>
|
||||
|
||||
struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last);
|
||||
struct tgsi_full_declaration vl_decl_interpolated_input
|
||||
(
|
||||
unsigned int name,
|
||||
unsigned int index,
|
||||
unsigned int first,
|
||||
unsigned int last,
|
||||
int interpolation
|
||||
);
|
||||
struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last);
|
||||
struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last);
|
||||
struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last);
|
||||
struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last);
|
||||
struct tgsi_full_instruction vl_inst2
|
||||
(
|
||||
int opcode,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src_file,
|
||||
unsigned int src_index
|
||||
);
|
||||
struct tgsi_full_instruction vl_inst3
|
||||
(
|
||||
int opcode,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src1_file,
|
||||
unsigned int src1_index,
|
||||
enum tgsi_file_type src2_file,
|
||||
unsigned int src2_index
|
||||
);
|
||||
struct tgsi_full_instruction vl_tex
|
||||
(
|
||||
int tex,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src1_file,
|
||||
unsigned int src1_index,
|
||||
enum tgsi_file_type src2_file,
|
||||
unsigned int src2_index
|
||||
);
|
||||
struct tgsi_full_instruction vl_inst4
|
||||
(
|
||||
int opcode,
|
||||
enum tgsi_file_type dst_file,
|
||||
unsigned int dst_index,
|
||||
enum tgsi_file_type src1_file,
|
||||
unsigned int src1_index,
|
||||
enum tgsi_file_type src2_file,
|
||||
unsigned int src2_index,
|
||||
enum tgsi_file_type src3_file,
|
||||
unsigned int src3_index
|
||||
);
|
||||
struct tgsi_full_instruction vl_end(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
static const char *
|
||||
cell_get_vendor(struct pipe_screen *screen)
|
||||
{
|
||||
return "Tungsten Graphics, Inc.";
|
||||
return "VMware, Inc.";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -389,22 +389,14 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
|
|||
const uint texWidth = pt->width[level];
|
||||
const uint texHeight = pt->height[level];
|
||||
const uint stride = ct->stride[level];
|
||||
unsigned flags = 0x0;
|
||||
unsigned size;
|
||||
|
||||
assert(transfer->texture);
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_READ) {
|
||||
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
|
||||
}
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_WRITE) {
|
||||
flags |= PIPE_BUFFER_USAGE_CPU_READ;
|
||||
}
|
||||
|
||||
if (!ct->mapped) {
|
||||
/* map now */
|
||||
ct->mapped = pipe_buffer_map(screen, ct->buffer, flags);
|
||||
ct->mapped = pipe_buffer_map(screen, ct->buffer,
|
||||
pipe_transfer_buffer_flags(transfer));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -417,8 +409,7 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
|
|||
if (!ctrans->map)
|
||||
return NULL; /* out of memory */
|
||||
|
||||
if (transfer->usage == PIPE_TRANSFER_READ ||
|
||||
transfer->usage == PIPE_TRANSFER_READ_WRITE) {
|
||||
if (transfer->usage & PIPE_TRANSFER_READ) {
|
||||
/* need to untwiddle the texture to make a linear version */
|
||||
const uint bpp = pf_get_size(ct->base.format);
|
||||
if (bpp == 4) {
|
||||
|
|
@ -459,8 +450,7 @@ cell_transfer_unmap(struct pipe_screen *screen,
|
|||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
}
|
||||
|
||||
if (transfer->usage == PIPE_TRANSFER_WRITE ||
|
||||
transfer->usage == PIPE_TRANSFER_READ_WRITE) {
|
||||
if (transfer->usage & PIPE_TRANSFER_WRITE) {
|
||||
/* The user wrote new texture data into the mapped buffer.
|
||||
* We need to convert the new linear data into the twiddled/tiled format.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -175,12 +175,19 @@ i915_is_buffer_referenced(struct pipe_context *pipe,
|
|||
static void i915_destroy(struct pipe_context *pipe)
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
int i;
|
||||
|
||||
draw_destroy(i915->draw);
|
||||
|
||||
if(i915->batch)
|
||||
i915->iws->batchbuffer_destroy(i915->batch);
|
||||
|
||||
/* unbind framebuffer */
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
|
||||
}
|
||||
pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
|
||||
|
||||
FREE(i915);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render)
|
|||
struct intel_winsys *iws = i915->iws;
|
||||
|
||||
if (i915->vbo_flushed)
|
||||
debug_printf("%s bad vbo flush occured stalling on hw\n");
|
||||
debug_printf("%s bad vbo flush occured stalling on hw\n", __FUNCTION__);
|
||||
|
||||
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
|
||||
|
||||
|
|
@ -389,14 +389,43 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
|
|||
uint nr)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
|
||||
if (i915_render->fallback) {
|
||||
draw_arrays_fallback(render, start, nr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* JB: TODO submit direct cmds */
|
||||
draw_arrays_fallback(render, start, nr);
|
||||
if (i915->dirty)
|
||||
i915_update_derived(i915);
|
||||
|
||||
if (i915->hardware_dirty)
|
||||
i915_emit_hardware_state(i915);
|
||||
|
||||
if (!BEGIN_BATCH(2, 0)) {
|
||||
FLUSH_BATCH(NULL);
|
||||
|
||||
/* Make sure state is re-emitted after a flush:
|
||||
*/
|
||||
i915_update_derived(i915);
|
||||
i915_emit_hardware_state(i915);
|
||||
i915->vbo_flushed = 1;
|
||||
|
||||
if (!BEGIN_BATCH(2, 0)) {
|
||||
assert(0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
OUT_BATCH(_3DPRIMITIVE |
|
||||
PRIM_INDIRECT |
|
||||
PRIM_INDIRECT_SEQUENTIAL |
|
||||
i915_render->hwprim |
|
||||
nr);
|
||||
OUT_BATCH(start); /* Beginning vertex index */
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
static const char *
|
||||
i915_get_vendor(struct pipe_screen *screen)
|
||||
{
|
||||
return "Tungsten Graphics, Inc.";
|
||||
return "VMware, Inc.";
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
|
|
|||
|
|
@ -588,9 +588,17 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe,
|
|||
const struct pipe_framebuffer_state *fb)
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
int i;
|
||||
|
||||
draw_flush(i915->draw);
|
||||
|
||||
i915->framebuffer = *fb; /* struct copy */
|
||||
i915->framebuffer.width = fb->width;
|
||||
i915->framebuffer.height = fb->height;
|
||||
i915->framebuffer.nr_cbufs = fb->nr_cbufs;
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]);
|
||||
}
|
||||
pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf);
|
||||
|
||||
i915->dirty |= I915_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue