Path: blob/21.2-virgl/src/gallium/tests/graw/fs-test.c
4565 views
/* Display a cleared blue window. This demo has no dependencies on1* any utility code, just the graw interface and gallium.2*/34#include "frontend/graw.h"5#include "pipe/p_screen.h"6#include "pipe/p_context.h"7#include "pipe/p_shader_tokens.h"8#include "pipe/p_state.h"9#include "pipe/p_defines.h"10#include <stdio.h> /* for fread(), etc */1112#include "util/u_inlines.h"13#include "util/u_memory.h" /* Offset() */14#include "util/u_draw_quad.h"15#include "util/u_box.h"1617static const char *filename = NULL;18unsigned show_fps = 0;192021static void usage(char *name)22{23fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);24#ifndef _WIN3225fprintf(stderr, "\n" );26fprintf(stderr, "options:\n");27fprintf(stderr, " -fps show frames per second\n");28#endif29}303132enum pipe_format formats[] = {33PIPE_FORMAT_RGBA8888_UNORM,34PIPE_FORMAT_BGRA8888_UNORM,35PIPE_FORMAT_NONE36};3738static const int WIDTH = 250;39static const int HEIGHT = 250;4041static struct pipe_screen *screen = NULL;42static struct pipe_context *ctx = NULL;43static struct pipe_resource *rttex = NULL;44static struct pipe_surface *surf = NULL;45static struct pipe_sampler_view *sv = NULL;46static void *sampler = NULL;47static void *window = NULL;48static struct pipe_resource *samptex = NULL;4950struct vertex {51float position[4];52float color[4];53float texcoord[4];54};5556/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension57* so that the final images are the same.58*/59static struct vertex vertices[] =60{61{ { 0.9, 0.9, 0.0, 1.0 },62{ 0, 0, 1, 1 },63{ 1, 1, 0, 1 } },6465{ { 0.9, -0.9, 0.0, 1.0 },66{ 1, 0, 0, 1 },67{ 1, -1, 0, 1 } },6869{ {-0.9, 0.0, 0.0, 1.0 },70{ 0, 1, 0, 1 },71{ -1, 0, 0, 1 } },72};7374static float constants1[] =75{ 0.4, 0, 0, 1,761, 1, 1, 1,772, 2, 2, 2,784, 8, 16, 32,79803, 0, 0, 0,810, .5, 0, 0,821, 0, 0, 1,830, 0, 0, 1,84851, 0, 0, 0.5,860, 1, 0, 0.5,870, 0, 1, 0,880, 0, 0, 1,89};909192static float constants2[] =93{ 1, 0, 0, 1,940, 1, 0, 1,950, 0, 1, 1,960, 0, 0, 0,97981, 1, 0, 1,991, .5, 0, 1,1001, 0, 0, 1,1010, 0, 0, 1,1021031, 0, 0, 0.5,1040, 1, 0, 0.5,1050, 0, 1, 0,1060, 0, 0, 1,107};108109static void init_fs_constbuf( void )110{111struct pipe_constant_buffer cb1;112struct pipe_constant_buffer cb2;113114memset(&cb1, 0, sizeof cb1);115cb1.buffer_size = sizeof constants1;116cb1.user_buffer = constants1;117118ctx->set_constant_buffer(ctx,119PIPE_SHADER_FRAGMENT, 0, false,120&cb1);121122memset(&cb2, 0, sizeof cb2);123cb2.buffer_size = sizeof constants2;124cb2.user_buffer = constants2;125126ctx->set_constant_buffer(ctx,127PIPE_SHADER_FRAGMENT, 1, false,128&cb2);129}130131132static void set_viewport( float x, float y,133float width, float height,134float zNear, float zFar)135{136float z = zFar;137float half_width = (float)width / 2.0f;138float half_height = (float)height / 2.0f;139float half_depth = ((float)zFar - (float)zNear) / 2.0f;140struct pipe_viewport_state vp;141142vp.scale[0] = half_width;143vp.scale[1] = half_height;144vp.scale[2] = half_depth;145146vp.translate[0] = half_width + x;147vp.translate[1] = half_height + y;148vp.translate[2] = half_depth + z;149150vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;151vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;152vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;153vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;154155ctx->set_viewport_states( ctx, 0, 1, &vp );156}157158static void set_vertices( void )159{160struct pipe_vertex_element ve[3];161struct pipe_vertex_buffer vbuf;162void *handle;163164memset(ve, 0, sizeof ve);165166ve[0].src_offset = Offset(struct vertex, position);167ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;168ve[1].src_offset = Offset(struct vertex, color);169ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;170ve[2].src_offset = Offset(struct vertex, texcoord);171ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;172173handle = ctx->create_vertex_elements_state(ctx, 3, ve);174ctx->bind_vertex_elements_state(ctx, handle);175176memset(&vbuf, 0, sizeof vbuf);177178vbuf.stride = sizeof( struct vertex );179vbuf.buffer_offset = 0;180vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,181PIPE_BIND_VERTEX_BUFFER,182PIPE_USAGE_DEFAULT,183sizeof(vertices),184vertices);185186ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf);187}188189static void set_vertex_shader( void )190{191void *handle;192const char *text =193"VERT\n"194"DCL IN[0]\n"195"DCL IN[1]\n"196"DCL IN[2]\n"197"DCL OUT[0], POSITION\n"198"DCL OUT[1], COLOR[0]\n"199"DCL OUT[2], GENERIC[0]\n"200" MOV OUT[0], IN[0]\n"201" MOV OUT[1], IN[1]\n"202" MOV OUT[2], IN[2]\n"203" END\n";204205handle = graw_parse_vertex_shader(ctx, text);206ctx->bind_vs_state(ctx, handle);207}208209static void set_fragment_shader( const char *filename )210{211FILE *f;212char buf[50000];213void *handle;214int sz;215216if ((f = fopen(filename, "r")) == NULL) {217fprintf(stderr, "Couldn't open %s\n", filename);218exit(1);219}220221sz = fread(buf, 1, sizeof(buf), f);222if (!feof(f)) {223printf("file too long\n");224exit(1);225}226printf("%.*s\n", sz, buf);227buf[sz] = 0;228229handle = graw_parse_fragment_shader(ctx, buf);230ctx->bind_fs_state(ctx, handle);231fclose(f);232}233234235static void draw( void )236{237union pipe_color_union clear_color = { {.1,.3,.5,0} };238239ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);240util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);241ctx->flush(ctx, NULL, 0);242243graw_save_surface_to_file(ctx, surf, NULL);244245screen->flush_frontbuffer(screen, ctx, rttex, 0, 0, window, NULL);246}247248#define SIZE 16249250static void init_tex( void )251{252struct pipe_sampler_view sv_template;253struct pipe_sampler_state sampler_desc;254struct pipe_resource templat;255struct pipe_box box;256ubyte tex2d[SIZE][SIZE][4];257int s, t;258259#if (SIZE != 2)260for (s = 0; s < SIZE; s++) {261for (t = 0; t < SIZE; t++) {262if (0) {263int x = (s ^ t) & 1;264tex2d[t][s][0] = (x) ? 0 : 63;265tex2d[t][s][1] = (x) ? 0 : 128;266tex2d[t][s][2] = 0;267tex2d[t][s][3] = 0xff;268}269else {270int x = ((s ^ t) >> 2) & 1;271tex2d[t][s][0] = s*255/(SIZE-1);272tex2d[t][s][1] = t*255/(SIZE-1);273tex2d[t][s][2] = (x) ? 0 : 128;274tex2d[t][s][3] = 0xff;275}276}277}278#else279tex2d[0][0][0] = 0;280tex2d[0][0][1] = 255;281tex2d[0][0][2] = 255;282tex2d[0][0][3] = 0;283284tex2d[0][1][0] = 0;285tex2d[0][1][1] = 0;286tex2d[0][1][2] = 255;287tex2d[0][1][3] = 255;288289tex2d[1][0][0] = 255;290tex2d[1][0][1] = 255;291tex2d[1][0][2] = 0;292tex2d[1][0][3] = 255;293294tex2d[1][1][0] = 255;295tex2d[1][1][1] = 0;296tex2d[1][1][2] = 0;297tex2d[1][1][3] = 255;298#endif299300memset(&templat, 0, sizeof(templat));301templat.target = PIPE_TEXTURE_2D;302templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;303templat.width0 = SIZE;304templat.height0 = SIZE;305templat.depth0 = 1;306templat.array_size = 1;307templat.last_level = 0;308templat.bind = PIPE_BIND_SAMPLER_VIEW;309310311samptex = screen->resource_create(screen,312&templat);313if (samptex == NULL)314exit(4);315316u_box_2d(0,0,SIZE,SIZE, &box);317318ctx->texture_subdata(ctx,319samptex,3200,321PIPE_MAP_WRITE,322&box,323tex2d,324sizeof tex2d[0],325sizeof tex2d);326327/* Possibly read back & compare against original data:328*/329if (0)330{331struct pipe_transfer *t;332uint32_t *ptr;333ptr = pipe_texture_map(ctx, samptex,3340, 0, /* level, layer */335PIPE_MAP_READ,3360, 0, SIZE, SIZE, &t); /* x, y, width, height */337338if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {339assert(0);340exit(9);341}342343ctx->texture_unmap(ctx, t);344}345346memset(&sv_template, 0, sizeof sv_template);347sv_template.format = samptex->format;348sv_template.texture = samptex;349sv_template.swizzle_r = 0;350sv_template.swizzle_g = 1;351sv_template.swizzle_b = 2;352sv_template.swizzle_a = 3;353sv = ctx->create_sampler_view(ctx, samptex, &sv_template);354if (sv == NULL)355exit(5);356357ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, 0, &sv);358359360memset(&sampler_desc, 0, sizeof sampler_desc);361sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;362sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;363sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;364sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;365sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;366sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;367sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;368sampler_desc.compare_func = 0;369sampler_desc.normalized_coords = 1;370sampler_desc.max_anisotropy = 0;371372sampler = ctx->create_sampler_state(ctx, &sampler_desc);373if (sampler == NULL)374exit(6);375376ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);377378}379380static void init( void )381{382struct pipe_framebuffer_state fb;383struct pipe_resource templat;384struct pipe_surface surf_tmpl;385int i;386387/* It's hard to say whether window or screen should be created388* first. Different environments would prefer one or the other.389*390* Also, no easy way of querying supported formats if the screen391* cannot be created first.392*/393for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {394screen = graw_create_window_and_screen(0, 0, 300, 300,395formats[i],396&window);397if (window && screen)398break;399}400if (!screen || !window) {401fprintf(stderr, "Unable to create window\n");402exit(1);403}404405ctx = screen->context_create(screen, NULL, 0);406if (ctx == NULL)407exit(3);408409memset(&templat, 0, sizeof(templat));410templat.target = PIPE_TEXTURE_2D;411templat.format = formats[i];412templat.width0 = WIDTH;413templat.height0 = HEIGHT;414templat.depth0 = 1;415templat.array_size = 1;416templat.last_level = 0;417templat.bind = (PIPE_BIND_RENDER_TARGET |418PIPE_BIND_DISPLAY_TARGET);419420rttex = screen->resource_create(screen,421&templat);422if (rttex == NULL)423exit(4);424425surf_tmpl.format = templat.format;426surf_tmpl.u.tex.level = 0;427surf_tmpl.u.tex.first_layer = 0;428surf_tmpl.u.tex.last_layer = 0;429surf = ctx->create_surface(ctx, rttex, &surf_tmpl);430if (surf == NULL)431exit(5);432433memset(&fb, 0, sizeof fb);434fb.nr_cbufs = 1;435fb.width = WIDTH;436fb.height = HEIGHT;437fb.cbufs[0] = surf;438439ctx->set_framebuffer_state(ctx, &fb);440441{442struct pipe_blend_state blend;443void *handle;444memset(&blend, 0, sizeof blend);445blend.rt[0].colormask = PIPE_MASK_RGBA;446handle = ctx->create_blend_state(ctx, &blend);447ctx->bind_blend_state(ctx, handle);448}449450{451struct pipe_depth_stencil_alpha_state depthstencil;452void *handle;453memset(&depthstencil, 0, sizeof depthstencil);454handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);455ctx->bind_depth_stencil_alpha_state(ctx, handle);456}457458{459struct pipe_rasterizer_state rasterizer;460void *handle;461memset(&rasterizer, 0, sizeof rasterizer);462rasterizer.cull_face = PIPE_FACE_NONE;463rasterizer.half_pixel_center = 1;464rasterizer.bottom_edge_rule = 1;465rasterizer.depth_clip_near = 1;466rasterizer.depth_clip_far = 1;467handle = ctx->create_rasterizer_state(ctx, &rasterizer);468ctx->bind_rasterizer_state(ctx, handle);469}470471set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);472473init_tex();474init_fs_constbuf();475476set_vertices();477set_vertex_shader();478set_fragment_shader(filename);479}480481static void args(int argc, char *argv[])482{483int i;484485for (i = 1; i < argc;) {486if (graw_parse_args(&i, argc, argv)) {487continue;488}489if (strcmp(argv[i], "-fps") == 0) {490show_fps = 1;491i++;492}493else if (i == argc - 1) {494filename = argv[i];495i++;496}497else {498usage(argv[0]);499exit(1);500}501}502503if (!filename) {504usage(argv[0]);505exit(1);506}507}508509int main( int argc, char *argv[] )510{511args(argc,argv);512init();513514graw_set_display_func( draw );515graw_main_loop();516return 0;517}518519520