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