Conflicts: src/gallium/drivers/softpipe/sp_quad_fs.c src/gallium/drivers/softpipe/sp_state.h src/gallium/drivers/softpipe/sp_state_fs.ctags/mesa_20090313
@@ -86,7 +86,7 @@ else | |||
endif | |||
# Directories | |||
SRC_DIRS = mesa glu glut/beos | |||
SRC_DIRS = gallium mesa glu glut/beos | |||
GLU_DIRS = sgi | |||
DRIVER_DIRS = beos | |||
PROGRAM_DIRS = beos samples redbook demos tests |
@@ -25,5 +25,5 @@ GLW_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXt $(TOP)/lib/GL.dylib | |||
APP_LIB_DEPS = -L$(TOP)/lib -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L/usr/X11R6/lib -lX11 -lXmu -lXt -lXi -lm | |||
# omit glw lib for now: | |||
SRC_DIRS = mesa glu glut/glx | |||
SRC_DIRS = gallium mesa glu glut/glx | |||
@@ -29,5 +29,5 @@ GLW_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXt $(TOP)/lib/GL.dylib | |||
APP_LIB_DEPS = -L$(TOP)/lib -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L/usr/X11R6/lib -lX11 -lXmu -lXt -lXi -lm | |||
# omit glw lib for now: | |||
SRC_DIRS = mesa glu glut/glx | |||
SRC_DIRS = gallium mesa glu glut/glx | |||
@@ -60,7 +60,7 @@ GLW_SOURCES = GLwDrawA.c | |||
# Directories to build | |||
LIB_DIR = lib | |||
SRC_DIRS = mesa glu glut/glx glw | |||
SRC_DIRS = gallium mesa glu glut/glx glw | |||
GLU_DIRS = sgi | |||
DRIVER_DIRS = x11 osmesa | |||
# Which subdirs under $(TOP)/progs/ to enter: |
@@ -36,7 +36,7 @@ GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGL -lXt -lX11 | |||
# Directories | |||
SRC_DIRS = glx/x11 mesa glu glut/glx glw | |||
SRC_DIRS = glx/x11 gallium mesa glu glut/glx glw | |||
DRIVER_DIRS = dri | |||
PROGRAM_DIRS = | |||
WINDOW_SYSTEM=dri |
@@ -21,7 +21,7 @@ CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec -I. -I$( | |||
CXXFLAGS = $(CFLAGS) | |||
# Omitting glw here: | |||
SRC_DIRS = mesa glu glut/glx | |||
SRC_DIRS = gallium mesa glu glut/glx | |||
MKDEP_OPTIONS = -fdepend -Y |
@@ -22,7 +22,7 @@ ifeq ($(HAVE_X86), yes) | |||
endif | |||
# Directories | |||
SRC_DIRS = mesa glu glut/directfb | |||
SRC_DIRS = gallium mesa glu glut/directfb | |||
GLU_DIRS = sgi | |||
DRIVER_DIRS = directfb | |||
PROGRAM_DIRS = demos directfb |
@@ -54,10 +54,10 @@ USING_EGL=0 | |||
# Directories | |||
ifeq ($(USING_EGL), 1) | |||
SRC_DIRS = egl glx/x11 mesa glu glut/glx glw | |||
SRC_DIRS = egl glx/x11 gallium mesa glu glut/glx glw | |||
PROGRAM_DIRS = egl | |||
else | |||
SRC_DIRS = glx/x11 mesa glu glut/glx glw | |||
SRC_DIRS = glx/x11 gallium mesa glu glut/glx glw | |||
PROGRAM_DIRS = | |||
endif | |||
@@ -66,4 +66,4 @@ WINDOW_SYSTEM=dri | |||
# gamma are missing because they have not been converted to use the new | |||
# interface. | |||
DRI_DIRS = intel_winsys | |||
DRI_DIRS = intel |
@@ -53,10 +53,10 @@ USING_EGL=0 | |||
# Directories | |||
ifeq ($(USING_EGL), 1) | |||
SRC_DIRS = egl glx/x11 mesa glu glut/glx glw | |||
SRC_DIRS = egl glx/x11 gallium mesa glu glut/glx glw | |||
PROGRAM_DIRS = egl | |||
else | |||
SRC_DIRS = glx/x11 mesa glu glut/glx glw | |||
SRC_DIRS = glx/x11 gallium mesa glu glut/glx glw | |||
PROGRAM_DIRS = | |||
endif | |||
@@ -6,7 +6,7 @@ CONFIG_NAME = linux-fbdev | |||
CFLAGS = -O3 -ffast-math -ansi -pedantic -fPIC -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE -DPTHREADS -DUSE_GLFBDEV_DRIVER | |||
SRC_DIRS = mesa glu glut/fbdev | |||
SRC_DIRS = gallium mesa glu glut/fbdev | |||
DRIVER_DIRS = fbdev osmesa | |||
PROGRAM_DIRS = fbdev demos redbook samples | |||
@@ -14,7 +14,7 @@ CXXFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_POSIX_SOURCE -D_POSIX_C_SOUR | |||
# Directories | |||
SRC_DIRS = mesa glu | |||
SRC_DIRS = gallium mesa glu | |||
DRIVER_DIRS = osmesa | |||
PROGRAM_DIRS = osdemos | |||
@@ -17,7 +17,7 @@ OSMESA_LIB_NAME = libOSMesa16.so | |||
# Directories | |||
SRC_DIRS = mesa glu | |||
SRC_DIRS = gallium mesa glu | |||
DRIVER_DIRS = osmesa | |||
PROGRAM_DIRS = | |||
@@ -18,7 +18,7 @@ OSMESA_LIB_NAME = libOSMesa16.a | |||
# Directories | |||
SRC_DIRS = mesa glu | |||
SRC_DIRS = gallium mesa glu | |||
DRIVER_DIRS = osmesa | |||
PROGRAM_DIRS = | |||
@@ -17,7 +17,7 @@ OSMESA_LIB_NAME = libOSMesa32.so | |||
# Directories | |||
SRC_DIRS = mesa glu | |||
SRC_DIRS = gallium mesa glu | |||
DRIVER_DIRS = osmesa | |||
PROGRAM_DIRS = | |||
@@ -43,7 +43,7 @@ GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -lm | |||
APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -lm -lpthread | |||
# Directories | |||
SRC_DIRS = glx/mini mesa glu glut/mini | |||
SRC_DIRS = glx/mini gallium mesa glu glut/mini | |||
DRIVER_DIRS = dri | |||
PROGRAM_DIRS = miniglx | |||
@@ -39,6 +39,7 @@ SOURCES = \ | |||
linestrip-stipple-wide.c \ | |||
linestrip-stipple.c \ | |||
linestrip.c \ | |||
pgon-mode.c \ | |||
point-clip.c \ | |||
point-param.c \ | |||
point-sprite.c \ |
@@ -0,0 +1,136 @@ | |||
/** | |||
* Test glPolygonMode. | |||
* A tri-strip w/ two tris is drawn so that the first tri is front-facing | |||
* but the second tri is back-facing. | |||
* Set glPolygonMode differently for the front/back faces | |||
* | |||
*/ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <math.h> | |||
#include <GL/glut.h> | |||
static int Win; | |||
static GLfloat Zrot = 0; | |||
static GLboolean FrontFillBackUnfilled = GL_TRUE; | |||
static GLboolean Lines = GL_TRUE; | |||
static void | |||
Draw(void) | |||
{ | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
if (FrontFillBackUnfilled) { | |||
if (Lines) { | |||
printf("FrontMode = FILL, BackMode = LINE\n"); | |||
glPolygonMode(GL_BACK, GL_LINE); | |||
} | |||
else { | |||
printf("FrontMode = FILL, BackMode = POINT\n"); | |||
glPolygonMode(GL_BACK, GL_POINT); | |||
} | |||
glPolygonMode(GL_FRONT, GL_FILL); | |||
} | |||
else { | |||
if (Lines) { | |||
printf("FrontMode = LINE, BackMode = FILL\n"); | |||
glPolygonMode(GL_FRONT, GL_LINE); | |||
} | |||
else { | |||
printf("FrontMode = POINT, BackMode = FILL\n"); | |||
glPolygonMode(GL_FRONT, GL_POINT); | |||
} | |||
glPolygonMode(GL_BACK, GL_FILL); | |||
} | |||
glPushMatrix(); | |||
glRotatef(Zrot, 0, 0, 1); | |||
glBegin(GL_TRIANGLE_STRIP); | |||
glVertex2f(-1, 0); | |||
glVertex2f( 1, 0); | |||
glVertex2f(0, 1); | |||
glVertex2f(0, -1); | |||
glEnd(); | |||
glPopMatrix(); | |||
glutSwapBuffers(); | |||
} | |||
static void | |||
Reshape(int width, int height) | |||
{ | |||
glViewport(0, 0, width, height); | |||
glMatrixMode(GL_PROJECTION); | |||
glLoadIdentity(); | |||
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); | |||
glMatrixMode(GL_MODELVIEW); | |||
glLoadIdentity(); | |||
glTranslatef(0.0, 0.0, -15.0); | |||
} | |||
static void | |||
Key(unsigned char key, int x, int y) | |||
{ | |||
const GLfloat step = 3.0; | |||
(void) x; | |||
(void) y; | |||
switch (key) { | |||
case 'p': | |||
FrontFillBackUnfilled = !FrontFillBackUnfilled; | |||
break; | |||
case 'l': | |||
Lines = !Lines; | |||
break; | |||
case 'z': | |||
Zrot -= step; | |||
break; | |||
case 'Z': | |||
Zrot += step; | |||
break; | |||
case 27: | |||
glutDestroyWindow(Win); | |||
exit(0); | |||
break; | |||
} | |||
glutPostRedisplay(); | |||
} | |||
static void | |||
Init(void) | |||
{ | |||
printf("GL_RENDERER = %s\n", (char*) glGetString(GL_RENDERER)); | |||
glLineWidth(3.0); | |||
glPointSize(3.0); | |||
glColor4f(1, 1, 1, 0.8); | |||
glEnable(GL_BLEND); | |||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
printf("Press 'p' to toggle polygon mode\n"); | |||
} | |||
int | |||
main(int argc, char *argv[]) | |||
{ | |||
glutInit(&argc, argv); | |||
glutInitWindowPosition(0, 0); | |||
glutInitWindowSize(400, 400); | |||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); | |||
Win = glutCreateWindow(argv[0]); | |||
glutReshapeFunc(Reshape); | |||
glutKeyboardFunc(Key); | |||
glutDisplayFunc(Draw); | |||
Init(); | |||
glutMainLoop(); | |||
return 0; | |||
} |
@@ -0,0 +1,20 @@ | |||
TOP = ../.. | |||
include $(TOP)/configs/current | |||
SUBDIRS = aux drivers | |||
default: subdirs | |||
subdirs: | |||
@for dir in $(SUBDIRS) ; do \ | |||
if [ -d $$dir ] ; then \ | |||
(cd $$dir && $(MAKE)) || exit 1 ; \ | |||
fi \ | |||
done | |||
clean: | |||
rm -f `find . -name \*.[oa]` |
@@ -15,7 +15,10 @@ OBJECTS = $(C_SOURCES:.c=.o) \ | |||
### Include directories | |||
INCLUDES = \ | |||
-I. \ | |||
-I$(TOP)/src/mesa/pipe \ | |||
-I$(TOP)/src/gallium/include \ | |||
-I$(TOP)/src/gallium/include/pipe \ | |||
-I$(TOP)/src/gallium/aux \ | |||
-I$(TOP)/src/gallium/drivers \ | |||
-I$(TOP)/src/mesa \ | |||
-I$(TOP)/include \ | |||
$(DRIVER_INCLUDES) | |||
@@ -38,7 +41,7 @@ INCLUDES = \ | |||
default: depend symlinks $(LIBNAME) | |||
$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/mesa/pipe/Makefile.template | |||
$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template | |||
$(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) | |||
@@ -0,0 +1,24 @@ | |||
TOP = ../../.. | |||
include $(TOP)/configs/current | |||
ifeq ($(CONFIG_NAME), linux-llvm) | |||
LLVM_DIR = llvm | |||
endif | |||
SUBDIRS = pipebuffer $(LLVM_DIR) | |||
default: subdirs | |||
subdirs: | |||
@for dir in $(SUBDIRS) ; do \ | |||
if [ -d $$dir ] ; then \ | |||
(cd $$dir && $(MAKE)) || exit 1 ; \ | |||
fi \ | |||
done | |||
clean: | |||
rm -f `find . -name \*.[oa]` |
@@ -459,7 +459,7 @@ static void clip_reset_stipple_counter( struct draw_stage *stage ) | |||
static void clip_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -472,7 +472,7 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw ) | |||
{ | |||
struct clipper *clipper = CALLOC_STRUCT(clipper); | |||
draw_alloc_tmps( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); | |||
draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); | |||
clipper->stage.draw = draw; | |||
clipper->stage.point = clip_point; |
@@ -242,7 +242,7 @@ draw_convert_wide_lines(struct draw_context *draw, boolean enable) | |||
/** | |||
* Allocate space for temporary post-transform vertices, such as for clipping. | |||
*/ | |||
void draw_alloc_tmps( struct draw_stage *stage, unsigned nr ) | |||
void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) | |||
{ | |||
assert(!stage->tmp); | |||
@@ -260,7 +260,7 @@ void draw_alloc_tmps( struct draw_stage *stage, unsigned nr ) | |||
} | |||
void draw_free_tmps( struct draw_stage *stage ) | |||
void draw_free_temp_verts( struct draw_stage *stage ) | |||
{ | |||
if (stage->tmp) { | |||
FREE( stage->tmp[0] ); |
@@ -123,7 +123,7 @@ static void cull_reset_stipple_counter( struct draw_stage *stage ) | |||
static void cull_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -135,7 +135,7 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw ) | |||
{ | |||
struct cull_stage *cull = CALLOC_STRUCT(cull_stage); | |||
draw_alloc_tmps( &cull->stage, 0 ); | |||
draw_alloc_temp_verts( &cull->stage, 0 ); | |||
cull->stage.draw = draw; | |||
cull->stage.next = NULL; |
@@ -176,7 +176,7 @@ static void flatshade_reset_stipple_counter( struct draw_stage *stage ) | |||
static void flatshade_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -188,7 +188,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) | |||
{ | |||
struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); | |||
draw_alloc_tmps( &flatshade->stage, 2 ); | |||
draw_alloc_temp_verts( &flatshade->stage, 2 ); | |||
flatshade->stage.draw = draw; | |||
flatshade->stage.next = NULL; |
@@ -159,7 +159,7 @@ static void offset_reset_stipple_counter( struct draw_stage *stage ) | |||
static void offset_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -171,7 +171,7 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw ) | |||
{ | |||
struct offset_stage *offset = CALLOC_STRUCT(offset_stage); | |||
draw_alloc_tmps( &offset->stage, 3 ); | |||
draw_alloc_temp_verts( &offset->stage, 3 ); | |||
offset->stage.draw = draw; | |||
offset->stage.next = NULL; |
@@ -45,7 +45,7 @@ | |||
#include "pipe/p_defines.h" | |||
#include "x86/rtasm/x86sse.h" | |||
#include "pipe/tgsi/exec/tgsi_exec.h" | |||
#include "tgsi/exec/tgsi_exec.h" | |||
struct gallivm_prog; | |||
@@ -276,9 +276,9 @@ extern struct draw_stage *draw_wide_stage( struct draw_context *context ); | |||
extern struct draw_stage *draw_validate_stage( struct draw_context *context ); | |||
extern void draw_free_tmps( struct draw_stage *stage ); | |||
extern void draw_reset_tmps( struct draw_stage *stage ); | |||
extern void draw_alloc_tmps( struct draw_stage *stage, unsigned nr ); | |||
extern void draw_free_temp_verts( struct draw_stage *stage ); | |||
extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); | |||
extern void draw_reset_vertex_ids( struct draw_context *draw ); | |||
@@ -212,6 +212,7 @@ passthrough_tri(struct draw_stage *stage, struct prim_header *header) | |||
static void | |||
stipple_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -223,7 +224,7 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw ) | |||
{ | |||
struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); | |||
draw_alloc_tmps( &stipple->stage, 2 ); | |||
draw_alloc_temp_verts( &stipple->stage, 2 ); | |||
stipple->stage.draw = draw; | |||
stipple->stage.next = NULL; |
@@ -176,7 +176,7 @@ static void twoside_reset_stipple_counter( struct draw_stage *stage ) | |||
static void twoside_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -188,7 +188,7 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw ) | |||
{ | |||
struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); | |||
draw_alloc_tmps( &twoside->stage, 3 ); | |||
draw_alloc_temp_verts( &twoside->stage, 3 ); | |||
twoside->stage.draw = draw; | |||
twoside->stage.next = NULL; |
@@ -165,6 +165,8 @@ static void unfilled_flush( struct draw_stage *stage, | |||
unsigned flags ) | |||
{ | |||
stage->next->flush( stage->next, flags ); | |||
stage->tri = unfilled_first_tri; | |||
} | |||
@@ -176,7 +178,7 @@ static void unfilled_reset_stipple_counter( struct draw_stage *stage ) | |||
static void unfilled_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -188,7 +190,7 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) | |||
{ | |||
struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); | |||
draw_alloc_tmps( &unfilled->stage, 0 ); | |||
draw_alloc_temp_verts( &unfilled->stage, 0 ); | |||
unfilled->stage.draw = draw; | |||
unfilled->stage.next = NULL; |
@@ -523,6 +523,9 @@ static void vbuf_destroy( struct draw_stage *stage ) | |||
if(vbuf->vf) | |||
draw_vf_destroy( vbuf->vf ); | |||
if (vbuf->render) | |||
vbuf->render->destroy( vbuf->render ); | |||
FREE( stage ); | |||
} | |||
@@ -34,8 +34,8 @@ | |||
*/ | |||
#include "pipe/draw/draw_private.h" | |||
#include "pipe/draw/draw_vertex.h" | |||
#include "draw/draw_private.h" | |||
#include "draw/draw_vertex.h" | |||
/** |
@@ -25,7 +25,12 @@ | |||
* | |||
**************************************************************************/ | |||
/* Author: | |||
/** | |||
* Post-transform vertex format info. The vertex_info struct is used by | |||
* the draw_vbuf code to emit hardware-specific vertex layouts into hw | |||
* vertex buffers. | |||
* | |||
* Author: | |||
* Brian Paul | |||
*/ | |||
@@ -34,13 +34,13 @@ | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#if defined(__i386__) || defined(__386__) | |||
#include "pipe/tgsi/exec/tgsi_sse2.h" | |||
#include "tgsi/exec/tgsi_sse2.h" | |||
#endif | |||
#include "draw_private.h" | |||
#include "draw_context.h" | |||
#include "x86/rtasm/x86sse.h" | |||
#include "pipe/llvm/gallivm.h" | |||
#include "llvm/gallivm.h" | |||
#define DBG_VS 0 |
@@ -370,7 +370,7 @@ void draw_vf_emit_vertex( struct draw_vertex_fetch *vf, | |||
unsigned j; | |||
for (j = 0; j < vf->attr_count; j++) { | |||
if(!a[j].isconst) { | |||
if (!a[j].isconst) { | |||
a[j].inputptr = (uint8_t *)&vertex->data[a[j].attrib][0]; | |||
a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 2003 Tungsten Graphics, inc. | |||
* Copyright 2008 Tungsten Graphics, inc. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
@@ -20,6 +20,17 @@ | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Vertex fetch/store/convert code. This functionality is used in two places: | |||
* 1. Vertex fetch/convert - to grab vertex data from incoming vertex | |||
* arrays and convert to format needed by vertex shaders. | |||
* 2. Vertex store/emit - to convert simple float[][4] vertex attributes | |||
* (which is the organization used throughout the draw/prim pipeline) to | |||
* hardware-specific formats and emit into hardware vertex buffers. | |||
* | |||
* | |||
* Authors: | |||
* Keith Whitwell <keithw@tungstengraphics.com> | |||
@@ -33,7 +44,7 @@ | |||
#include "pipe/p_state.h" | |||
#include "draw_vertex.h" | |||
#include "draw_private.h" // for vertex_header | |||
#include "draw_private.h" /* for vertex_header */ | |||
enum draw_vf_attr_format { | |||
@@ -181,6 +192,7 @@ struct draw_vf_attr_type { | |||
unsigned offset; | |||
}; | |||
/** XXX this could be moved into draw_vf.c */ | |||
struct draw_vf_fastpath { | |||
unsigned vertex_stride; | |||
unsigned attr_count; | |||
@@ -209,6 +221,7 @@ void | |||
draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ); | |||
/** XXX this type and function could probably be moved into draw_vf.c */ | |||
struct draw_vf_format_info { | |||
const char *name; | |||
draw_vf_insert_func insert[4]; |
@@ -175,7 +175,7 @@ static void wide_line_aa(struct draw_stage *stage, | |||
float *pos; | |||
float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; | |||
float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; | |||
const float len = sqrt(dx * dx + dy * dy); | |||
const float len = (float) sqrt(dx * dx + dy * dy); | |||
uint i; | |||
dx = dx * half_width / len; | |||
@@ -400,7 +400,7 @@ static void wide_flush( struct draw_stage *stage, unsigned flags ) | |||
} | |||
static void draw_reset_stipple_counter( struct draw_stage *stage ) | |||
static void wide_reset_stipple_counter( struct draw_stage *stage ) | |||
{ | |||
stage->next->reset_stipple_counter( stage->next ); | |||
} | |||
@@ -408,7 +408,7 @@ static void draw_reset_stipple_counter( struct draw_stage *stage ) | |||
static void wide_destroy( struct draw_stage *stage ) | |||
{ | |||
draw_free_tmps( stage ); | |||
draw_free_temp_verts( stage ); | |||
FREE( stage ); | |||
} | |||
@@ -417,7 +417,7 @@ struct draw_stage *draw_wide_stage( struct draw_context *draw ) | |||
{ | |||
struct wide_stage *wide = CALLOC_STRUCT(wide_stage); | |||
draw_alloc_tmps( &wide->stage, 4 ); | |||
draw_alloc_temp_verts( &wide->stage, 4 ); | |||
wide->stage.draw = draw; | |||
wide->stage.next = NULL; | |||
@@ -425,7 +425,7 @@ struct draw_stage *draw_wide_stage( struct draw_context *draw ) | |||
wide->stage.line = wide_first_line; | |||
wide->stage.tri = passthrough_tri; | |||
wide->stage.flush = wide_flush; | |||
wide->stage.reset_stipple_counter = draw_reset_stipple_counter; | |||
wide->stage.reset_stipple_counter = wide_reset_stipple_counter; | |||
wide->stage.destroy = wide_destroy; | |||
return &wide->stage; |
@@ -15,7 +15,7 @@ GALLIVM_SOURCES = \ | |||
storagesoa.cpp \ | |||
instructionssoa.cpp | |||
INC_SOURCES = gallivm_builtins.cpp llvm_base_shader.cpp | |||
INC_SOURCES = gallivm_builtins.cpp | |||
CPP_SOURCES = \ | |||
$(GALLIVM_SOURCES) | |||
@@ -30,7 +30,9 @@ OBJECTS = $(C_SOURCES:.c=.o) \ | |||
### Include directories | |||
INCLUDES = \ | |||
-I. \ | |||
-I$(TOP)/src/mesa/pipe \ | |||
-I$(TOP)/src/gallium/drivers | |||
-I$(TOP)/src/gallium/aux \ | |||
-I$(TOP)/src/gallium/include \ | |||
-I$(TOP)/src/mesa \ | |||
-I$(TOP)/include | |||
@@ -65,8 +67,6 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) | |||
gallivm_builtins.cpp: llvm_builtins.c | |||
clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins | |||
llvm_base_shader.cpp: llvm_entry.c | |||
clang --emit-llvm $< |llvm-as |opt -std-compile-opts |llvm2cpp -for=Shader -gen-module -o=$@ -f -funcname=createBaseShader | |||
# Emacs tags | |||
tags: | |||
@@ -77,7 +77,7 @@ tags: | |||
clean: | |||
-rm -f *.o */*.o *~ *.so *~ server/*.o | |||
-rm -f depend depend.bak | |||
-rm -f gallivm_builtins.cpp llvm_base_shader.cpp | |||
-rm -f gallivm_builtins.cpp | |||
symlinks: | |||
@@ -42,8 +42,8 @@ | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "pipe/tgsi/exec/tgsi_exec.h" | |||
#include "pipe/tgsi/util/tgsi_dump.h" | |||
#include "tgsi/exec/tgsi_exec.h" | |||
#include "tgsi/util/tgsi_dump.h" | |||
#include <llvm/Module.h> | |||
#include <llvm/CallingConv.h> |
@@ -42,8 +42,8 @@ | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "pipe/tgsi/exec/tgsi_exec.h" | |||
#include "pipe/tgsi/util/tgsi_dump.h" | |||
#include "tgsi/exec/tgsi_exec.h" | |||
#include "tgsi/util/tgsi_dump.h" | |||
#include <llvm/Module.h> | |||
#include <llvm/CallingConv.h> |
@@ -0,0 +1,121 @@ | |||
#include "instructionssoa.h" | |||
#include "storagesoa.h" | |||
#include <llvm/Constants.h> | |||
using namespace llvm; | |||
InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, | |||
llvm::BasicBlock *block, StorageSoa *storage) | |||
: m_builder(block), | |||
m_storage(storage), | |||
m_idx(0) | |||
{ | |||
} | |||
const char * InstructionsSoa::name(const char *prefix) const | |||
{ | |||
++m_idx; | |||
snprintf(m_name, 32, "%s%d", prefix, m_idx); | |||
return m_name; | |||
} | |||
llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, | |||
llvm::Value *z, llvm::Value *w) | |||
{ | |||
VectorType *vectorType = VectorType::get(Type::FloatTy, 4); | |||
Constant *constVector = Constant::getNullValue(vectorType); | |||
Value *res = m_builder.CreateInsertElement(constVector, x, | |||
m_storage->constantInt(0), | |||
name("vecx")); | |||
res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), | |||
name("vecxy")); | |||
res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), | |||
name("vecxyz")); | |||
if (w) | |||
res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), | |||
name("vecxyzw")); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> InstructionsSoa::arl(const std::vector<llvm::Value*> in) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
//Extract x's | |||
llvm::Value *x1 = m_builder.CreateExtractElement(in[0], | |||
m_storage->constantInt(0), | |||
name("extractX")); | |||
//cast it to an unsigned int | |||
x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); | |||
res[0] = x1;//vectorFromVals(x1, x2, x3, x4); | |||
//only x is valid. the others shouldn't be necessary | |||
/* | |||
res[1] = Constant::getNullValue(m_floatVecType); | |||
res[2] = Constant::getNullValue(m_floatVecType); | |||
res[3] = Constant::getNullValue(m_floatVecType); | |||
*/ | |||
return res; | |||
} | |||
std::vector<llvm::Value*> InstructionsSoa::add(const std::vector<llvm::Value*> in1, | |||
const std::vector<llvm::Value*> in2) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); | |||
res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); | |||
res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); | |||
res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> in1, | |||
const std::vector<llvm::Value*> in2) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); | |||
res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); | |||
res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); | |||
res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); | |||
return res; | |||
} | |||
void InstructionsSoa::end() | |||
{ | |||
m_builder.CreateRetVoid(); | |||
} | |||
std::vector<llvm::Value*> InstructionsSoa::madd(const std::vector<llvm::Value*> in1, | |||
const std::vector<llvm::Value*> in2, | |||
const std::vector<llvm::Value*> in3) | |||
{ | |||
std::vector<llvm::Value*> res = mul(in1, in2); | |||
return add(res, in3); | |||
} | |||
std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = m_builder.CreateExtractElement(vector, | |||
m_storage->constantInt(0), | |||
name("extract1X")); | |||
res[1] = m_builder.CreateExtractElement(vector, | |||
m_storage->constantInt(1), | |||
name("extract2X")); | |||
res[2] = m_builder.CreateExtractElement(vector, | |||
m_storage->constantInt(2), | |||
name("extract3X")); | |||
res[3] = m_builder.CreateExtractElement(vector, | |||
m_storage->constantInt(3), | |||
name("extract4X")); | |||
return res; | |||
} |
@@ -46,17 +46,25 @@ public: | |||
InstructionsSoa(llvm::Module *mod, llvm::Function *func, | |||
llvm::BasicBlock *block, StorageSoa *storage); | |||
std::vector<llvm::Value*> arl(const std::vector<llvm::Value*> in); | |||
std::vector<llvm::Value*> add(const std::vector<llvm::Value*> in1, | |||
const std::vector<llvm::Value*> in2); | |||
std::vector<llvm::Value*> madd(const std::vector<llvm::Value*> in1, | |||
const std::vector<llvm::Value*> in2, | |||
const std::vector<llvm::Value*> in3); | |||
std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1, | |||
const std::vector<llvm::Value*> in2); | |||
void end(); | |||
std::vector<llvm::Value*> extractVector(llvm::Value *vector); | |||
private: | |||
const char * name(const char *prefix) const; | |||
llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, | |||
llvm::Value *z, llvm::Value *w); | |||
private: | |||
llvm::LLVMFoldingBuilder m_builder; | |||
StorageSoa *m_storage; | |||
private: | |||
mutable int m_idx; | |||
mutable char m_name[32]; |
@@ -0,0 +1,389 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
#include "storagesoa.h" | |||
#include "gallivm_p.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "pipe/p_debug.h" | |||
#include <llvm/BasicBlock.h> | |||
#include <llvm/Module.h> | |||
#include <llvm/Value.h> | |||
#include <llvm/CallingConv.h> | |||
#include <llvm/Constants.h> | |||
#include <llvm/DerivedTypes.h> | |||
#include <llvm/InstrTypes.h> | |||
#include <llvm/Instructions.h> | |||
using namespace llvm; | |||
StorageSoa::StorageSoa(llvm::BasicBlock *block, | |||
llvm::Value *input, | |||
llvm::Value *output, | |||
llvm::Value *consts, | |||
llvm::Value *temps) | |||
: m_block(block), | |||
m_input(input), | |||
m_output(output), | |||
m_consts(consts), | |||
m_temps(temps), | |||
m_immediates(0), | |||
m_idx(0) | |||
{ | |||
} | |||
void StorageSoa::addImmediate(float *vec) | |||
{ | |||
std::vector<float> vals(4); | |||
vals[0] = vec[0]; | |||
vals[1] = vec[1]; | |||
vals[2] = vec[2]; | |||
vals[3] = vec[3]; | |||
m_immediatesToFlush.push_back(vals); | |||
} | |||
void StorageSoa::declareImmediates() | |||
{ | |||
if (m_immediatesToFlush.empty()) | |||
return; | |||
VectorType *vectorType = VectorType::get(Type::FloatTy, 4); | |||
ArrayType *vectorChannels = ArrayType::get(vectorType, 4); | |||
ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); | |||
m_immediates = new GlobalVariable( | |||
/*Type=*/arrayType, | |||
/*isConstant=*/false, | |||
/*Linkage=*/GlobalValue::ExternalLinkage, | |||
/*Initializer=*/0, // has initializer, specified below | |||
/*Name=*/name("immediates"), | |||
currentModule()); | |||
std::vector<Constant*> arrayVals; | |||
for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { | |||
std::vector<float> vec = m_immediatesToFlush[i]; | |||
std::vector<float> vals(4); | |||
std::vector<Constant*> channelArray; | |||
vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; | |||
llvm::Constant *xChannel = createConstGlobalVector(vals); | |||
vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; | |||
llvm::Constant *yChannel = createConstGlobalVector(vals); | |||
vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; | |||
llvm::Constant *zChannel = createConstGlobalVector(vals); | |||
vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; | |||
llvm::Constant *wChannel = createConstGlobalVector(vals); | |||
channelArray.push_back(xChannel); | |||
channelArray.push_back(yChannel); | |||
channelArray.push_back(zChannel); | |||
channelArray.push_back(wChannel); | |||
Constant *constChannels = ConstantArray::get(vectorChannels, | |||
channelArray); | |||
arrayVals.push_back(constChannels); | |||
} | |||
Constant *constArray = ConstantArray::get(arrayType, arrayVals); | |||
m_immediates->setInitializer(constArray); | |||
m_immediatesToFlush.clear(); | |||
} | |||
llvm::Value *StorageSoa::addrElement(int idx) const | |||
{ | |||
std::map<int, llvm::Value*>::const_iterator itr = m_addresses.find(idx); | |||
if (itr == m_addresses.end()) { | |||
debug_printf("Trying to access invalid shader 'address'\n"); | |||
return 0; | |||
} | |||
llvm::Value * res = (*itr).second; | |||
res = new LoadInst(res, name("addr"), false, m_block); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> StorageSoa::inputElement(llvm::Value *idx) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = element(m_input, idx, 0); | |||
res[1] = element(m_input, idx, 1); | |||
res[2] = element(m_input, idx, 2); | |||
res[3] = element(m_input, idx, 3); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> StorageSoa::constElement(llvm::Value *idx) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; | |||
xChannel = elementPointer(m_consts, idx, 0); | |||
yChannel = elementPointer(m_consts, idx, 1); | |||
zChannel = elementPointer(m_consts, idx, 2); | |||
wChannel = elementPointer(m_consts, idx, 3); | |||
res[0] = alignedArrayLoad(xChannel); | |||
res[1] = alignedArrayLoad(yChannel); | |||
res[2] = alignedArrayLoad(zChannel); | |||
res[3] = alignedArrayLoad(wChannel); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> StorageSoa::outputElement(llvm::Value *idx) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = element(m_output, idx, 0); | |||
res[1] = element(m_output, idx, 1); | |||
res[2] = element(m_output, idx, 2); | |||
res[3] = element(m_output, idx, 3); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> StorageSoa::tempElement(llvm::Value *idx) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = element(m_temps, idx, 0); | |||
res[1] = element(m_temps, idx, 1); | |||
res[2] = element(m_temps, idx, 2); | |||
res[3] = element(m_temps, idx, 3); | |||
return res; | |||
} | |||
std::vector<llvm::Value*> StorageSoa::immediateElement(llvm::Value *idx) | |||
{ | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = element(m_immediates, idx, 0); | |||
res[1] = element(m_immediates, idx, 1); | |||
res[2] = element(m_immediates, idx, 2); | |||
res[3] = element(m_immediates, idx, 3); | |||
return res; | |||
} | |||
llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, | |||
int channel) const | |||
{ | |||
std::vector<Value*> indices; | |||
if (m_immediates == ptr) | |||
indices.push_back(constantInt(0)); | |||
indices.push_back(index); | |||
indices.push_back(constantInt(channel)); | |||
GetElementPtrInst *getElem = new GetElementPtrInst(ptr, | |||
indices.begin(), | |||
indices.end(), | |||
name("ptr"), | |||
m_block); | |||
return getElem; | |||
} | |||
llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, | |||
int channel) const | |||
{ | |||
llvm::Value *res = elementPointer(ptr, index, channel); | |||
LoadInst *load = new LoadInst(res, name("element"), false, m_block); | |||
//load->setAlignment(8); | |||
return load; | |||
} | |||
const char * StorageSoa::name(const char *prefix) const | |||
{ | |||
++m_idx; | |||
snprintf(m_name, 32, "%s%d", prefix, m_idx); | |||
return m_name; | |||
} | |||
llvm::ConstantInt * StorageSoa::constantInt(int idx) const | |||
{ | |||
if (m_constInts.find(idx) != m_constInts.end()) { | |||
return m_constInts[idx]; | |||
} | |||
ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); | |||
m_constInts[idx] = constInt; | |||
return constInt; | |||
} | |||
llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) | |||
{ | |||
VectorType *vectorType = VectorType::get(Type::FloatTy, 4); | |||
PointerType *vectorPtr = PointerType::get(vectorType, 0); | |||
CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); | |||
LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); | |||
load->setAlignment(8); | |||
return load; | |||
} | |||
llvm::Module * StorageSoa::currentModule() const | |||
{ | |||
if (!m_block || !m_block->getParent()) | |||
return 0; | |||
return m_block->getParent()->getParent(); | |||
} | |||
llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector<float> &vec) | |||
{ | |||
VectorType *vectorType = VectorType::get(Type::FloatTy, 4); | |||
std::vector<Constant*> immValues; | |||
ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); | |||
ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); | |||
ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); | |||
ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); | |||
immValues.push_back(constx); | |||
immValues.push_back(consty); | |||
immValues.push_back(constz); | |||
immValues.push_back(constw); | |||
Constant *constVector = ConstantVector::get(vectorType, immValues); | |||
return constVector; | |||
} | |||
std::vector<llvm::Value*> StorageSoa::load(Argument type, int idx, int swizzle, | |||
llvm::Value *indIdx) | |||
{ | |||
std::vector<llvm::Value*> val(4); | |||
//if we have an indirect index, always use that | |||
// if not use the integer offset to create one | |||
llvm::Value *realIndex = 0; | |||
if (indIdx) | |||
realIndex = indIdx; | |||
else | |||
realIndex = constantInt(idx); | |||
debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); | |||
switch(type) { | |||
case Input: | |||
val = inputElement(realIndex); | |||
break; | |||
case Output: | |||
val = outputElement(realIndex); | |||
break; | |||
case Temp: | |||
val = tempElement(realIndex); | |||
break; | |||
case Const: | |||
val = constElement(realIndex); | |||
break; | |||
case Immediate: | |||
val = immediateElement(realIndex); | |||
break; | |||
case Address: | |||
debug_printf("Address not handled in the load phase!\n"); | |||
assert(0); | |||
break; | |||
} | |||
if (!gallivm_is_swizzle(swizzle)) | |||
return val; | |||
std::vector<llvm::Value*> res(4); | |||
res[0] = val[gallivm_x_swizzle(swizzle)]; | |||
res[1] = val[gallivm_y_swizzle(swizzle)]; | |||
res[2] = val[gallivm_z_swizzle(swizzle)]; | |||
res[3] = val[gallivm_w_swizzle(swizzle)]; | |||
return res; | |||
} | |||
void StorageSoa::store(Argument type, int idx, const std::vector<llvm::Value*> &val, | |||
int mask) | |||
{ | |||
llvm::Value *out = 0; | |||
switch(type) { | |||
case Output: | |||
out = m_output; | |||
break; | |||
case Temp: | |||
out = m_temps; | |||
break; | |||
case Input: | |||
out = m_input; | |||
break; | |||
case Address: { | |||
llvm::Value *addr = m_addresses[idx]; | |||
if (!addr) { | |||
addAddress(idx); | |||
addr = m_addresses[idx]; | |||
assert(addr); | |||
} | |||
new StoreInst(val[0], addr, false, m_block); | |||
return; | |||
break; | |||
} | |||
default: | |||
debug_printf("Can't save output of this type: %d !\n", type); | |||
assert(0); | |||
break; | |||
} | |||
llvm::Value *realIndex = constantInt(idx); | |||
if ((mask & TGSI_WRITEMASK_X)) { | |||
llvm::Value *xChannel = elementPointer(out, realIndex, 0); | |||
new StoreInst(val[0], xChannel, false, m_block); | |||
} | |||
if ((mask & TGSI_WRITEMASK_Y)) { | |||
llvm::Value *yChannel = elementPointer(out, realIndex, 1); | |||
new StoreInst(val[1], yChannel, false, m_block); | |||
} | |||
if ((mask & TGSI_WRITEMASK_Z)) { | |||
llvm::Value *zChannel = elementPointer(out, realIndex, 2); | |||
new StoreInst(val[2], zChannel, false, m_block); | |||
} | |||
if ((mask & TGSI_WRITEMASK_W)) { | |||
llvm::Value *wChannel = elementPointer(out, realIndex, 3); | |||
new StoreInst(val[3], wChannel, false, m_block); | |||
} | |||
} | |||
void StorageSoa::addAddress(int idx) | |||
{ | |||
GlobalVariable *val = new GlobalVariable( | |||
/*Type=*/IntegerType::get(32), | |||
/*isConstant=*/false, | |||
/*Linkage=*/GlobalValue::ExternalLinkage, | |||
/*Initializer=*/0, // has initializer, specified below | |||
/*Name=*/name("address"), | |||
currentModule()); | |||
val->setInitializer(Constant::getNullValue(IntegerType::get(32))); | |||
debug_printf("adding to %d\n", idx); | |||
m_addresses[idx] = val; | |||
} |
@@ -29,19 +29,31 @@ | |||
#define STORAGESOA_H | |||
#include <vector> | |||
#include <list> | |||
#include <map> | |||
namespace llvm { | |||
class BasicBlock; | |||
class Constant; | |||
class ConstantInt; | |||
class GlobalVariable; | |||
class LoadInst; | |||
class Value; | |||
class VectorType; | |||
class Module; | |||
} | |||
class StorageSoa | |||
{ | |||
public: | |||
enum Argument { | |||
Input, | |||
Output, | |||
Temp, | |||
Const, | |||
Immediate, | |||
Address | |||
}; | |||
public: | |||
StorageSoa(llvm::BasicBlock *block, | |||
llvm::Value *input, | |||
@@ -49,31 +61,35 @@ public: | |||
llvm::Value *consts, | |||
llvm::Value *temps); | |||
void addImmediate(float *vec); | |||
llvm::Value * addrElement(int idx) const; | |||
std::vector<llvm::Value*> load(Argument type, int idx, int swizzle, | |||
llvm::Value *indIdx =0); | |||
void store(Argument type, int idx, const std::vector<llvm::Value*> &val, | |||
int mask); | |||
std::vector<llvm::Value*> inputElement(int idx, int swizzle, llvm::Value *indIdx =0); | |||
std::vector<llvm::Value*> constElement(int idx, int swizzle, llvm::Value *indIdx =0); | |||
std::vector<llvm::Value*> outputElement(int idx, int swizzle, llvm::Value *indIdx =0); | |||
std::vector<llvm::Value*> tempElement(int idx, int swizzle, llvm::Value *indIdx =0); | |||
std::vector<llvm::Value*> immediateElement(int idx, int swizzle); | |||
void addImmediate(float *vec); | |||
void declareImmediates(); | |||
void addAddress(int idx); | |||
llvm::Value *extractIndex(llvm::Value *vec); | |||
llvm::Value * addrElement(int idx) const; | |||
void storeOutput(int dstIdx, const std::vector<llvm::Value*> &val, | |||
int mask); | |||
void storeTemp(int idx, const std::vector<llvm::Value*> &val, | |||
int mask); | |||
void storeAddress(int idx, const std::vector<llvm::Value*> &val, | |||
int mask); | |||
llvm::ConstantInt *constantInt(int) const; | |||
private: | |||
llvm::Value *elementPointer(llvm::Value *ptr, int index, | |||
llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, | |||
int channel) const; | |||
llvm::Value *element(llvm::Value *ptr, int index, | |||
llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, | |||
int channel) const; | |||
const char *name(const char *prefix) const; | |||
llvm::ConstantInt *constantInt(int) const; | |||
llvm::Value *alignedArrayLoad(llvm::Value *val); | |||
llvm::Module *currentModule() const; | |||
llvm::Constant *createConstGlobalVector(const std::vector<float> &vec); | |||
std::vector<llvm::Value*> inputElement(llvm::Value *indIdx); | |||
std::vector<llvm::Value*> constElement(llvm::Value *indIdx); | |||
std::vector<llvm::Value*> outputElement(llvm::Value *indIdx); | |||
std::vector<llvm::Value*> tempElement(llvm::Value *indIdx); | |||
std::vector<llvm::Value*> immediateElement(llvm::Value *indIdx); | |||
private: | |||
llvm::BasicBlock *m_block; | |||
@@ -81,6 +97,11 @@ private: | |||
llvm::Value *m_output; | |||
llvm::Value *m_consts; | |||
llvm::Value *m_temps; | |||
llvm::GlobalVariable *m_immediates; | |||
std::map<int, llvm::Value*> m_addresses; | |||
std::vector<std::vector<float> > m_immediatesToFlush; | |||
mutable std::map<int, llvm::ConstantInt*> m_constInts; | |||
mutable char m_name[32]; |
@@ -10,11 +10,11 @@ | |||
#include "pipe/p_shader_tokens.h" | |||
#include "pipe/tgsi/util/tgsi_parse.h" | |||
#include "pipe/tgsi/exec/tgsi_exec.h" | |||
#include "pipe/tgsi/util/tgsi_util.h" | |||
#include "pipe/tgsi/util/tgsi_build.h" | |||
#include "pipe/tgsi/util/tgsi_dump.h" | |||
#include "tgsi/util/tgsi_parse.h" | |||
#include "tgsi/exec/tgsi_exec.h" | |||
#include "tgsi/util/tgsi_util.h" | |||
#include "tgsi/util/tgsi_build.h" | |||
#include "tgsi/util/tgsi_dump.h" | |||
#include <llvm/Module.h> | |||
@@ -44,7 +44,6 @@ | |||
#include <iostream> | |||
using namespace llvm; | |||
#include "llvm_base_shader.cpp" | |||
static inline FunctionType *vertexShaderFunctionType() | |||
{ | |||
@@ -149,10 +148,14 @@ translate_declaration(struct gallivm_ir *prog, | |||
static void | |||
translate_declarationir(struct gallivm_ir *, | |||
llvm::Module *, | |||
StorageSoa *, | |||
struct tgsi_full_declaration *, | |||
StorageSoa *storage, | |||
struct tgsi_full_declaration *decl, | |||
struct tgsi_full_declaration *) | |||
{ | |||
if (decl->Declaration.File == TGSI_FILE_ADDRESS) { | |||
int idx = decl->u.DeclarationRange.First; | |||
storage->addAddress(idx); | |||
} | |||
} | |||
static void | |||
@@ -704,18 +707,22 @@ translate_instructionir(llvm::Module *module, | |||
if (src->SrcRegister.Indirect) { | |||
indIdx = storage->addrElement(src->SrcRegisterInd.Index); | |||
indIdx = storage->extractIndex(indIdx); | |||
} | |||
if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { | |||
val = storage->constElement(src->SrcRegister.Index, swizzle, indIdx); | |||
val = storage->load(StorageSoa::Const, | |||
src->SrcRegister.Index, swizzle, indIdx); | |||
} else if (src->SrcRegister.File == TGSI_FILE_INPUT) { | |||
val = storage->inputElement(src->SrcRegister.Index, swizzle, indIdx); | |||
val = storage->load(StorageSoa::Input, | |||
src->SrcRegister.Index, swizzle, indIdx); | |||
} else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { | |||
val = storage->tempElement(src->SrcRegister.Index, swizzle); | |||
val = storage->load(StorageSoa::Temp, | |||
src->SrcRegister.Index, swizzle, indIdx); | |||
} else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { | |||
val = storage->outputElement(src->SrcRegister.Index, swizzle, indIdx); | |||
val = storage->load(StorageSoa::Output, | |||
src->SrcRegister.Index, swizzle, indIdx); | |||
} else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { | |||
val = storage->immediateElement(src->SrcRegister.Index, swizzle); | |||
val = storage->load(StorageSoa::Immediate, | |||
src->SrcRegister.Index, swizzle, indIdx); | |||
} else { | |||
fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); | |||
return; | |||
@@ -727,6 +734,7 @@ translate_instructionir(llvm::Module *module, | |||
std::vector<llvm::Value*> out(4); | |||
switch (inst->Instruction.Opcode) { | |||
case TGSI_OPCODE_ARL: { | |||
out = instr->arl(inputs[0]); | |||
} | |||
break; | |||
case TGSI_OPCODE_MOV: { | |||
@@ -776,6 +784,7 @@ translate_instructionir(llvm::Module *module, | |||
} | |||
break; | |||
case TGSI_OPCODE_MAD: { | |||
out = instr->madd(inputs[0], inputs[1], inputs[2]); | |||
} | |||
break; | |||
case TGSI_OPCODE_SUB: { | |||
@@ -1059,11 +1068,14 @@ translate_instructionir(llvm::Module *module, | |||
struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; | |||
if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { | |||
storage->storeOutput(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); | |||
storage->store(StorageSoa::Output, | |||
dst->DstRegister.Index, out, dst->DstRegister.WriteMask); | |||
} else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { | |||
storage->storeTemp(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); | |||
storage->store(StorageSoa::Temp, | |||
dst->DstRegister.Index, out, dst->DstRegister.WriteMask); | |||
} else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { | |||
storage->storeAddress(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); | |||
storage->store(StorageSoa::Address, | |||
dst->DstRegister.Index, out, dst->DstRegister.WriteMask); | |||
} else { | |||
fprintf(stderr, "ERROR: unsupported LLVM destination!"); | |||
assert(!"wrong destination"); | |||
@@ -1074,7 +1086,7 @@ translate_instructionir(llvm::Module *module, | |||
llvm::Module * | |||
tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) | |||
{ | |||
llvm::Module *mod = createBaseShader(); | |||
llvm::Module *mod = new Module("shader"); | |||
struct tgsi_parse_context parse; | |||
struct tgsi_full_instruction fi; | |||
struct tgsi_full_declaration fd; | |||
@@ -1191,6 +1203,7 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, | |||
break; | |||
case TGSI_TOKEN_TYPE_INSTRUCTION: | |||
storage.declareImmediates(); | |||
translate_instructionir(mod, &storage, &instr, | |||
&parse.FullToken.FullInstruction, | |||
&fi, instno); |
@@ -17,7 +17,7 @@ C_SOURCES = \ | |||
ASM_SOURCES = | |||
include ../Makefile.template | |||
include ../../Makefile.template | |||
symlinks: | |||
@@ -110,7 +110,7 @@ pb_malloc_buffer_create(size_t size, | |||
buf = CALLOC_STRUCT(malloc_buffer); | |||
if(!buf) | |||
return NULL; | |||
buf->base.base.refcount = 1; | |||
buf->base.base.alignment = desc->alignment; | |||
buf->base.base.usage = desc->usage; | |||
@@ -119,7 +119,7 @@ pb_malloc_buffer_create(size_t size, | |||
buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment); | |||
if(!buf->data) { | |||
FREE(buf); | |||
align_free(buf); | |||
return NULL; | |||
} | |||
@@ -54,8 +54,8 @@ | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "pipe/tgsi/util/tgsi_parse.h" | |||
#include "pipe/tgsi/util/tgsi_util.h" | |||
#include "tgsi/util/tgsi_parse.h" | |||
#include "tgsi/util/tgsi_util.h" | |||
#include "tgsi_exec.h" | |||
#define TILE_TOP_LEFT 0 | |||
@@ -176,13 +176,13 @@ tgsi_exec_machine_bind_shader( | |||
if (numDeclarations == maxDeclarations) { | |||
declarations = REALLOC(declarations, | |||
maxDeclarations | |||
* sizeof(struct tgsi_full_instruction), | |||
* sizeof(struct tgsi_full_declaration), | |||
(maxDeclarations + 10) | |||
* sizeof(struct tgsi_full_instruction)); | |||
* sizeof(struct tgsi_full_declaration)); | |||
maxDeclarations += 10; | |||
} | |||
memcpy(declarations + numDeclarations, | |||
&parse.FullToken.FullInstruction, | |||
&parse.FullToken.FullDeclaration, | |||
sizeof(declarations[0])); | |||
numDeclarations++; | |||
break; | |||
@@ -1337,9 +1337,12 @@ exec_tex(struct tgsi_exec_machine *mach, | |||
} | |||
/** | |||
* Evaluate a constant-valued coefficient at the position of the | |||
* current quad. | |||
*/ | |||
static void | |||
constant_interpolation( | |||
eval_constant_coef( | |||
struct tgsi_exec_machine *mach, | |||
unsigned attrib, | |||
unsigned chan ) | |||
@@ -1351,8 +1354,12 @@ constant_interpolation( | |||
} | |||
} | |||
/** | |||
* Evaluate a linear-valued coefficient at the position of the | |||
* current quad. | |||
*/ | |||
static void | |||
linear_interpolation( | |||
eval_linear_coef( | |||
struct tgsi_exec_machine *mach, | |||
unsigned attrib, | |||
unsigned chan ) | |||
@@ -1368,8 +1375,12 @@ linear_interpolation( | |||
mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; | |||
} | |||
/** | |||
* Evaluate a perspective-valued coefficient at the position of the | |||
* current quad. | |||
*/ | |||
static void | |||
perspective_interpolation( | |||
eval_perspective_coef( | |||
struct tgsi_exec_machine *mach, | |||
unsigned attrib, | |||
unsigned chan ) | |||
@@ -1388,7 +1399,7 @@ perspective_interpolation( | |||
} | |||
typedef void (* interpolation_func)( | |||
typedef void (* eval_coef_func)( | |||
struct tgsi_exec_machine *mach, | |||
unsigned attrib, | |||
unsigned chan ); | |||
@@ -1401,7 +1412,7 @@ exec_declaration( | |||
if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { | |||
if( decl->Declaration.File == TGSI_FILE_INPUT ) { | |||
unsigned first, last, mask; | |||
interpolation_func interp; | |||
eval_coef_func eval; | |||
assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); | |||
@@ -1411,15 +1422,15 @@ exec_declaration( | |||
switch( decl->Interpolation.Interpolate ) { | |||
case TGSI_INTERPOLATE_CONSTANT: | |||
interp = constant_interpolation; | |||
eval = eval_constant_coef; | |||
break; | |||
case TGSI_INTERPOLATE_LINEAR: | |||
interp = linear_interpolation; | |||
eval = eval_linear_coef; | |||
break; | |||
case TGSI_INTERPOLATE_PERSPECTIVE: | |||
interp = perspective_interpolation; | |||
eval = eval_perspective_coef; | |||
break; | |||
default: | |||
@@ -1431,7 +1442,7 @@ exec_declaration( | |||
for( i = first; i <= last; i++ ) { | |||
for( j = 0; j < NUM_CHANNELS; j++ ) { | |||
interp( mach, i, j ); | |||
eval( mach, i, j ); | |||
} | |||
} | |||
} | |||
@@ -1441,7 +1452,7 @@ exec_declaration( | |||
for( j = 0; j < NUM_CHANNELS; j++ ) { | |||
if( mask & (1 << j) ) { | |||
for( i = first; i <= last; i++ ) { | |||
interp( mach, i, j ); | |||
eval( mach, i, j ); | |||
} | |||
} | |||
} |
@@ -27,8 +27,8 @@ | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "pipe/tgsi/util/tgsi_parse.h" | |||
#include "pipe/tgsi/util/tgsi_util.h" | |||
#include "tgsi/util/tgsi_parse.h" | |||
#include "tgsi/util/tgsi_util.h" | |||
#include "tgsi_exec.h" | |||
#include "tgsi_sse2.h" | |||
@@ -0,0 +1,199 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
/** | |||
* TGSI program transformation utility. | |||
* | |||
* Authors: Brian Paul | |||
*/ | |||
#include "tgsi_transform.h" | |||
static void | |||
emit_instruction(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_instruction *inst) | |||
{ | |||
uint ti = ctx->ti; | |||
ti += tgsi_build_full_instruction(inst, | |||
ctx->tokens_out + ti, | |||
ctx->header, | |||
ctx->max_tokens_out - ti); | |||
ctx->ti = ti; | |||
} | |||
static void | |||
emit_declaration(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_declaration *decl) | |||
{ | |||
uint ti = ctx->ti; | |||
ti += tgsi_build_full_declaration(decl, | |||
ctx->tokens_out + ti, | |||
ctx->header, | |||
ctx->max_tokens_out - ti); | |||
ctx->ti = ti; | |||
} | |||
static void | |||
emit_immediate(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_immediate *imm) | |||
{ | |||
uint ti = ctx->ti; | |||
ti += tgsi_build_full_immediate(imm, | |||
ctx->tokens_out + ti, | |||
ctx->header, | |||
ctx->max_tokens_out - ti); | |||
ctx->ti = ti; | |||
} | |||
/** | |||
* Apply user-defined transformations to the input shader to produce | |||
* the output shader. | |||
* For example, a register search-and-replace operation could be applied | |||
* by defining a transform_instruction() callback that examined and changed | |||
* the instruction src/dest regs. | |||
* | |||
* \return number of tokens emitted | |||
*/ | |||
int | |||
tgsi_transform_shader(const struct tgsi_token *tokens_in, | |||
struct tgsi_token *tokens_out, | |||
uint max_tokens_out, | |||
struct tgsi_transform_context *ctx) | |||
{ | |||
uint procType; | |||
/* input shader */ | |||
struct tgsi_parse_context parse; | |||
/* output shader */ | |||
struct tgsi_processor *processor; | |||
/** | |||
** callback context init | |||
**/ | |||
ctx->emit_instruction = emit_instruction; | |||
ctx->emit_declaration = emit_declaration; | |||
ctx->emit_immediate = emit_immediate; | |||
ctx->tokens_out = tokens_out; | |||
ctx->max_tokens_out = max_tokens_out; | |||
/** | |||
** Setup to begin parsing input shader | |||
**/ | |||
if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { | |||
debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); | |||
return -1; | |||
} | |||
procType = parse.FullHeader.Processor.Processor; | |||
assert(procType == TGSI_PROCESSOR_FRAGMENT || | |||
procType == TGSI_PROCESSOR_VERTEX || | |||
procType == TGSI_PROCESSOR_GEOMETRY); | |||
/** | |||
** Setup output shader | |||
**/ | |||
*(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); | |||
ctx->header = (struct tgsi_header *) (tokens_out + 1); | |||
*ctx->header = tgsi_build_header(); | |||
processor = (struct tgsi_processor *) (tokens_out + 2); | |||
*processor = tgsi_build_processor( procType, ctx->header ); | |||
ctx->ti = 3; | |||
/** | |||
** Loop over incoming program tokens/instructions | |||
*/ | |||
while( !tgsi_parse_end_of_tokens( &parse ) ) { | |||
tgsi_parse_token( &parse ); | |||
switch( parse.FullToken.Token.Type ) { | |||
case TGSI_TOKEN_TYPE_INSTRUCTION: | |||
{ | |||
struct tgsi_full_instruction *fullinst | |||
= &parse.FullToken.FullInstruction; | |||
if (ctx->transform_instruction) | |||
ctx->transform_instruction(ctx, fullinst); | |||
else | |||
ctx->emit_instruction(ctx, fullinst); | |||
} | |||
break; | |||
case TGSI_TOKEN_TYPE_DECLARATION: | |||
{ | |||
struct tgsi_full_declaration *fulldecl | |||
= &parse.FullToken.FullDeclaration; | |||
if (ctx->transform_declaration) | |||
ctx->transform_declaration(ctx, fulldecl); | |||
else | |||
ctx->emit_declaration(ctx, fulldecl); | |||
} | |||
break; | |||
case TGSI_TOKEN_TYPE_IMMEDIATE: | |||
{ | |||
struct tgsi_full_immediate *fullimm | |||
= &parse.FullToken.FullImmediate; | |||
if (ctx->transform_immediate) | |||
ctx->transform_immediate(ctx, fullimm); | |||
else | |||
ctx->emit_immediate(ctx, fullimm); | |||
} | |||
break; | |||
default: | |||
assert( 0 ); | |||
} | |||
} | |||
if (ctx->epilog) { | |||
ctx->epilog(ctx); | |||
} | |||
tgsi_parse_free (&parse); | |||
return ctx->ti; | |||
} |
@@ -0,0 +1,93 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
#ifndef TGSI_TRANSFORM_H | |||
#define TGSI_TRANSFORM_H | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "tgsi/util/tgsi_parse.h" | |||
#include "tgsi/util/tgsi_build.h" | |||
/** | |||
* Subclass this to add caller-specific data | |||
*/ | |||
struct tgsi_transform_context | |||
{ | |||
/**** PUBLIC ***/ | |||
/** | |||
* User-defined callbacks invoked per instruction. | |||
*/ | |||
void (*transform_instruction)(struct tgsi_transform_context *ctx, | |||
struct tgsi_full_instruction *inst); | |||
void (*transform_declaration)(struct tgsi_transform_context *ctx, | |||
struct tgsi_full_declaration *decl); | |||
void (*transform_immediate)(struct tgsi_transform_context *ctx, | |||
struct tgsi_full_immediate *imm); | |||
/** | |||
* Called at end of input program to allow caller to append extra | |||
* instructions. Return number of tokens emitted. | |||
*/ | |||
void (*epilog)(struct tgsi_transform_context *ctx); | |||
/*** PRIVATE ***/ | |||
/** | |||
* These are setup by tgsi_transform_shader() and cannot be overridden. | |||
* Meant to be called from in the above user callback functions. | |||
*/ | |||
void (*emit_instruction)(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_instruction *inst); | |||
void (*emit_declaration)(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_declaration *decl); | |||
void (*emit_immediate)(struct tgsi_transform_context *ctx, | |||
const struct tgsi_full_immediate *imm); | |||
struct tgsi_header *header; | |||
uint max_tokens_out; | |||
struct tgsi_token *tokens_out; | |||
uint ti; | |||
}; | |||
extern int | |||
tgsi_transform_shader(const struct tgsi_token *tokens_in, | |||
struct tgsi_token *tokens_out, | |||
uint max_tokens_out, | |||
struct tgsi_transform_context *ctx); | |||
#endif /* TGSI_TRANSFORM_H */ |