diff options
author | Thomas Balling Sørensen <tball@tball-laptop.(none)> | 2010-10-05 12:04:08 +0200 |
---|---|---|
committer | Thomas Balling Sørensen <tball@tball-laptop.(none)> | 2010-10-05 12:04:08 +0200 |
commit | 1218430e1200a08cd64b6555d3fd1fd0274ad9e5 (patch) | |
tree | e060fb27b8388a4bd237ca39fc20f1675c5e367c /src/gallium/tests | |
parent | 63b1525cf0a50e3d31328c3b56355a86056e4c05 (diff) | |
parent | bf21b7006c63c3dc47045c22d4f372dfe6c7ce67 (diff) |
Merge branch 'master' into pipe-video
Conflicts:
configs/linux-dri
configure.ac
src/gallium/drivers/nvfx/Makefile
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_screen.h
src/gallium/include/state_tracker/dri1_api.h
src/gallium/include/state_tracker/drm_api.h
src/gallium/tests/python/samples/tri.py
src/gallium/tests/trivial/Makefile
src/gallium/tests/unit/Makefile
src/gallium/tests/unit/SConscript
src/gallium/tests/unit/u_format_test.c
src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
Diffstat (limited to 'src/gallium/tests')
61 files changed, 4039 insertions, 183 deletions
diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript new file mode 100644 index 00000000000..ffde61965b4 --- /dev/null +++ b/src/gallium/tests/graw/SConscript @@ -0,0 +1,37 @@ +Import('*') + +try: + graw +except NameError: + print 'warning: graw library not avaiable: skipping build of graw test' + Return() + +env = env.Clone() + +env.Prepend(LIBPATH = [graw.dir]) +env.Prepend(LIBS = ['graw'] + gallium) + +if platform in ('freebsd8', 'sunos5'): + env.Append(LIBS = ['m']) + +if platform == 'freebsd8': + env.Append(LIBS = ['pthread']) + +progs = [ + 'clear', + 'tri', + 'tri-instanced', + 'quad-tex', + 'fs-test', + 'vs-test', + 'gs-test', + 'shader-leak', + 'tri-gs', +] + +for prog in progs: + env.Program( + target = prog, + source = prog + '.c', + ) + diff --git a/src/gallium/tests/raw/clear.c b/src/gallium/tests/graw/clear.c index 706e3be3728..ce52a93aa1b 100644 --- a/src/gallium/tests/raw/clear.c +++ b/src/gallium/tests/graw/clear.c @@ -7,7 +7,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include <unistd.h> /* for sleep() */ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ @@ -20,33 +19,58 @@ enum pipe_format formats[] = { static const int WIDTH = 300; static const int HEIGHT = 300; -int main( int argc, char *argv[] ) +struct pipe_screen *screen; +struct pipe_context *ctx; +struct pipe_surface *surf; +static void *window = NULL; + +static void draw( void ) { - struct pipe_screen *screen; - struct pipe_context *pipe; - struct pipe_surface *surf; - struct pipe_framebuffer_state fb; - struct pipe_texture *tex, templat; - void *window = NULL; float clear_color[4] = {1,0,1,1}; - int i; - screen = graw_init(); - if (screen == NULL) - exit(1); + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource *tex, templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ for (i = 0; window == NULL && formats[i] != PIPE_FORMAT_NONE; i++) { - window = graw_create_window(0,0,300,300, formats[i]); + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); } - if (window == NULL) exit(2); - pipe = screen->context_create(screen, NULL); - if (pipe == NULL) + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) exit(3); templat.target = PIPE_TEXTURE_2D; @@ -57,10 +81,10 @@ int main( int argc, char *argv[] ) templat.last_level = 0; templat.nr_samples = 1; templat.bind = (PIPE_BIND_RENDER_TARGET | - PIPE_BIND_DISPLAY_TARGET); + PIPE_BIND_DISPLAY_TARGET); tex = screen->resource_create(screen, - &templat); + &templat); if (tex == NULL) exit(4); @@ -76,20 +100,16 @@ int main( int argc, char *argv[] ) fb.height = HEIGHT; fb.cbufs[0] = surf; - pipe->set_framebuffer_state(pipe, &fb); - pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0); - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->set_framebuffer_state(ctx, &fb); +} - /* At the moment, libgraw includes/makes available all the symbols - * from gallium/auxiliary, including these debug helpers. Will - * eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - */ - if (0) - debug_dump_surface_bmp(pipe, "result.bmp", surf); - screen->flush_frontbuffer(screen, surf, window); - sleep(100); +int main( int argc, char *argv[] ) +{ + init(); + + graw_set_display_func( draw ); + graw_main_loop(); return 0; } diff --git a/src/gallium/tests/graw/fragment-shader b/src/gallium/tests/graw/fragment-shader new file mode 120000 index 00000000000..c7dd0b7c6b2 --- /dev/null +++ b/src/gallium/tests/graw/fragment-shader @@ -0,0 +1 @@ +../python/tests/regress/fragment-shader
\ No newline at end of file diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c new file mode 100644 index 00000000000..53fbb744d86 --- /dev/null +++ b/src/gallium/tests/graw/fs-test.c @@ -0,0 +1,556 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include <stdio.h> /* for fread(), etc */ + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_inlines.h" +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" +#include "util/u_box.h" + +static const char *filename = NULL; +unsigned show_fps = 0; + + +static void usage(char *name) +{ + fprintf(stderr, "usage: %s [ options ] shader_filename\n", name); +#ifndef WIN32 + fprintf(stderr, "\n" ); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -fps show frames per second\n"); +#endif +} + + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 250; +static const int HEIGHT = 250; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_resource *rttex = NULL; +static struct pipe_resource *constbuf1 = NULL; +static struct pipe_resource *constbuf2 = NULL; +static struct pipe_surface *surf = NULL; +static struct pipe_sampler_view *sv = NULL; +static void *sampler = NULL; +static void *window = NULL; +static struct pipe_resource *samptex = NULL; + +struct vertex { + float position[4]; + float color[4]; + float texcoord[4]; +}; + +/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension + * so that the final images are the same. + */ +static struct vertex vertices[] = +{ + { { 0.9, 0.9, 0.0, 1.0 }, + { 0, 0, 1, 1 }, + { 1, 1, 0, 1 } }, + + { { 0.9, -0.9, 0.0, 1.0 }, + { 1, 0, 0, 1 }, + { 1, -1, 0, 1 } }, + + { {-0.9, 0.0, 0.0, 1.0 }, + { 0, 1, 0, 1 }, + { -1, 0, 0, 1 } }, +}; + +static float constants1[] = +{ 0.4, 0, 0, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + 4, 8, 16, 32, + + 3, 0, 0, 0, + 0, .5, 0, 0, + 1, 0, 0, 1, + 0, 0, 0, 1, + + 1, 0, 0, 0.5, + 0, 1, 0, 0.5, + 0, 0, 1, 0, + 0, 0, 0, 1, +}; + + +static float constants2[] = +{ 1, 0, 0, 1, + 0, 1, 0, 1, + 0, 0, 1, 1, + 0, 0, 0, 0, + + 1, 1, 0, 1, + 1, .5, 0, 1, + 1, 0, 0, 1, + 0, 0, 0, 1, + + 1, 0, 0, 0.5, + 0, 1, 0, 0.5, + 0, 0, 1, 0, + 0, 0, 0, 1, +}; + +static void init_fs_constbuf( void ) +{ + struct pipe_resource templat; + struct pipe_box box; + + templat.target = PIPE_BUFFER; + templat.format = PIPE_FORMAT_R8_UNORM; + templat.width0 = sizeof(constants1); + templat.height0 = 1; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_CONSTANT_BUFFER; + + constbuf1 = screen->resource_create(screen, + &templat); + if (constbuf1 == NULL) + exit(4); + + constbuf2 = screen->resource_create(screen, + &templat); + if (constbuf2 == NULL) + exit(4); + + + { + u_box_2d(0,0,sizeof(constants1),1, &box); + + ctx->transfer_inline_write(ctx, + constbuf1, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + constants1, + sizeof constants1, + sizeof constants1); + + + ctx->set_constant_buffer(ctx, + PIPE_SHADER_FRAGMENT, 0, + constbuf1); + } + { + u_box_2d(0,0,sizeof(constants2),1, &box); + + ctx->transfer_inline_write(ctx, + constbuf2, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + constants2, + sizeof constants2, + sizeof constants2); + + + ctx->set_constant_buffer(ctx, + PIPE_SHADER_FRAGMENT, 1, + constbuf2); + } +} + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[3]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[2].src_offset = Offset(struct vertex, texcoord); + ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 3, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + vbuf.stride = sizeof( struct vertex ); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL IN[2]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR[0]\n" + "DCL OUT[2], GENERIC[0]\n" + " MOV OUT[0], IN[0]\n" + " MOV OUT[1], IN[1]\n" + " MOV OUT[2], IN[2]\n" + " END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( const char *filename ) +{ + FILE *f; + char buf[50000]; + void *handle; + int sz; + + if ((f = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Couldn't open %s\n", filename); + exit(1); + } + + sz = fread(buf, 1, sizeof(buf), f); + if (!feof(f)) { + printf("file too long\n"); + exit(1); + } + printf("%.*s\n", sz, buf); + buf[sz] = 0; + + handle = graw_parse_fragment_shader(ctx, buf); + ctx->bind_fs_state(ctx, handle); + fclose(f); +} + + +static void draw( void ) +{ + float clear_color[4] = {.1,.3,.5,0}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + +#define SIZE 16 + +static void init_tex( void ) +{ + struct pipe_sampler_view sv_template; + struct pipe_sampler_state sampler_desc; + struct pipe_resource templat; + struct pipe_box box; + ubyte tex2d[SIZE][SIZE][4]; + int s, t; + +#if (SIZE != 2) + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + if (0) { + int x = (s ^ t) & 1; + tex2d[t][s][0] = (x) ? 0 : 63; + tex2d[t][s][1] = (x) ? 0 : 128; + tex2d[t][s][2] = 0; + tex2d[t][s][3] = 0xff; + } + else { + int x = ((s ^ t) >> 2) & 1; + tex2d[t][s][0] = s*255/(SIZE-1); + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = (x) ? 0 : 128; + tex2d[t][s][3] = 0xff; + } + } + } +#else + tex2d[0][0][0] = 0; + tex2d[0][0][1] = 255; + tex2d[0][0][2] = 255; + tex2d[0][0][3] = 0; + + tex2d[0][1][0] = 0; + tex2d[0][1][1] = 0; + tex2d[0][1][2] = 255; + tex2d[0][1][3] = 255; + + tex2d[1][0][0] = 255; + tex2d[1][0][1] = 255; + tex2d[1][0][2] = 0; + tex2d[1][0][3] = 255; + + tex2d[1][1][0] = 255; + tex2d[1][1][1] = 0; + tex2d[1][1][2] = 0; + tex2d[1][1][3] = 255; +#endif + + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; + templat.width0 = SIZE; + templat.height0 = SIZE; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_SAMPLER_VIEW; + + + samptex = screen->resource_create(screen, + &templat); + if (samptex == NULL) + exit(4); + + u_box_2d(0,0,SIZE,SIZE, &box); + + ctx->transfer_inline_write(ctx, + samptex, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + tex2d, + sizeof tex2d[0], + sizeof tex2d); + + /* Possibly read back & compare against original data: + */ + if (0) + { + struct pipe_transfer *t; + uint32_t *ptr; + t = pipe_get_transfer(ctx, samptex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_READ, + 0, 0, SIZE, SIZE); /* x, y, width, height */ + + ptr = ctx->transfer_map(ctx, t); + + if (memcmp(ptr, tex2d, sizeof tex2d) != 0) { + assert(0); + exit(9); + } + + ctx->transfer_unmap(ctx, t); + + ctx->transfer_destroy(ctx, t); + } + + memset(&sv_template, 0, sizeof sv_template); + sv_template.format = samptex->format; + sv_template.texture = samptex; + sv_template.first_level = 0; + sv_template.last_level = 0; + sv_template.swizzle_r = 0; + sv_template.swizzle_g = 1; + sv_template.swizzle_b = 2; + sv_template.swizzle_a = 3; + sv = ctx->create_sampler_view(ctx, samptex, &sv_template); + if (sv == NULL) + exit(5); + + ctx->set_fragment_sampler_views(ctx, 1, &sv); + + + memset(&sampler_desc, 0, sizeof sampler_desc); + sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler_desc.compare_func = 0; + sampler_desc.normalized_coords = 1; + sampler_desc.max_anisotropy = 0; + + sampler = ctx->create_sampler_state(ctx, &sampler_desc); + if (sampler == NULL) + exit(6); + + ctx->bind_fragment_sampler_states(ctx, 1, &sampler); + +} + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,WIDTH,HEIGHT, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + rttex = screen->resource_create(screen, + &templat); + if (rttex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, rttex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + + init_tex(); + init_fs_constbuf(); + + set_vertices(); + set_vertex_shader(); + set_fragment_shader(filename); +} + +static void args(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fps") == 0) { + show_fps = 1; + } + else if (i == argc - 1) { + filename = argv[i]; + } + else { + usage(argv[0]); + exit(1); + } + } + + if (!filename) { + usage(argv[0]); + exit(1); + } +} + +int main( int argc, char *argv[] ) +{ + args(argc,argv); + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/geometry-shader/add-mix.txt b/src/gallium/tests/graw/geometry-shader/add-mix.txt new file mode 100644 index 00000000000..63e689a5158 --- /dev/null +++ b/src/gallium/tests/graw/geometry-shader/add-mix.txt @@ -0,0 +1,23 @@ +GEOM +PROPERTY GS_INPUT_PRIMITIVE TRIANGLES +PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP +DCL IN[][0], POSITION, CONSTANT +DCL IN[][1], COLOR, CONSTANT +DCL OUT[0], POSITION, CONSTANT +DCL OUT[1], COLOR, CONSTANT + +MOV OUT[0], IN[0][0] +ADD OUT[1], IN[0][1], IN[1][1] +EMIT + +MOV OUT[0], IN[1][0] +ADD OUT[1], IN[1][1], IN[2][1] +EMIT + +MOV OUT[0], IN[2][0] +ADD OUT[1], IN[2][1], IN[0][1] +EMIT + +ENDPRIM + +END diff --git a/src/gallium/tests/graw/geometry-shader/add.txt b/src/gallium/tests/graw/geometry-shader/add.txt new file mode 100644 index 00000000000..d8c7c41e9bd --- /dev/null +++ b/src/gallium/tests/graw/geometry-shader/add.txt @@ -0,0 +1,23 @@ +GEOM +PROPERTY GS_INPUT_PRIMITIVE TRIANGLES +PROPERTY GS_OUTPUT_PRIMITIVE LINE_STRIP +DCL IN[][0], POSITION, CONSTANT +DCL IN[][1], COLOR, CONSTANT +DCL OUT[0], POSITION, CONSTANT +DCL OUT[1], COLOR, CONSTANT + +MOV OUT[0], IN[0][0] +ADD OUT[1], IN[0][1], IN[0][1] +EMIT + +MOV OUT[0], IN[1][0] +ADD OUT[1], IN[1][1], IN[1][1] +EMIT + +MOV OUT[0], IN[2][0] +ADD OUT[1], IN[2][1], IN[2][1] +EMIT + +ENDPRIM + +END diff --git a/src/gallium/tests/graw/geometry-shader/line.txt b/src/gallium/tests/graw/geometry-shader/line.txt new file mode 100644 index 00000000000..8be3f7fd985 --- /dev/null +++ b/src/gallium/tests/graw/geometry-shader/line.txt @@ -0,0 +1,28 @@ +GEOM +PROPERTY GS_INPUT_PRIMITIVE TRIANGLES +PROPERTY GS_OUTPUT_PRIMITIVE LINE_STRIP +PROPERTY GS_MAX_OUTPUT_VERTICES 4 +DCL IN[][0], POSITION, CONSTANT +DCL IN[][1], COLOR, CONSTANT +DCL OUT[0], POSITION, CONSTANT +DCL OUT[1], COLOR, CONSTANT + +MOV OUT[0], IN[0][0] +MOV OUT[1], IN[0][1] +EMIT + +MOV OUT[0], IN[1][0] +MOV OUT[1], IN[0][1] +EMIT + +MOV OUT[0], IN[2][0] +MOV OUT[1], IN[2][1] +EMIT + +MOV OUT[0], IN[0][0] +MOV OUT[1], IN[0][1] +EMIT + +ENDPRIM + +END diff --git a/src/gallium/tests/graw/geometry-shader/mov-cb-2d.txt b/src/gallium/tests/graw/geometry-shader/mov-cb-2d.txt new file mode 100644 index 00000000000..058acfbcb5a --- /dev/null +++ b/src/gallium/tests/graw/geometry-shader/mov-cb-2d.txt @@ -0,0 +1,24 @@ +GEOM +PROPERTY GS_INPUT_PRIMITIVE TRIANGLES +PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP +DCL IN[][0], POSITION, CONSTANT +DCL IN[][1], COLOR, CONSTANT +DCL OUT[0], POSITION, CONSTANT +DCL OUT[1], COLOR, CONSTANT +DCL CONST[1][0..6] + +MOV OUT[0], IN[0][0] +MOV OUT[1], CONST[1][0] +EMIT + +MOV OUT[0], IN[1][0] +MOV OUT[1], CONST[1][1] +EMIT + +MOV OUT[0], IN[2][0] +MOV OUT[1], CONST[1][4] +EMIT + +ENDPRIM + +END diff --git a/src/gallium/tests/graw/geometry-shader/mov.txt b/src/gallium/tests/graw/geometry-shader/mov.txt new file mode 100644 index 00000000000..97150a5da45 --- /dev/null +++ b/src/gallium/tests/graw/geometry-shader/mov.txt @@ -0,0 +1,23 @@ +GEOM +PROPERTY GS_INPUT_PRIMITIVE TRIANGLES +PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP +DCL IN[][0], POSITION, CONSTANT +DCL IN[][1], COLOR, CONSTANT +DCL OUT[0], POSITION, CONSTANT +DCL OUT[1], COLOR, CONSTANT + +MOV OUT[0], IN[0][0] +MOV OUT[1], IN[0][1] +EMIT + +MOV OUT[0], IN[1][0] +MOV OUT[1], IN[1][1] +EMIT + +MOV OUT[0], IN[2][0] +MOV OUT[1], IN[2][1] +EMIT + +ENDPRIM + +END diff --git a/src/gallium/tests/graw/geometry-shader/multi-line.txt b/src/gallium/tests/graw/geometry-shader/multi-line.txt new file mode 100644 index 00000000000..0762d19cdd9 --- /dev/null +++ b/src/gallium/tests/graw/geometry-shader/multi-line.txt @@ -0,0 +1,42 @@ +GEOM +PROPERTY GS_INPUT_PRIMITIVE TRIANGLES +PROPERTY GS_OUTPUT_PRIMITIVE LINE_STRIP +PROPERTY GS_MAX_OUTPUT_VERTICES 8 +DCL IN[][0], POSITION, CONSTANT +DCL IN[][1], COLOR, CONSTANT +DCL OUT[0], POSITION, CONSTANT +DCL OUT[1], COLOR, CONSTANT +DCL TEMP[0] + +MOV TEMP[0], IN[0][0] +ADD TEMP[0].y, IN[0][0], IN[1][0] + +MOV OUT[0], TEMP[0] +MOV OUT[1], IN[0][1] +EMIT +MOV OUT[0], IN[2][0] +MOV OUT[1], IN[0][1] +EMIT +MOV OUT[0], IN[0][0] +MOV OUT[1], IN[2][1] +EMIT +MOV OUT[0], TEMP[0] +MOV OUT[1], IN[0][1] +EMIT +ENDPRIM + +MOV OUT[0], TEMP[0] +MOV OUT[1], IN[0][1] +EMIT +MOV OUT[0], IN[2][0] +MOV OUT[1], IN[0][1] +EMIT +MOV OUT[0], IN[1][0] +MOV OUT[1], IN[2][1] +EMIT +MOV OUT[0], TEMP[0] +MOV OUT[1], IN[0][1] +EMIT +ENDPRIM + +END diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c new file mode 100644 index 00000000000..62714900bd9 --- /dev/null +++ b/src/gallium/tests/graw/gs-test.c @@ -0,0 +1,624 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include <stdio.h> /* for fread(), etc */ + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_inlines.h" +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" +#include "util/u_box.h" + +static const char *filename = NULL; +unsigned show_fps = 0; +unsigned draw_strip = 0; + + +static void usage(char *name) +{ + fprintf(stderr, "usage: %s [ options ] shader_filename\n", name); +#ifndef WIN32 + fprintf(stderr, "\n" ); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -fps show frames per second\n"); + fprintf(stderr, " -strip renders a triangle strip\n"); +#endif +} + + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 250; +static const int HEIGHT = 250; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_resource *rttex = NULL; +static struct pipe_resource *constbuf1 = NULL; +static struct pipe_resource *constbuf2 = NULL; +static struct pipe_surface *surf = NULL; +static struct pipe_sampler_view *sv = NULL; +static void *sampler = NULL; +static void *window = NULL; +static struct pipe_resource *samptex = NULL; + +struct vertex { + float position[4]; + float color[4]; + float texcoord[4]; + float generic[4]; +}; + +/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension + * so that the final images are the same. + */ +static struct vertex vertices[] = +{ + { { 0.9, 0.9, 0.0, 1.0 }, + { 0, 0, 1, 1 }, + { 1, 1, 0, 1 }, + { 1, 0, 1, 0 } + }, + + { { 0.9, -0.9, 0.0, 1.0 }, + { 1, 0, 0, 1 }, + { 1, -1, 0, 1 }, + { 0, 1, 0, 1 } + }, + + { {-0.9, 0.0, 0.0, 1.0 }, + { 0, 1, 0, 1 }, + { -1, 0, 0, 1 }, + { 0, 0, 1, 1 } + }, +}; + +static struct vertex vertices_strip[] = +{ + { { 0.9, 0.9, 0.0, 1.0 }, + { 0, 0, 1, 1 }, + { 1, 1, 0, 1 }, + { 1, 0, 0, 1 } + }, + + { { 0.9, -0.9, 0.0, 1.0 }, + { 1, 0, 0, 1 }, + { 1, -1, 0, 1 }, + { 0, 1, 0, 1 } + }, + + { {-0.9, 0.9, 0.0, 1.0 }, + { 0, 1, 0, 1 }, + { -1, 1, 0, 1 }, + { 0, 0, 1, 1 } + }, + + { {-0.9, -0.9, 0.0, 1.0 }, + { 1, 1, 0, 1 }, + { -1, -1, 0, 1 }, + { 1, 1, 0, 1 } + }, +}; + +static float constants1[] = +{ 0.4, 0, 0, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + 4, 8, 16, 32, + + 3, 0, 0, 0, + 0, .5, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + + 1, 0, 0, 0.5, + 0, 1, 0, 0.5, + 0, 0, 1, 0, + 0, 0, 0, 1, +}; + + +static float constants2[] = +{ 1, 0, 0, 1, + 0, 1, 0, 1, + 0, 0, 1, 1, + 0, 0, 0, 1, + + 1, 1, 0, 1, + 1, .5, 0, 1, + 0, 1, 1, 1, + 1, 0, 1, 1, + + 1, 0, 0, 0.5, + 0, 1, 0, 0.5, + 0, 0, 1, 0, + 0, 0, 0, 1, +}; + + +static void init_fs_constbuf( void ) +{ + struct pipe_resource templat; + struct pipe_box box; + + templat.target = PIPE_BUFFER; + templat.format = PIPE_FORMAT_R8_UNORM; + templat.width0 = sizeof(constants1); + templat.height0 = 1; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_CONSTANT_BUFFER; + + constbuf1 = screen->resource_create(screen, &templat); + if (constbuf1 == NULL) + exit(4); + constbuf2 = screen->resource_create(screen, &templat); + if (constbuf2 == NULL) + exit(4); + + { + u_box_2d(0,0,sizeof(constants1),1, &box); + + ctx->transfer_inline_write(ctx, + constbuf1, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + constants1, + sizeof constants1, + sizeof constants1); + + + ctx->set_constant_buffer(ctx, + PIPE_SHADER_GEOMETRY, 0, + constbuf1); + } + { + u_box_2d(0,0,sizeof(constants2),1, &box); + + ctx->transfer_inline_write(ctx, + constbuf2, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + constants2, + sizeof constants2, + sizeof constants2); + + + ctx->set_constant_buffer(ctx, + PIPE_SHADER_GEOMETRY, 1, + constbuf2); + } +} + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[4]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[2].src_offset = Offset(struct vertex, texcoord); + ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[3].src_offset = Offset(struct vertex, generic); + ve[3].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 4, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + vbuf.stride = sizeof( struct vertex ); + vbuf.buffer_offset = 0; + if (draw_strip) { + vbuf.max_index = sizeof(vertices_strip) / vbuf.stride; + vbuf.buffer = screen->user_buffer_create(screen, + vertices_strip, + sizeof(vertices_strip), + PIPE_BIND_VERTEX_BUFFER); + } else { + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + } + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL IN[2]\n" + "DCL IN[3]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR[0]\n" + "DCL OUT[2], GENERIC[0]\n" + "DCL OUT[3], GENERIC[1]\n" + " MOV OUT[0], IN[0]\n" + " MOV OUT[1], IN[1]\n" + " MOV OUT[2], IN[2]\n" + " MOV OUT[3], IN[3]\n" + " END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], COLOR, LINEAR\n" + "DCL OUT[0], COLOR\n" + " 0: MOV OUT[0], IN[0]\n" + " 1: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + +static void set_geometry_shader( void ) +{ + FILE *f; + char buf[50000]; + void *handle; + int sz; + + if ((f = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Couldn't open %s\n", filename); + exit(1); + } + + sz = fread(buf, 1, sizeof(buf), f); + if (!feof(f)) { + printf("file too long\n"); + exit(1); + } + printf("%.*s\n", sz, buf); + buf[sz] = 0; + + handle = graw_parse_geometry_shader(ctx, buf); + ctx->bind_gs_state(ctx, handle); + fclose(f); +} + + +static void draw( void ) +{ + float clear_color[4] = {.1,.3,.5,0}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + if (draw_strip) + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + else + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + +#define SIZE 16 + +static void init_tex( void ) +{ + struct pipe_sampler_view sv_template; + struct pipe_sampler_state sampler_desc; + struct pipe_resource templat; + struct pipe_box box; + ubyte tex2d[SIZE][SIZE][4]; + int s, t; + +#if (SIZE != 2) + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + if (0) { + int x = (s ^ t) & 1; + tex2d[t][s][0] = (x) ? 0 : 63; + tex2d[t][s][1] = (x) ? 0 : 128; + tex2d[t][s][2] = 0; + tex2d[t][s][3] = 0xff; + } + else { + int x = ((s ^ t) >> 2) & 1; + tex2d[t][s][0] = s*255/(SIZE-1); + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = (x) ? 0 : 128; + tex2d[t][s][3] = 0xff; + } + } + } +#else + tex2d[0][0][0] = 0; + tex2d[0][0][1] = 255; + tex2d[0][0][2] = 255; + tex2d[0][0][3] = 0; + + tex2d[0][1][0] = 0; + tex2d[0][1][1] = 0; + tex2d[0][1][2] = 255; + tex2d[0][1][3] = 255; + + tex2d[1][0][0] = 255; + tex2d[1][0][1] = 255; + tex2d[1][0][2] = 0; + tex2d[1][0][3] = 255; + + tex2d[1][1][0] = 255; + tex2d[1][1][1] = 0; + tex2d[1][1][2] = 0; + tex2d[1][1][3] = 255; +#endif + + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; + templat.width0 = SIZE; + templat.height0 = SIZE; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_SAMPLER_VIEW; + + + samptex = screen->resource_create(screen, + &templat); + if (samptex == NULL) + exit(4); + + u_box_2d(0,0,SIZE,SIZE, &box); + + ctx->transfer_inline_write(ctx, + samptex, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + tex2d, + sizeof tex2d[0], + sizeof tex2d); + + /* Possibly read back & compare against original data: + */ + if (0) + { + struct pipe_transfer *t; + uint32_t *ptr; + t = pipe_get_transfer(ctx, samptex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_READ, + 0, 0, SIZE, SIZE); /* x, y, width, height */ + + ptr = ctx->transfer_map(ctx, t); + + if (memcmp(ptr, tex2d, sizeof tex2d) != 0) { + assert(0); + exit(9); + } + + ctx->transfer_unmap(ctx, t); + + ctx->transfer_destroy(ctx, t); + } + + memset(&sv_template, 0, sizeof sv_template); + sv_template.format = samptex->format; + sv_template.texture = samptex; + sv_template.first_level = 0; + sv_template.last_level = 0; + sv_template.swizzle_r = 0; + sv_template.swizzle_g = 1; + sv_template.swizzle_b = 2; + sv_template.swizzle_a = 3; + sv = ctx->create_sampler_view(ctx, samptex, &sv_template); + if (sv == NULL) + exit(5); + + ctx->set_fragment_sampler_views(ctx, 1, &sv); + + + memset(&sampler_desc, 0, sizeof sampler_desc); + sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler_desc.compare_func = 0; + sampler_desc.normalized_coords = 1; + sampler_desc.max_anisotropy = 0; + + sampler = ctx->create_sampler_state(ctx, &sampler_desc); + if (sampler == NULL) + exit(6); + + ctx->bind_fragment_sampler_states(ctx, 1, &sampler); + +} + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,WIDTH,HEIGHT, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + rttex = screen->resource_create(screen, + &templat); + if (rttex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, rttex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + + init_tex(); + init_fs_constbuf(); + + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); + set_geometry_shader(); +} + +static void args(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fps") == 0) { + show_fps = 1; + } + else if (strcmp(argv[i], "-strip") == 0) { + draw_strip = 1; + } + else if (i == argc - 1) { + filename = argv[i]; + } + else { + usage(argv[0]); + exit(1); + } + } + + if (!filename) { + usage(argv[0]); + exit(1); + } +} + +int main( int argc, char *argv[] ) +{ + args(argc,argv); + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c new file mode 100644 index 00000000000..c50ef12ab5a --- /dev/null +++ b/src/gallium/tests/graw/quad-tex.c @@ -0,0 +1,403 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_inlines.h" +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" +#include "util/u_box.h" + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_resource *rttex = NULL; +static struct pipe_resource *samptex = NULL; +static struct pipe_surface *surf = NULL; +static struct pipe_sampler_view *sv = NULL; +static void *sampler = NULL; +static void *window = NULL; + +struct vertex { + float position[4]; + float color[4]; +}; + +static struct vertex vertices[] = +{ + { { 0.9, -0.9, 0.0, 1.0 }, + { 1, 0, 0, 1 } }, + + { { 0.9, 0.9, 0.0, 1.0 }, + { 1, 1, 0, 1 } }, + + { {-0.9, 0.9, 0.0, 1.0 }, + { 0, 1, 0, 1 } }, + + { {-0.9, -0.9, 0.0, 1.0 }, + { 0, 0, 0, 1 } }, +}; + + + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[2]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 2, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + vbuf.stride = sizeof( struct vertex ); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], GENERIC[0]\n" + " 0: MOV OUT[1], IN[1]\n" + " 1: MOV OUT[0], IN[0]\n" + " 2: END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], GENERIC[0], PERSPECTIVE\n" + "DCL OUT[0], COLOR\n" + "DCL TEMP[0]\n" + "DCL SAMP[0]\n" + " 0: TXP TEMP[0], IN[0], SAMP[0], 2D\n" + " 1: MOV OUT[0], TEMP[0]\n" + " 2: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + +static void draw( void ) +{ + float clear_color[4] = {.5,.5,.5,1}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + +#define SIZE 16 + +static void init_tex( void ) +{ + struct pipe_sampler_view sv_template; + struct pipe_sampler_state sampler_desc; + struct pipe_resource templat; + struct pipe_box box; + ubyte tex2d[SIZE][SIZE][4]; + int s, t; + +#if (SIZE != 2) + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + if (0) { + int x = (s ^ t) & 1; + tex2d[t][s][0] = (x) ? 0 : 63; + tex2d[t][s][1] = (x) ? 0 : 128; + tex2d[t][s][2] = 0; + tex2d[t][s][3] = 0xff; + } + else { + int x = ((s ^ t) >> 2) & 1; + tex2d[t][s][0] = s*255/(SIZE-1); + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = (x) ? 0 : 128; + tex2d[t][s][3] = 0xff; + } + } + } +#else + tex2d[0][0][0] = 0; + tex2d[0][0][1] = 255; + tex2d[0][0][2] = 255; + tex2d[0][0][3] = 0; + + tex2d[0][1][0] = 0; + tex2d[0][1][1] = 0; + tex2d[0][1][2] = 255; + tex2d[0][1][3] = 255; + + tex2d[1][0][0] = 255; + tex2d[1][0][1] = 255; + tex2d[1][0][2] = 0; + tex2d[1][0][3] = 255; + + tex2d[1][1][0] = 255; + tex2d[1][1][1] = 0; + tex2d[1][1][2] = 0; + tex2d[1][1][3] = 255; +#endif + + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; + templat.width0 = SIZE; + templat.height0 = SIZE; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_SAMPLER_VIEW; + + + samptex = screen->resource_create(screen, + &templat); + if (samptex == NULL) + exit(4); + + u_box_2d(0,0,SIZE,SIZE, &box); + + ctx->transfer_inline_write(ctx, + samptex, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + tex2d, + sizeof tex2d[0], + sizeof tex2d); + + /* Possibly read back & compare against original data: + */ + if (0) + { + struct pipe_transfer *t; + uint32_t *ptr; + t = pipe_get_transfer(ctx, samptex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_READ, + 0, 0, SIZE, SIZE); /* x, y, width, height */ + + ptr = ctx->transfer_map(ctx, t); + + if (memcmp(ptr, tex2d, sizeof tex2d) != 0) { + assert(0); + exit(9); + } + + ctx->transfer_unmap(ctx, t); + + ctx->transfer_destroy(ctx, t); + } + + memset(&sv_template, 0, sizeof sv_template); + sv_template.format = samptex->format; + sv_template.texture = samptex; + sv_template.first_level = 0; + sv_template.last_level = 0; + sv_template.swizzle_r = 0; + sv_template.swizzle_g = 1; + sv_template.swizzle_b = 2; + sv_template.swizzle_a = 3; + sv = ctx->create_sampler_view(ctx, samptex, &sv_template); + if (sv == NULL) + exit(5); + + ctx->set_fragment_sampler_views(ctx, 1, &sv); + + + memset(&sampler_desc, 0, sizeof sampler_desc); + sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler_desc.compare_func = 0; + sampler_desc.normalized_coords = 1; + sampler_desc.max_anisotropy = 0; + + sampler = ctx->create_sampler_state(ctx, &sampler_desc); + if (sampler == NULL) + exit(6); + + ctx->bind_fragment_sampler_states(ctx, 1, &sampler); + +} + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + rttex = screen->resource_create(screen, + &templat); + if (rttex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, rttex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + + init_tex(); + + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); +} + + +int main( int argc, char *argv[] ) +{ + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c new file mode 100644 index 00000000000..ec30871e82c --- /dev/null +++ b/src/gallium/tests/graw/shader-leak.c @@ -0,0 +1,266 @@ +/** + * Create shaders in a loop to test memory usage. + */ + +#include <stdio.h> +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" + + +static int num_iters = 100; + + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_surface *surf = NULL; +static void *window = NULL; + +struct vertex { + float position[4]; + float color[4]; +}; + +static struct vertex vertices[1] = +{ + { + { 0.0f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f } + } +}; + + + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[2]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 2, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + vbuf.stride = sizeof(struct vertex); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR\n" + " 0: MOV OUT[1], IN[1]\n" + " 1: MOV OUT[0], IN[0]\n" + " 2: END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + + + +static void * +set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], COLOR, LINEAR\n" + "DCL OUT[0], COLOR\n" + "DCL TEMP[0..1]\n" + " 0: MUL TEMP[0], IN[0], IN[0]\n" + " 1: ADD TEMP[1], IN[0], IN[0]\n" + " 2: SUB OUT[0], TEMP[0], TEMP[1]\n" + " 3: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + return handle; +} + + +static void draw( void ) +{ + float clear_color[4] = {0, 0, 0, 1}; + int i; + + printf("Creating %d shaders\n", num_iters); + + for (i = 0; i < num_iters; i++) { + void *fs = set_fragment_shader(); + + ctx->bind_fs_state(ctx, fs); + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + + ctx->bind_fs_state(ctx, NULL); + ctx->delete_fs_state(ctx, fs); + } + + screen->flush_frontbuffer(screen, surf, window); + ctx->destroy(ctx); + + exit(0); +} + + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource *tex, templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + tex = screen->resource_create(screen, &templat); + if (tex == NULL) { + fprintf(stderr, "Unable to create screen texture!\n"); + exit(4); + } + + surf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + set_vertices(); + set_vertex_shader(); + if (0) + set_fragment_shader(); +} + + +int main( int argc, char *argv[] ) +{ + if (argc > 1) + num_iters = atoi(argv[1]); + + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c new file mode 100644 index 00000000000..152ae408eb0 --- /dev/null +++ b/src/gallium/tests/graw/tri-gs.c @@ -0,0 +1,268 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_surface *surf = NULL; +static void *window = NULL; + +struct vertex { + float position[4]; + float color[4]; +}; + +static struct vertex vertices[4] = +{ + { { 0.0f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f } + }, + { { -0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { { 0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + } +}; + + + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[2]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 2, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + vbuf.stride = sizeof( struct vertex ); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR\n" + " 0: MOV OUT[1], IN[1]\n" + " 1: MOV OUT[0], IN[0]\n" + " 2: END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], COLOR, LINEAR\n" + "DCL OUT[0], COLOR\n" + " 0: MOV OUT[0], IN[0]\n" + " 1: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + +static void set_geometry_shader( void ) +{ + void *handle; + const char *text = + "GEOM\n" + "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n" + "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n" + "DCL IN[][0], POSITION, CONSTANT\n" + "DCL IN[][1], COLOR, CONSTANT\n" + "DCL OUT[0], POSITION, CONSTANT\n" + "DCL OUT[1], COLOR, CONSTANT\n" + "0:MOV OUT[0], IN[0][0]\n" + "1:MOV OUT[1], IN[0][1]\n" + "2:EMIT\n" + "3:MOV OUT[0], IN[1][0]\n" + "4:MOV OUT[1], IN[0][1]\n" /* copy color from input vertex 0 */ + "5:EMIT\n" + "6:MOV OUT[0], IN[2][0]\n" + "7:MOV OUT[1], IN[2][1]\n" + "8:EMIT\n" + "9:ENDPRIM\n" + "10:END\n"; + + handle = graw_parse_geometry_shader(ctx, text); + ctx->bind_gs_state(ctx, handle); +} + +static void draw( void ) +{ + float clear_color[4] = {1,0,1,1}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + + screen->flush_frontbuffer(screen, surf, window); +} + + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource *tex, templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + tex = screen->resource_create(screen, + &templat); + if (tex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); + set_geometry_shader(); +} + + +int main( int argc, char *argv[] ) +{ + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c new file mode 100644 index 00000000000..8859f745fdb --- /dev/null +++ b/src/gallium/tests/graw/tri-instanced.c @@ -0,0 +1,345 @@ +/* + * Test draw instancing. + */ + +#include <stdio.h> +#include <string.h> + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" + + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_surface *surf = NULL; +static void *window = NULL; + +struct vertex { + float position[4]; + float color[4]; +}; + + +static int draw_elements = 0; + + +/** + * Vertex data. + * Each vertex has three attributes: position, color and translation. + * The translation attribute is a per-instance attribute. See + * "instance_divisor" below. + */ +static struct vertex vertices[4] = +{ + { + { 0.0f, -0.3f, 0.0f, 1.0f }, /* pos */ + { 1.0f, 0.0f, 0.0f, 1.0f } /* color */ + }, + { + { -0.2f, 0.3f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { + { 0.2f, 0.3f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + } +}; + + +#define NUM_INST 5 + +static float inst_data[NUM_INST][4] = +{ + { -0.50f, 0.4f, 0.0f, 0.0f }, + { -0.25f, 0.1f, 0.0f, 0.0f }, + { 0.00f, 0.2f, 0.0f, 0.0f }, + { 0.25f, 0.1f, 0.0f, 0.0f }, + { 0.50f, 0.3f, 0.0f, 0.0f } +}; + + +static ushort indices[3] = { 0, 2, 1 }; + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[3]; + struct pipe_vertex_buffer vbuf[2]; + struct pipe_index_buffer ibuf; + void *handle; + + memset(ve, 0, sizeof ve); + + /* pos */ + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[0].vertex_buffer_index = 0; + + /* color */ + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].vertex_buffer_index = 0; + + /* per-instance info */ + ve[2].src_offset = 0; + ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[2].vertex_buffer_index = 1; + ve[2].instance_divisor = 1; + + handle = ctx->create_vertex_elements_state(ctx, 3, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + /* vertex data */ + vbuf[0].stride = sizeof( struct vertex ); + vbuf[0].max_index = sizeof(vertices) / vbuf[0].stride; + vbuf[0].buffer_offset = 0; + vbuf[0].buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + /* instance data */ + vbuf[1].stride = sizeof( inst_data[0] ); + vbuf[1].max_index = sizeof(inst_data) / vbuf[1].stride; + vbuf[1].buffer_offset = 0; + vbuf[1].buffer = screen->user_buffer_create(screen, + inst_data, + sizeof(inst_data), + PIPE_BIND_VERTEX_BUFFER); + + + ctx->set_vertex_buffers(ctx, 2, vbuf); + + /* index data */ + ibuf.buffer = screen->user_buffer_create(screen, + indices, + sizeof(indices), + PIPE_BIND_VERTEX_BUFFER); + ibuf.offset = 0; + ibuf.index_size = 2; + + ctx->set_index_buffer(ctx, &ibuf); + +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL IN[2]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR\n" + " 0: MOV OUT[1], IN[1]\n" + " 1: ADD OUT[0], IN[0], IN[2]\n" /* add instance pos to vertex pos */ + " 2: END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], COLOR, LINEAR\n" + "DCL OUT[0], COLOR\n" + " 0: MOV OUT[0], IN[0]\n" + " 1: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + +static void draw( void ) +{ + float clear_color[4] = {1,0,1,1}; + struct pipe_draw_info info; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + + util_draw_init_info(&info); + info.indexed = (draw_elements != 0); + info.mode = PIPE_PRIM_TRIANGLES; + info.start = 0; + info.count = 3; + /* draw NUM_INST triangles */ + info.instance_count = NUM_INST; + + ctx->draw_vbo(ctx, &info); + + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource *tex, templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + tex = screen->resource_create(screen, + &templat); + if (tex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); +} + + +static void options(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-e") == 0) + draw_elements = 1; + } + if (draw_elements) + printf("Using pipe_context::draw_elements_instanced()\n"); + else + printf("Using pipe_context::draw_arrays_instanced()\n"); +} + + +int main( int argc, char *argv[] ) +{ + options(argc, argv); + + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c new file mode 100644 index 00000000000..f7e39588a4d --- /dev/null +++ b/src/gallium/tests/graw/tri.c @@ -0,0 +1,263 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include <stdio.h> + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_surface *surf = NULL; +static void *window = NULL; + +struct vertex { + float position[4]; + float color[4]; +}; + +static struct vertex vertices[3] = +{ + { + { 0.0f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f } + }, + { + { -0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { + { 0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + } +}; + + + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[2]; + struct pipe_vertex_buffer vbuf; + void *handle; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 2, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + + vbuf.stride = sizeof( struct vertex ); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + void *handle; + const char *text = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR\n" + " 0: MOV OUT[1], IN[1]\n" + " 1: MOV OUT[0], IN[0]\n" + " 2: END\n"; + + handle = graw_parse_vertex_shader(ctx, text); + ctx->bind_vs_state(ctx, handle); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], COLOR, LINEAR\n" + "DCL OUT[0], COLOR\n" + " 0: MOV OUT[0], IN[0]\n" + " 1: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + +static void draw( void ) +{ + float clear_color[4] = {1,0,1,1}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource *tex, templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,300,300, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) { + fprintf(stderr, "Unable to create context!\n"); + exit(3); + } + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + tex = screen->resource_create(screen, + &templat); + if (tex == NULL) { + fprintf(stderr, "Unable to create screen texture!\n"); + exit(4); + } + + surf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) { + fprintf(stderr, "Unable to get tex surface!\n"); + exit(5); + } + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); +} + + +int main( int argc, char *argv[] ) +{ + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/graw/vertex-shader b/src/gallium/tests/graw/vertex-shader new file mode 120000 index 00000000000..7b216e8ca08 --- /dev/null +++ b/src/gallium/tests/graw/vertex-shader @@ -0,0 +1 @@ +../python/tests/regress/vertex-shader
\ No newline at end of file diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c new file mode 100644 index 00000000000..e1cd814bf72 --- /dev/null +++ b/src/gallium/tests/graw/vs-test.c @@ -0,0 +1,508 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#include "state_tracker/graw.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include <stdio.h> /* for fread(), etc */ + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ +#include "util/u_inlines.h" +#include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" +#include "util/u_box.h" + +static const char *filename = NULL; +unsigned show_fps = 0; + + +static void usage(char *name) +{ + fprintf(stderr, "usage: %s [ options ] shader_filename\n", name); +#ifndef WIN32 + fprintf(stderr, "\n" ); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -fps show frames per second\n"); +#endif +} + + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 250; +static const int HEIGHT = 250; + +static struct pipe_screen *screen = NULL; +static struct pipe_context *ctx = NULL; +static struct pipe_resource *rttex = NULL; +static struct pipe_resource *constbuf = NULL; +static struct pipe_surface *surf = NULL; +static struct pipe_sampler_view *sv = NULL; +static void *sampler = NULL; +static void *window = NULL; +static struct pipe_resource *samptex = NULL; + +struct vertex { + float position[4]; + float color[3]; +}; + +/* Draw a regular mesh + */ +#define MESH_SZ 16 +static struct vertex vertices[MESH_SZ * MESH_SZ]; + +static float constants[] = +{ 0.4, 0, 0, 1, + 1, 1, 1, 1, + 2, 2, 2, 2, + 4, 8, 16, 32, + + 3, 0, 0, 0, + 0, .5, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + + 1, 0, 0, 0.5, + 0, 1, 0, 0.5, + 0, 0, 1, 0, + 0, 0, 0, 1, +}; + +static void init_fs_constbuf( void ) +{ + struct pipe_resource templat; + struct pipe_box box; + + templat.target = PIPE_BUFFER; + templat.format = PIPE_FORMAT_R8_UNORM; + templat.width0 = sizeof(constants); + templat.height0 = 1; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_CONSTANT_BUFFER; + + constbuf = screen->resource_create(screen, + &templat); + if (constbuf == NULL) + exit(4); + + + u_box_2d(0,0,sizeof(constants),1, &box); + + ctx->transfer_inline_write(ctx, + constbuf, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + constants, + sizeof constants, + sizeof constants); + + + ctx->set_constant_buffer(ctx, + PIPE_SHADER_FRAGMENT, 0, + constbuf); +} + + +static void set_viewport( float x, float y, + float width, float height, + float near, float far) +{ + float z = far; + float half_width = (float)width / 2.0f; + float half_height = (float)height / 2.0f; + float half_depth = ((float)far - (float)near) / 2.0f; + struct pipe_viewport_state vp; + + vp.scale[0] = half_width; + vp.scale[1] = half_height; + vp.scale[2] = half_depth; + vp.scale[3] = 1.0f; + + vp.translate[0] = half_width + x; + vp.translate[1] = half_height + y; + vp.translate[2] = half_depth + z; + vp.translate[3] = 0.0f; + + ctx->set_viewport_state( ctx, &vp ); +} + +static void set_vertices( void ) +{ + struct pipe_vertex_element ve[2]; + struct pipe_vertex_buffer vbuf; + void *handle; + int x,y; + + memset(ve, 0, sizeof ve); + + ve[0].src_offset = Offset(struct vertex, position); + ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + ve[1].src_offset = Offset(struct vertex, color); + ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + handle = ctx->create_vertex_elements_state(ctx, 2, ve); + ctx->bind_vertex_elements_state(ctx, handle); + + for (x = 0; x < MESH_SZ; x++) { + for (y = 0; y < MESH_SZ; y++) { + int i = y * MESH_SZ + x; + vertices[i].position[0] = ((float)x)/MESH_SZ * 2.0 - 1.0; + vertices[i].position[1] = ((float)y)/MESH_SZ * 2.0 - 1.0; + vertices[i].position[2] = 0; + vertices[i].position[3] = 1.0; + + vertices[i].color[0] = .5; + vertices[i].color[1] = (float)x / (float)MESH_SZ; + vertices[i].color[2] = (float)y / (float)MESH_SZ; + } + } + + vbuf.stride = sizeof( struct vertex ); + vbuf.max_index = sizeof(vertices) / vbuf.stride; + vbuf.buffer_offset = 0; + vbuf.buffer = screen->user_buffer_create(screen, + vertices, + sizeof(vertices), + PIPE_BIND_VERTEX_BUFFER); + + ctx->set_vertex_buffers(ctx, 1, &vbuf); +} + +static void set_vertex_shader( void ) +{ + FILE *f; + char buf[50000]; + void *handle; + int sz; + + if ((f = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Couldn't open %s\n", filename); + exit(1); + } + + sz = fread(buf, 1, sizeof(buf), f); + if (!feof(f)) { + printf("file too long\n"); + exit(1); + } + printf("%.*s\n", sz, buf); + buf[sz] = 0; + + handle = graw_parse_vertex_shader(ctx, buf); + ctx->bind_vs_state(ctx, handle); + fclose(f); +} + +static void set_fragment_shader( void ) +{ + void *handle; + const char *text = + "FRAG\n" + "DCL IN[0], COLOR, LINEAR\n" + "DCL OUT[0], COLOR\n" + " 0: MOV OUT[0], IN[0]\n" + " 1: END\n"; + + handle = graw_parse_fragment_shader(ctx, text); + ctx->bind_fs_state(ctx, handle); +} + + + +static void draw( void ) +{ + float clear_color[4] = {.1,.3,.5,0}; + + ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#if 0 + /* At the moment, libgraw leaks out/makes available some of the + * symbols from gallium/auxiliary, including these debug helpers. + * Will eventually want to bless some of these paths, and lock the + * others down so they aren't accessible from test programs. + * + * This currently just happens to work on debug builds - a release + * build will probably fail to link here: + */ + debug_dump_surface_bmp(ctx, "result.bmp", surf); +#endif + + screen->flush_frontbuffer(screen, surf, window); +} + +#define SIZE 16 + +static void init_tex( void ) +{ + struct pipe_sampler_view sv_template; + struct pipe_sampler_state sampler_desc; + struct pipe_resource templat; + struct pipe_box box; + ubyte tex2d[SIZE][SIZE][4]; + int s, t; + +#if (SIZE != 2) + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + if (0) { + int x = (s ^ t) & 1; + tex2d[t][s][0] = (x) ? 0 : 63; + tex2d[t][s][1] = (x) ? 0 : 128; + tex2d[t][s][2] = 0; + tex2d[t][s][3] = 0xff; + } + else { + int x = ((s ^ t) >> 2) & 1; + tex2d[t][s][0] = s*255/(SIZE-1); + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = (x) ? 0 : 128; + tex2d[t][s][3] = 0xff; + } + } + } +#else + tex2d[0][0][0] = 0; + tex2d[0][0][1] = 255; + tex2d[0][0][2] = 255; + tex2d[0][0][3] = 0; + + tex2d[0][1][0] = 0; + tex2d[0][1][1] = 0; + tex2d[0][1][2] = 255; + tex2d[0][1][3] = 255; + + tex2d[1][0][0] = 255; + tex2d[1][0][1] = 255; + tex2d[1][0][2] = 0; + tex2d[1][0][3] = 255; + + tex2d[1][1][0] = 255; + tex2d[1][1][1] = 0; + tex2d[1][1][2] = 0; + tex2d[1][1][3] = 255; +#endif + + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; + templat.width0 = SIZE; + templat.height0 = SIZE; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = PIPE_BIND_SAMPLER_VIEW; + + + samptex = screen->resource_create(screen, + &templat); + if (samptex == NULL) + exit(4); + + u_box_2d(0,0,SIZE,SIZE, &box); + + ctx->transfer_inline_write(ctx, + samptex, + u_subresource(0,0), + PIPE_TRANSFER_WRITE, + &box, + tex2d, + sizeof tex2d[0], + sizeof tex2d); + + /* Possibly read back & compare against original data: + */ + if (0) + { + struct pipe_transfer *t; + uint32_t *ptr; + t = pipe_get_transfer(ctx, samptex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_READ, + 0, 0, SIZE, SIZE); /* x, y, width, height */ + + ptr = ctx->transfer_map(ctx, t); + + if (memcmp(ptr, tex2d, sizeof tex2d) != 0) { + assert(0); + exit(9); + } + + ctx->transfer_unmap(ctx, t); + + ctx->transfer_destroy(ctx, t); + } + + memset(&sv_template, 0, sizeof sv_template); + sv_template.format = samptex->format; + sv_template.texture = samptex; + sv_template.first_level = 0; + sv_template.last_level = 0; + sv_template.swizzle_r = 0; + sv_template.swizzle_g = 1; + sv_template.swizzle_b = 2; + sv_template.swizzle_a = 3; + sv = ctx->create_sampler_view(ctx, samptex, &sv_template); + if (sv == NULL) + exit(5); + + ctx->set_fragment_sampler_views(ctx, 1, &sv); + + + memset(&sampler_desc, 0, sizeof sampler_desc); + sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler_desc.compare_func = 0; + sampler_desc.normalized_coords = 1; + sampler_desc.max_anisotropy = 0; + + sampler = ctx->create_sampler_state(ctx, &sampler_desc); + if (sampler == NULL) + exit(6); + + ctx->bind_fragment_sampler_states(ctx, 1, &sampler); + +} + +static void init( void ) +{ + struct pipe_framebuffer_state fb; + struct pipe_resource templat; + int i; + + /* It's hard to say whether window or screen should be created + * first. Different environments would prefer one or the other. + * + * Also, no easy way of querying supported formats if the screen + * cannot be created first. + */ + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + screen = graw_create_window_and_screen(0,0,WIDTH,HEIGHT, + formats[i], + &window); + } + + ctx = screen->context_create(screen, NULL); + if (ctx == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.bind = (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + + rttex = screen->resource_create(screen, + &templat); + if (rttex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, rttex, 0, 0, 0, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + ctx->set_framebuffer_state(ctx, &fb); + + { + struct pipe_blend_state blend; + void *handle; + memset(&blend, 0, sizeof blend); + blend.rt[0].colormask = PIPE_MASK_RGBA; + handle = ctx->create_blend_state(ctx, &blend); + ctx->bind_blend_state(ctx, handle); + } + + { + struct pipe_depth_stencil_alpha_state depthstencil; + void *handle; + memset(&depthstencil, 0, sizeof depthstencil); + handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); + ctx->bind_depth_stencil_alpha_state(ctx, handle); + } + + { + struct pipe_rasterizer_state rasterizer; + void *handle; + memset(&rasterizer, 0, sizeof rasterizer); + rasterizer.cull_face = PIPE_FACE_NONE; + rasterizer.point_size = 8.0; + rasterizer.gl_rasterization_rules = 1; + handle = ctx->create_rasterizer_state(ctx, &rasterizer); + ctx->bind_rasterizer_state(ctx, handle); + } + + set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); + + init_tex(); + init_fs_constbuf(); + + set_vertices(); + set_vertex_shader(); + set_fragment_shader(); +} + +static void args(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fps") == 0) { + show_fps = 1; + } + else if (i == argc - 1) { + filename = argv[i]; + } + else { + usage(argv[0]); + exit(1); + } + } + + if (!filename) { + usage(argv[0]); + exit(1); + } +} + +int main( int argc, char *argv[] ) +{ + args(argc,argv); + init(); + + graw_set_display_func( draw ); + graw_main_loop(); + return 0; +} diff --git a/src/gallium/tests/python/retrace/interpreter.py b/src/gallium/tests/python/retrace/interpreter.py index 7118ff85ed8..16132abb06d 100755 --- a/src/gallium/tests/python/retrace/interpreter.py +++ b/src/gallium/tests/python/retrace/interpreter.py @@ -111,6 +111,7 @@ struct_factories = { #"pipe_texture": gallium.Texture, 'pipe_subresource': gallium.pipe_subresource, 'pipe_box': gallium.pipe_box, + 'pipe_draw_info': gallium.pipe_draw_info, } @@ -230,8 +231,8 @@ class Screen(Object): context = self.real.context_create() return Context(self.interpreter, context) - def is_format_supported(self, format, target, bind, geom_flags): - return self.real.is_format_supported(format, target, bind, geom_flags) + def is_format_supported(self, format, target, sample_count, bind, geom_flags): + return self.real.is_format_supported(format, target, sample_count, bind, geom_flags) def resource_create(self, templat): return self.real.resource_create( @@ -432,6 +433,9 @@ class Context(Object): swizzle_b = templ.swizzle_g, swizzle_a = templ.swizzle_a) + def sampler_view_destroy(self, view): + pass + def set_fragment_sampler_views(self, num, views): for i in range(num): self.real.set_fragment_sampler_view(i, views[i]) @@ -456,6 +460,10 @@ class Context(Object): return elements[0:num_elements] def bind_vertex_elements_state(self, state): + if state is None: + self.real.set_vertex_elements(0) + return + elements = state num_elements = len(elements) self.velems = elements @@ -526,43 +534,31 @@ class Context(Object): return minindex + ibias, maxindex + ibias - def draw_arrays(self, mode, start, count): - self.dump_vertices(start, count) - - self.real.draw_arrays(mode, start, count) - self._set_dirty() - - def draw_elements(self, indexBuffer, indexSize, indexBias, mode, start, count): - if self.interpreter.verbosity(2): - minindex, maxindex = self.dump_indices(indexBuffer, indexSize, indexBias, start, count) - self.dump_vertices(minindex, maxindex - minindex) + def set_index_buffer(self, ib): + if ib: + self.real.set_index_buffer(ib.index_size, ib.offset, ib.buffer) + else: + self.real.set_index_buffer(0, 0, None) - self.real.draw_elements(indexBuffer, indexSize, indexBias, mode, start, count) - self._set_dirty() - - def draw_range_elements(self, indexBuffer, indexSize, indexBias, minIndex, maxIndex, mode, start, count): + def draw_vbo(self, info): if self.interpreter.verbosity(2): - minindex, maxindex = self.dump_indices(indexBuffer, indexSize, indexBias, start, count) - minindex = min(minindex, minIndex) - maxindex = min(maxindex, maxIndex) - self.dump_vertices(minindex, maxindex - minindex) + if 0: + minindex, maxindex = self.dump_indices(indexBuffer, indexSize, indexBias, start, count) + + self.dump_vertices(info.minindex, info.maxindex + 1 - info.minindex) - self.real.draw_range_elements(indexBuffer, indexSize, indexBias, minIndex, maxIndex, mode, start, count) + self.real.draw_vbo(info) self._set_dirty() - - def surface_copy(self, dest, destx, desty, src, srcx, srcy, width, height): - if dest is not None and src is not None: + + def resource_copy_region(self, dst, subdst, dstx, dsty, dstz, src, subsrc, srcx, srcy, srcz, width, height): + if dst is not None and src is not None: if self.interpreter.options.all: - self.interpreter.present(self.real, src, 'surface_copy_src', srcx, srcy, width, height) - self.real.surface_copy(dest, destx, desty, src, srcx, srcy, width, height) - if dest in self.cbufs: - self._set_dirty() - flags = gallium.PIPE_FLUSH_FRAME - else: - flags = 0 + self.interpreter.present(self.real, src, 'resource_copy_src', srcx, srcy, width, height) + self.real.resource_copy_region(dst, subdst, dstx, dsty, dstx, src, subsrc, srcx, srcy, srcz, width, height) + flags = 0 self.flush(flags) if self.interpreter.options.all: - self.interpreter.present(self.real, dest, 'surface_copy_dest', destx, desty, width, height) + self.interpreter.present(self.real, dst, 'resource_copy_dst', dstx, dsty, width, height) def is_resource_referenced(self, texture, face, level): #return self.real.is_resource_referenced(format, texture, face, level) diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-2d.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-2d.sh index f70a5146f4e..bbc3a10f9b5 100644 --- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-2d.sh +++ b/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-2d.sh @@ -2,8 +2,8 @@ FRAG DCL IN[0], COLOR, LINEAR DCL OUT[0], COLOR -DCL CONST[1][1..2] +DCL CONST[1][6] -MAD OUT[0], IN[0], CONST[1][2], CONST[1][1] +MOV OUT[0], CONST[1][6] END diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-kil.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-kil.sh new file mode 100644 index 00000000000..583b0ca4a4a --- /dev/null +++ b/src/gallium/tests/python/tests/regress/fragment-shader/frag-kil.sh @@ -0,0 +1,18 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMP[0] + +IMM FLT32 { 0.6, 0.6, 0.6, 0.0 } +IMM FLT32 { 0.01, 0.0, 0.0, 0.0 } +IMM FLT32 { 1.0, 0.0, 0.0, 0.0 } + +SLT TEMP[0], IN[0], IMM[0] +MUL OUT[0], IN[0], TEMP[0] +MOV OUT[0].w, IMM[2].xxxx +SUB TEMP[0], TEMP[0], IMM[1].xxxy +KIL TEMP[0] + +END diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mad-immx.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-mad-immx.sh new file mode 100644 index 00000000000..6b034915769 --- /dev/null +++ b/src/gallium/tests/python/tests/regress/fragment-shader/frag-mad-immx.sh @@ -0,0 +1,10 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR +DCL IMMX[0..1] {{ 0.5, 0.4, 0.6, 1.0 }, + { 0.5, 0.4, 0.6, 0.0 }} + +MAD OUT[0], IN[0], IMMX[0], IMMX[1] + +END diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-tempx.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-tempx.sh new file mode 100644 index 00000000000..81bcad2d65c --- /dev/null +++ b/src/gallium/tests/python/tests/regress/fragment-shader/frag-tempx.sh @@ -0,0 +1,14 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR + +DCL TEMPX[0][0..1] + +IMM FLT32 { -0.5, -0.4, -0.6, 0.0 } + +ADD TEMPX[0][0], IN[0], IMM[0] +ADD TEMPX[0][1], IN[0], IMM[0] +ABS OUT[0], TEMPX[0][1] + +END diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-abs.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-abs.sh index 79c9ca69fb1..062a48b531e 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-abs.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-abs.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL TEMP[0] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-add.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-add.sh index ca97ad05df0..188931ebc8d 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-add.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-add.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-arl.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-arl.sh index 321140e89e8..0039597f6f0 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-arl.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-arl.sh @@ -1,6 +1,6 @@ VERT -DCL IN[0], POSITION +DCL IN[0] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-arr.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-arr.sh index d60ea46b367..fdde4f9ad12 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-arr.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-arr.sh @@ -1,6 +1,6 @@ VERT -DCL IN[0], POSITION +DCL IN[0] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-1d.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-1d.sh index b41fe5dd38f..e227917fd3b 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-1d.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-1d.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL CONST[1] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-2d.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-2d.sh index 45f5e6b7299..39768d2dda9 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-2d.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-cb-2d.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL CONST[1][1..2] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp3.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp3.sh index caff622fe61..357e224f696 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp3.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp3.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL TEMP[0] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp4.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp4.sh index 3dd2fd1c2f7..14f61066014 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp4.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-dp4.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL TEMP[0] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-dst.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-dst.sh index da9cc18dfc0..2d59bd1a0c3 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-dst.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-dst.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-ex2.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-ex2.sh index 4637227e5c4..e2383a6b5bd 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-ex2.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-ex2.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-flr.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-flr.sh index aa80d6e394c..fa24806663b 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-flr.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-flr.sh @@ -1,6 +1,6 @@ VERT -DCL IN[0], POSITION +DCL IN[0] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-frc.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-frc.sh index 64d1a494e13..ff09bfafd0c 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-frc.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-frc.sh @@ -1,6 +1,6 @@ VERT -DCL IN[0], POSITION +DCL IN[0] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-lg2.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-lg2.sh index 5cf16fd1aa8..876b7ab6608 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-lg2.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-lg2.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-lit.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-lit.sh index a4a752d4d23..a2235ff6119 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-lit.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-lit.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-lrp.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-lrp.sh index 4bb5f3ec3f4..a26ca3b0ec0 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-lrp.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-lrp.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-mad.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-mad.sh index daaa941f15f..caf83a91e48 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-mad.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-mad.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-max.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-max.sh index af279ec7f4a..db84a499214 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-max.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-max.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-min.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-min.sh index 46d886c55b8..63a8c2cf3cd 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-min.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-min.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-mov.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-mov.sh index 0ef91637e03..4c23e3eaadb 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-mov.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-mov.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-mul.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-mul.sh index d34f6cd6e3c..a409cd4b21e 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-mul.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-mul.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-rcp.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-rcp.sh index cfb3ec37dc2..d440e35d9a3 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-rcp.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-rcp.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-rsq.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-rsq.sh index faf1e6e7d41..6fbd53ae0ac 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-rsq.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-rsq.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-sge.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-sge.sh index 6de1d071ef4..e32a21b6109 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-sge.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-sge.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-slt.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-slt.sh index 9a524229845..2af61062922 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-slt.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-slt.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-abs.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-abs.sh index dc87ce4ae70..e768d95049d 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-abs.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-abs.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL TEMP[0] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh index d82eb08fd30..40ca5d60def 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR DCL TEMP[0] diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-neg.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-neg.sh index e39bebcd9f1..297bc1ee3ed 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-neg.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-neg.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-swz.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-swz.sh index 6f20552f212..528f164b9ee 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-swz.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-srcmod-swz.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-sub.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-sub.sh index 0f9678b8a3e..90249abdd38 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-sub.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-sub.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vert-xpd.sh b/src/gallium/tests/python/tests/regress/vertex-shader/vert-xpd.sh index 39d42ae2a0d..72b048676fb 100644 --- a/src/gallium/tests/python/tests/regress/vertex-shader/vert-xpd.sh +++ b/src/gallium/tests/python/tests/regress/vertex-shader/vert-xpd.sh @@ -1,7 +1,7 @@ VERT -DCL IN[0], POSITION -DCL IN[1], COLOR +DCL IN[0] +DCL IN[1] DCL OUT[0], POSITION DCL OUT[1], COLOR diff --git a/src/gallium/tests/python/tests/surface_copy.py b/src/gallium/tests/python/tests/surface_copy.py index 8d841644035..7a6ede38044 100755 --- a/src/gallium/tests/python/tests/surface_copy.py +++ b/src/gallium/tests/python/tests/surface_copy.py @@ -70,13 +70,14 @@ class TextureTest(TestCase): face = self.face level = self.level zslice = self.zslice - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 - if not dev.is_format_supported(format, target, bind, geom_flags): + sample_count = 0 + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - if not dev.is_format_supported(format, target, bind, geom_flags): + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip # textures diff --git a/src/gallium/tests/python/tests/texture_blit.py b/src/gallium/tests/python/tests/texture_blit.py index 77f006ea04e..089d05c6237 100755 --- a/src/gallium/tests/python/tests/texture_blit.py +++ b/src/gallium/tests/python/tests/texture_blit.py @@ -55,7 +55,7 @@ def tex_coords(texture, face, level, zslice): [0.0, 1.0], ] - if texture.target == PIPE_TEXTURE_2D: + if texture.target == PIPE_TEXTURE_2D or texture.target == PIPE_TEXTURE_RECT: return [[s, t, 0.0] for s, t in st] elif texture.target == PIPE_TEXTURE_3D: depth = texture.get_depth(level) @@ -130,17 +130,18 @@ class TextureColorSampleTest(TestCase): zslice = self.zslice minz = 0.0 maxz = 1.0 - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 + sample_count = 0 if width != height: geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE if not is_pot(width) or not is_pot(height) or not is_pot(depth): geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO - - if not dev.is_format_supported(format, target, bind, geom_flags): + + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - + # disabled blending/masking blend = Blend() blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE @@ -348,17 +349,18 @@ class TextureDepthSampleTest(TestCase): zslice = self.zslice minz = 0.0 maxz = 1.0 - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 + sample_count = 0 if width != height: geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE if not is_pot(width) or not is_pot(height) or not is_pot(depth): geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO - - if not dev.is_format_supported(format, target, bind, geom_flags): + + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - + # disabled blending/masking blend = Blend() blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE diff --git a/src/gallium/tests/python/tests/texture_transfer.py b/src/gallium/tests/python/tests/texture_transfer.py index 4aa3d6c709b..65c919bc64d 100755 --- a/src/gallium/tests/python/tests/texture_transfer.py +++ b/src/gallium/tests/python/tests/texture_transfer.py @@ -71,12 +71,13 @@ class TextureTest(TestCase): face = self.face level = self.level zslice = self.zslice - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 - if not dev.is_format_supported(format, target, bind, geom_flags): + sample_count = 0 + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - + # textures texture = dev.resource_create( target = target, diff --git a/src/gallium/tests/raw/SConscript b/src/gallium/tests/raw/SConscript deleted file mode 100644 index 073b97951e7..00000000000 --- a/src/gallium/tests/raw/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -Import('*') - -env = env.Clone() - -env.Prepend(LIBPATH = [graw.dir]) -env.Prepend(LIBS = [graw.name]) - -progs = [ - 'clear' -] - -for prog in progs: - env.Program( - target = prog, - source = prog + '.c', - ) - diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c index 522ff3cb42d..cf88edcdc56 100644 --- a/src/gallium/tests/trivial/quad-tex.c +++ b/src/gallium/tests/trivial/quad-tex.c @@ -58,18 +58,13 @@ /* util_make_[fragment|vertex]_passthrough_shader */ #include "util/u_simple_shaders.h" -/* softpipe software driver */ -#include "softpipe/sp_public.h" - +/* sw_screen_create: to get a software pipe driver */ +#include "target-helpers/inline_sw_helper.h" +/* debug_screen_wrap: to wrap with debug pipe drivers */ +#include "target-helpers/inline_debug_helper.h" /* null software winsys */ #include "sw/null/null_sw_winsys.h" -/* traceing support see src/gallium/drivers/trace/README for more info. */ -#if USE_TRACE -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#endif - struct program { struct pipe_screen *screen; @@ -98,10 +93,11 @@ struct program static void init_prog(struct program *p) { /* create the software rasterizer */ - p->screen = softpipe_create_screen(null_sw_create()); -#if USE_TRACE - p->screen = trace_screen_create(p->screen); -#endif + p->screen = sw_screen_create(null_sw_create()); + /* wrap the screen with any debugger */ + p->screen = debug_screen_wrap(p->screen); + + /* create the pipe driver context and cso context */ p->pipe = p->screen->context_create(p->screen, NULL); p->cso = cso_create_context(p->pipe); @@ -201,8 +197,7 @@ static void init_prog(struct program *p) /* rasterizer */ memset(&p->rasterizer, 0, sizeof(p->rasterizer)); - p->rasterizer.front_winding = PIPE_WINDING_CW; - p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.cull_face = PIPE_FACE_NONE; p->rasterizer.gl_rasterization_rules = 1; /* sampler */ @@ -272,7 +267,7 @@ static void init_prog(struct program *p) } /* fragment shader */ - p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D); + p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR); } static void close_prog(struct program *p) diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c index 48305240a4b..667a27b28ab 100644 --- a/src/gallium/tests/trivial/tri.c +++ b/src/gallium/tests/trivial/tri.c @@ -56,18 +56,13 @@ /* util_make_[fragment|vertex]_passthrough_shader */ #include "util/u_simple_shaders.h" -/* softpipe software driver */ -#include "softpipe/sp_public.h" - +/* sw_screen_create: to get a software pipe driver */ +#include "target-helpers/inline_sw_helper.h" +/* debug_screen_wrap: to wrap with debug pipe drivers */ +#include "target-helpers/inline_debug_helper.h" /* null software winsys */ #include "sw/null/null_sw_winsys.h" -/* traceing support see src/gallium/drivers/trace/README for more info. */ -#if USE_TRACE -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#endif - struct program { struct pipe_screen *screen; @@ -93,10 +88,11 @@ struct program static void init_prog(struct program *p) { /* create the software rasterizer */ - p->screen = softpipe_create_screen(null_sw_create()); -#if USE_TRACE - p->screen = trace_screen_create(p->screen); -#endif + p->screen = sw_screen_create(null_sw_create()); + /* wrap the screen with any debugger */ + p->screen = debug_screen_wrap(p->screen); + + /* create the pipe driver context and cso context */ p->pipe = p->screen->context_create(p->screen, NULL); p->cso = cso_create_context(p->pipe); @@ -151,8 +147,7 @@ static void init_prog(struct program *p) /* rasterizer */ memset(&p->rasterizer, 0, sizeof(p->rasterizer)); - p->rasterizer.front_winding = PIPE_WINDING_CW; - p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.cull_face = PIPE_FACE_NONE; p->rasterizer.gl_rasterization_rules = 1; /* drawing destination */ diff --git a/src/gallium/tests/unit/translate_test.c b/src/gallium/tests/unit/translate_test.c new file mode 100644 index 00000000000..d0946a91a26 --- /dev/null +++ b/src/gallium/tests/unit/translate_test.c @@ -0,0 +1,310 @@ +/************************************************************************** + * + * Copyright © 2010 Luca Barbieri + * + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h> +#include <translate/translate.h> +#include <util/u_memory.h> +#include <util/u_format.h> +#include <util/u_cpu_detect.h> +#include <rtasm/rtasm_cpu.h> + +/* don't use this for serious use */ +static double rand_double() +{ + const double rm = (double)RAND_MAX + 1; + double div = 1; + double v = 0; + unsigned i; + for(i = 0; i < 4; ++i) + { + div *= rm; + v += (double)rand() / div; + } + return v; +} + +int main(int argc, char** argv) +{ + struct translate *(*create_fn)(const struct translate_key *key) = 0; + + struct translate_key key; + unsigned output_format; + unsigned input_format; + unsigned buffer_size = 4096; + unsigned char* buffer[5]; + unsigned char* byte_buffer; + float* float_buffer; + double* double_buffer; + unsigned count = 4; + unsigned i, j, k; + unsigned passed = 0; + unsigned total = 0; + const float error = 0.03125; + + create_fn = 0; + + util_cpu_detect(); + + if(argc <= 1) + {} + else if (!strcmp(argv[1], "generic")) + create_fn = translate_generic_create; + else if (!strcmp(argv[1], "x86")) + create_fn = translate_sse2_create; + else if (!strcmp(argv[1], "nosse")) + { + util_cpu_caps.has_sse = 0; + util_cpu_caps.has_sse2 = 0; + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse")) + { + if(!util_cpu_caps.has_sse || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE (test with qemu)\n"); + return 2; + } + util_cpu_caps.has_sse2 = 0; + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse2")) + { + if(!util_cpu_caps.has_sse2 || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE2 (test with qemu)\n"); + return 2; + } + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse3")) + { + if(!util_cpu_caps.has_sse3 || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE3 (test with qemu)\n"); + return 2; + } + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse4.1")) + { + if(!util_cpu_caps.has_sse4_1 || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE4.1 (test with qemu)\n"); + return 2; + } + create_fn = translate_sse2_create; + } + + if (!create_fn) + { + printf("Usage: ./translate_test [generic|x86|nosse|sse|sse2|sse3|sse4.1]\n"); + return 2; + } + + for (i = 1; i < Elements(buffer); ++i) + buffer[i] = align_malloc(buffer_size, 4096); + + byte_buffer = align_malloc(buffer_size, 4096); + float_buffer = align_malloc(buffer_size, 4096); + double_buffer = align_malloc(buffer_size, 4096); + + key.nr_elements = 1; + key.element[0].input_buffer = 0; + key.element[0].input_offset = 0; + key.element[0].output_offset = 0; + key.element[0].type = TRANSLATE_ELEMENT_NORMAL; + key.element[0].instance_divisor = 0; + + srand(4359025); + + /* avoid negative values that work badly when converted to unsigned format*/ + for (i = 0; i < buffer_size; ++i) + byte_buffer[i] = rand() & 0x7f7f7f7f; + + for (i = 0; i < buffer_size / sizeof(float); ++i) + float_buffer[i] = (float)rand_double(); + + for (i = 0; i < buffer_size / sizeof(double); ++i) + double_buffer[i] = rand_double(); + + for (output_format = 1; output_format < PIPE_FORMAT_COUNT; ++output_format) + { + const struct util_format_description* output_format_desc = util_format_description(output_format); + unsigned output_format_size; + unsigned output_normalized = 0; + + if (!output_format_desc + || !output_format_desc->fetch_rgba_float + || !output_format_desc->pack_rgba_float + || output_format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB + || output_format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN + || !translate_is_output_format_supported(output_format)) + continue; + + for(i = 0; i < output_format_desc->nr_channels; ++i) + { + if(output_format_desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT) + output_normalized |= (1 << output_format_desc->channel[i].normalized); + } + + output_format_size = util_format_get_stride(output_format, 1); + + for (input_format = 1; input_format < PIPE_FORMAT_COUNT; ++input_format) + { + const struct util_format_description* input_format_desc = util_format_description(input_format); + unsigned input_format_size; + struct translate* translate[2]; + unsigned fail = 0; + unsigned used_generic = 0; + unsigned input_normalized = 0; + boolean input_is_float = FALSE; + + if (!input_format_desc + || !input_format_desc->fetch_rgba_float + || !input_format_desc->pack_rgba_float + || input_format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB + || input_format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN + || !translate_is_output_format_supported(input_format)) + continue; + + input_format_size = util_format_get_stride(input_format, 1); + + for(i = 0; i < input_format_desc->nr_channels; ++i) + { + if(input_format_desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) + { + input_is_float = 1; + input_normalized |= 1 << 1; + } + else + input_normalized |= (1 << input_format_desc->channel[i].normalized); + } + + if(((input_normalized | output_normalized) == 3) + || ((input_normalized & 1) && (output_normalized & 1) + && input_format_size * output_format_desc->nr_channels > output_format_size * input_format_desc->nr_channels)) + continue; + + key.element[0].input_format = input_format; + key.element[0].output_format = output_format; + key.output_stride = output_format_size; + translate[0] = create_fn(&key); + if (!translate[0]) + continue; + + key.element[0].input_format = output_format; + key.element[0].output_format = input_format; + key.output_stride = input_format_size; + translate[1] = create_fn(&key); + if(!translate[1]) + { + used_generic = 1; + translate[1] = translate_generic_create(&key); + if(!translate[1]) + continue; + } + + for(i = 1; i < 5; ++i) + memset(buffer[i], 0xcd - (0x22 * i), 4096); + + if(input_is_float && input_format_desc->channel[0].size == 32) + buffer[0] = (unsigned char*)float_buffer; + else if(input_is_float && input_format_desc->channel[0].size == 64) + buffer[0] = (unsigned char*)double_buffer; + else if(input_is_float) + abort(); + else + buffer[0] = byte_buffer; + + translate[0]->set_buffer(translate[0], 0, buffer[0], input_format_size, ~0); + translate[0]->run(translate[0], 0, count, 0, buffer[1]); + translate[1]->set_buffer(translate[1], 0, buffer[1], output_format_size, ~0); + translate[1]->run(translate[1], 0, count, 0, buffer[2]); + translate[0]->set_buffer(translate[0], 0, buffer[2], input_format_size, ~0); + translate[0]->run(translate[0], 0, count, 0, buffer[3]); + translate[1]->set_buffer(translate[1], 0, buffer[3], output_format_size, ~0); + translate[1]->run(translate[1], 0, count, 0, buffer[4]); + + for (i = 0; i < count; ++i) + { + float a[4]; + float b[4]; + input_format_desc->fetch_rgba_float(a, buffer[2] + i * input_format_size, 0, 0); + input_format_desc->fetch_rgba_float(b, buffer[4] + i * input_format_size, 0, 0); + + for (j = 0; j < count; ++j) + { + float d = a[j] - b[j]; + if (d > error || d < -error) + { + fail = 1; + break; + } + } + } + + printf("%s%s: %s -> %s -> %s -> %s -> %s\n", + fail ? "FAIL" : "PASS", + used_generic ? "[GENERIC]" : "", + input_format_desc->name, output_format_desc->name, input_format_desc->name, output_format_desc->name, input_format_desc->name); + + if (1) + { + for (i = 0; i < Elements(buffer); ++i) + { + unsigned format_size = (i & 1) ? output_format_size : input_format_size; + printf("%c ", (i == 2 || i == 4) ? '*' : ' '); + for (j = 0; j < count; ++j) + { + for (k = 0; k < format_size; ++k) + { + printf("%02x", buffer[i][j * format_size + k]); + } + printf(" "); + } + printf("\n"); + } + } + + if (!fail) + ++passed; + ++total; + + if(translate[1]) + translate[1]->release(translate[1]); + translate[0]->release(translate[0]); + } + } + + printf("%u/%u tests passed for translate_%s\n", passed, total, argv[1]); + return passed != total; +} diff --git a/src/gallium/tests/unit/u_format_compatible_test.c b/src/gallium/tests/unit/u_format_compatible_test.c new file mode 100644 index 00000000000..c655c35f20a --- /dev/null +++ b/src/gallium/tests/unit/u_format_compatible_test.c @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2009-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 <stdlib.h> +#include <stdio.h> + +#include "util/u_format.h" + + +static boolean +test_all(void) +{ + enum pipe_format src_format; + enum pipe_format dst_format; + + for (src_format = 1; src_format < PIPE_FORMAT_COUNT; ++src_format) { + const struct util_format_description *src_format_desc; + src_format_desc = util_format_description(src_format); + if (!src_format_desc) { + continue; + } + + for (dst_format = 1; dst_format < PIPE_FORMAT_COUNT; ++dst_format) { + const struct util_format_description *dst_format_desc; + dst_format_desc = util_format_description(dst_format); + if (!dst_format_desc) { + continue; + } + + if (dst_format == src_format) { + continue; + } + + if (util_is_format_compatible(src_format_desc, dst_format_desc)) { + debug_printf("%s -> %s\n", src_format_desc->short_name, dst_format_desc->short_name); + } + } + } + + return TRUE; +} + + +int main(int argc, char **argv) +{ + boolean success; + + success = test_all(); + + return success ? 0 : 1; +} |