The galliumtri demo is a significantly enhanced Gallium version of tri.
By default it works like the tri, but the triangle size oscillates and the 
fragment shader from sge2.txt.
It can also be configured to behave exactly like tri, like clear or it can load 
arbitrary vertex, fragment and geometry shaders (totally untested).
---
 src/gallium/programs/demos/Makefile        |    8 +-
 src/gallium/programs/demos/galliumtri.c    |  250 ++++++++++++++++++++++++++++
 src/gallium/programs/galliumut/galliumut.h |   65 +++++++
 3 files changed, 320 insertions(+), 3 deletions(-)
 create mode 100644 src/gallium/programs/demos/galliumtri.c

diff --git a/src/gallium/programs/demos/Makefile 
b/src/gallium/programs/demos/Makefile
index 1623815..e1fba0e 100644
--- a/src/gallium/programs/demos/Makefile
+++ b/src/gallium/programs/demos/Makefile
@@ -2,7 +2,6 @@ TOP = ../../../..
 include $(TOP)/configs/current
 
 LIBRARY_INCLUDES = -I../galliumut
-#$(shell pkg-config gdk-pixbuf-2.0 --cflags)
 LIBRARY_DEFINES = --std=gnu99
 
 default: programs
@@ -16,9 +15,9 @@ lib.a:
 GALLIUM_LIBS = ../galliumut/libgalliumut.a 
$(TOP)/src/gallium/auxiliary/util/libutil.a 
$(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a 
$(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a
 LIBS = -L$(TOP)/$(LIB_DIR) -lEGL -lGL
 
-C_SOURCES = galliumgears.c galliumglobe.c galliumsync.c
+C_SOURCES = galliumgears.c galliumglobe.c galliumtri.c
 
-PROGRAMS = galliumgears galliumglobe
+PROGRAMS = galliumgears galliumglobe galliumtri
 
 programs: $(PROGRAMS)
 
@@ -27,3 +26,6 @@ galliumgears: galliumgears.o $(HEADERS) $(LIB_DEP) 
$(GALLIUM_LIBS)
 
 galliumglobe: galliumglobe.o $(HEADERS) $(LIB_DEP) $(GALLIUM_LIBS)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(GALLIUM_LIBS) $(shell 
pkg-config gdk-pixbuf-2.0 --libs)
+
+galliumtri: galliumtri.o $(HEADERS) $(LIB_DEP) $(GALLIUM_LIBS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(GALLIUM_LIBS)
diff --git a/src/gallium/programs/demos/galliumtri.c 
b/src/gallium/programs/demos/galliumtri.c
new file mode 100644
index 0000000..c85ca4a
--- /dev/null
+++ b/src/gallium/programs/demos/galliumtri.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2009       Luca Barbieri  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
+ * LUCA BARBIERI 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 "galliumut.h"
+#include "math_lib.h"
+#include "uureg.h"
+
+int draw_tri = 1;
+int bypass = 0;
+int gpu = 1;
+float speed = 1.0f;
+float clear_color[4] = {0.3, 0.1, 0.3, 1.0};
+struct mesh* tri;
+const char* vs_file;
+const char* gs_file;
+const char* fs_file;
+int use_sge2_fs = 1;
+
+struct tri_vs
+{
+       vecf scale;
+       vecf translate;
+};
+
+static void* create_tri_vs(struct pipe_context* ctx)
+{
+       _VERT;
+
+       _VS_INPUT(in_coord, 0);
+       _VS_INPUT(in_color, 1);
+       _OUTPUT(out_position, POSITION, 0);
+       _OUTPUT(out_color, COLOR, 0);
+
+       _CONST(scale, struct tri_vs);
+       _CONST(translate, struct tri_vs);
+
+       _MOV(out_color, in_color);
+       _MAD(out_position, in_coord, scale, translate);
+
+       return _END_SHADER(ctx);
+}
+
+static void* create_sge2_fs(struct pipe_context* ctx)
+{
+       _FRAG;
+
+       _FS_INPUT(in_color, COLOR, 0, LINEAR);
+       _OUTPUT(out_color, COLOR, 0);
+
+       _TEMP(r0);
+       _TEMP(r1);
+
+       _SGE(r0, in_color, _yzxw(in_color));
+       _SGE(r1, in_color, _zxyw(in_color));
+       _MUL(r0, r0, r1);
+       _MUL(out_color, r0, in_color);
+
+       return _END_SHADER(ctx);
+}
+
+static struct mesh* build_tri(struct pipe_screen* screen, int gpu, float x, 
float y, float w, float h)
+{
+       float* p;
+       struct mesh* mesh = mesh_new(screen, gpu, 2, 3 * sizeof(float), -1, 3, 
0, &p, 0);
+       mesh->mode = PIPE_PRIM_TRIANGLES;
+       mesh->elem[0].vertex_buffer_index = 0;
+       mesh->elem[0].nr_components = 2;
+       mesh->elem[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+       mesh->elem[0].src_offset = 0;
+       mesh->elem[1].vertex_buffer_index = 0;
+       mesh->elem[1].nr_components = 4;
+       mesh->elem[1].src_format = PIPE_FORMAT_R8G8B8A8_UNORM;
+       mesh->elem[1].src_offset = 2 * sizeof(float);
+
+       *p++ = x + 0.05f * w;
+       *p++ = y + 0.95f * h;
+       ((unsigned char*)p)[0] = 0.8 *  255;
+       ((unsigned char*)p)[1] = 0;
+       ((unsigned char*)p)[2] = 0;
+       ((unsigned char*)p)[3] = 255;
+       ++p;
+
+       *p++ = x + 0.95f * w;
+       *p++ = y + 0.95f * h;
+       ((unsigned char*)p)[0] = 0;
+       ((unsigned char*)p)[1] = 0.9 * 255;
+       ((unsigned char*)p)[2] = 0;
+       ((unsigned char*)p)[3] = 255;
+       ++p;
+
+       *p++ = x + 0.5f * w;
+       *p++ = y + 0.05f * h;
+       ((unsigned char*)p)[0] = 0;
+       ((unsigned char*)p)[1] = 0;
+       ((unsigned char*)p)[2] = 0.7 *  255;
+       ((unsigned char*)p)[3] = 255;
+       ++p;
+
+       return mesh_complete(mesh);
+}
+
+static int
+draw(struct pipe_context* ctx, struct pipe_framebuffer_state* fb, double time)
+{
+       float size = (cos(time * speed) + 1.0) / 2.0;
+
+       if(!bypass)
+               framebuffer_set_with_viewport(ctx, fb);
+       else
+               ctx->set_framebuffer_state(ctx, fb);
+
+       ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 1.0, 0);
+
+       if(!draw_tri)
+               return 0;
+
+       if(!bypass)
+       {
+               struct pipe_constant_buffer vcb;
+               struct tri_vs* vc = cbuf_begin(ctx->screen, &vcb, sizeof(struct 
tri_vs));
+               vc->scale = vec4f_set(size, size, 0.0, 1.0);
+               vc->translate = vec4f_set(0.0, 0.0, 0.0, 0.0);
+               cbuf_end_vs(ctx, &vcb);
+
+               mesh_draw_bound(ctx, tri);
+       }
+       else
+       {
+               tri = build_tri(ctx->screen, 1, (1.0 - size) * 0.5 * fb->width, 
(1.0 - size) * 0.5 * fb->height, fb->width * size, fb->height * size);
+               mesh_draw(ctx, tri);
+               mesh_free(tri);
+       }
+
+       return 0;
+}
+
+static void
+init(struct pipe_context* ctx)
+{
+       if(!draw_tri)
+               return;
+
+       ctx->bind_depth_stencil_alpha_state(ctx, 
create_no_depth_stencil_alpha(ctx));
+       ctx->bind_rasterizer_state(ctx, bypass ? create_bypass_rasterizer(ctx) 
: create_default_rasterizer(ctx));
+       ctx->bind_blend_state(ctx, create_no_blend(ctx));
+
+       void* vs;
+       if(vs_file)
+               vs = load_vs(ctx, vs_file);
+       else if(!bypass)
+               vs = create_tri_vs(ctx);
+       else
+       {
+               unsigned semantic_names[2] = {TGSI_SEMANTIC_POSITION, 
TGSI_SEMANTIC_COLOR};
+               unsigned semantic_indexes[2] = {0, 0};
+               vs = util_make_vertex_passthrough_shader(ctx, 2, 
semantic_names, semantic_indexes);
+       }
+       ctx->bind_vs_state(ctx, vs);
+
+       void* gs = 0;
+       if(gs_file)
+               gs = load_gs(ctx, gs_file);
+       if(gs)
+               ctx->bind_gs_state(ctx, gs);
+
+       void* fs;
+       if(fs_file)
+               fs = load_fs(ctx, fs_file);
+       else if(use_sge2_fs)
+               fs = create_sge2_fs(ctx);
+       else
+               fs = util_make_fragment_clonecolor_shader(ctx, 1);
+       ctx->bind_fs_state(ctx, fs);
+
+       if(!bypass)
+       {
+               tri = build_tri(ctx->screen, 1, -1, -1, 2, 2);
+               mesh_bind(ctx, tri);
+       }
+}
+
+int
+main(int argc, char *argv[])
+{
+       for(char** p = argv + 1; *p; ++p)
+       {
+               if(!strcmp(*p, "-b"))
+                       bypass = 1;
+               else if(!strcmp(*p, "-c"))
+               {
+                       clear_color[0] = atof(*++p);
+                       clear_color[1] = atof(*++p);
+                       clear_color[2] = atof(*++p);
+                       clear_color[3] = atof(*++p);
+               }
+               else if(!strcmp(*p, "-f"))
+                       fs_file = *++p;
+               else if(!strcmp(*p, "-g"))
+                       gs_file = *++p;
+               else if(!strcmp(*p, "-n"))
+                       draw_tri = 0;
+               else if(!strcmp(*p, "-s"))
+                       speed = atof(*++p);
+               else if(!strcmp(*p, "-t"))
+                       use_sge2_fs = 0;
+               else if(!strcmp(*p, "-u"))
+                       gpu = 0;
+               else if(!strcmp(*p, "-v"))
+                       vs_file = *++p;
+               else
+               {
+                       fprintf(stderr, "Usage: galliumtri [OPTIONS...]\n");
+                       fprintf(stderr, "galliumtri is a port of tri that 
directly uses the Mesa Gallium3D API\n");
+                       fprintf(stderr, "Use -t -s 0 to make it behave like 
tri\n");
+                       fprintf(stderr, "Use -n -c 0 0 1 0 to make it behave 
like clear\n");
+                       fprintf(stderr, "\n");
+                       fprintf(stderr, "-b\t\tbypass vertex shading, clipping 
and viewport\n");
+                       fprintf(stderr, "-c R G B A\tclear with this color 
(default is 0.3 0.1 0.3 1.0)\n");
+                       fprintf(stderr, "-f FILE\t\tload and use the fragment 
shader in FILE\n");
+                       fprintf(stderr, "-g FILE\t\tload and use the geometry 
shader in FILE\n");
+                       fprintf(stderr, "-n\t\tjust clear, don't show the 
triangle\n");
+                       fprintf(stderr, "-s SPEED\tvary the triangle size at 
this speed (default is 1)\n");
+                       fprintf(stderr, "-t\t\tuse a trivial fragment 
shader\n");
+                       fprintf(stderr, "-u\t\tput the triangle in a user 
buffer\n");
+                       fprintf(stderr, "-v FILE\t\tload and use the vertex 
shader in FILE\n");
+                       return 1;
+               }
+       }
+
+       init_and_render(init, draw, 1);
+       return 0;
+}
diff --git a/src/gallium/programs/galliumut/galliumut.h 
b/src/gallium/programs/galliumut/galliumut.h
index 603acf8..f849271 100644
--- a/src/gallium/programs/galliumut/galliumut.h
+++ b/src/gallium/programs/galliumut/galliumut.h
@@ -601,6 +601,71 @@ gen_mipmaps(struct pipe_context* ctx, struct pipe_texture* 
tex, struct mesh* qua
        draw_on_mipmaps(ctx, tex, 0, 0, PIPE_MAX_TEXTURE_LEVELS, quad, 
mipmap_samplers);
 }
 
+#include <tgsi/tgsi_text.h>
+
+static inline void*
+load_shader(struct pipe_context* ctx, const char* file, int* pprocessor)
+{
+       void* shader = 0;
+       FILE* fp = fopen(file, "r");
+       if(!fp)
+               return 0;
+       char* text = malloc(1024 * 1024);
+       int len = fread(text, 1, 1024 * 1024 - 1, fp);
+       text[len] = 0;
+       fclose(fp);
+
+       struct pipe_shader_state state;
+       struct tgsi_token* tokens = malloc(1024 * 1024 * sizeof(struct 
tgsi_token));
+       if(!tgsi_text_translate(text, tokens, 1024 * 1024))
+               goto out;
+       unsigned processor = ((struct tgsi_processor *)&tokens[1])->Processor;
+       state.tokens = tokens;
+       if(*pprocessor >= 0 && processor != *pprocessor)
+               goto out;
+       *pprocessor = processor;
+
+       if(processor == TGSI_PROCESSOR_VERTEX)
+               shader = ctx->create_vs_state(ctx, &state);
+       else if(processor == TGSI_PROCESSOR_GEOMETRY)
+               shader = ctx->create_gs_state(ctx, &state);
+       else if(processor == TGSI_PROCESSOR_FRAGMENT)
+               shader = ctx->create_fs_state(ctx, &state);
+
+out:
+       free(text);
+       free(tokens);
+       return shader;
+}
+
+static inline void*
+load_vs(struct pipe_context* ctx, const char* file)
+{
+       int processor = TGSI_PROCESSOR_VERTEX;
+       return load_shader(ctx, file, &processor);
+}
+
+static inline void*
+load_gs(struct pipe_context* ctx, const char* file)
+{
+       int processor = TGSI_PROCESSOR_GEOMETRY;
+       return load_shader(ctx, file, &processor);
+}
+
+static inline void*
+load_fs(struct pipe_context* ctx, const char* file)
+{
+       int processor = TGSI_PROCESSOR_FRAGMENT;
+       return load_shader(ctx, file, &processor);
+}
+
+static inline void*
+load_any_shader(struct pipe_context* ctx, const char* file)
+{
+       int processor = -1;
+       return load_shader(ctx, file, &processor);
+}
+
 typedef void (*init_t)(struct pipe_context*);
 typedef int (*draw_t)(struct pipe_context*, struct pipe_framebuffer_state*, 
double);
 
-- 
1.6.3.3


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to