13464ebd5Sriastradh/** 23464ebd5Sriastradh * Create shaders in a loop to test memory usage. 33464ebd5Sriastradh */ 43464ebd5Sriastradh 53464ebd5Sriastradh#include <stdio.h> 67ec681f3Smrg#include "frontend/graw.h" 73464ebd5Sriastradh#include "pipe/p_screen.h" 83464ebd5Sriastradh#include "pipe/p_context.h" 93464ebd5Sriastradh#include "pipe/p_state.h" 103464ebd5Sriastradh#include "pipe/p_defines.h" 113464ebd5Sriastradh 123464ebd5Sriastradh#include "util/u_memory.h" /* Offset() */ 133464ebd5Sriastradh#include "util/u_draw_quad.h" 14af69d88dSmrg#include "util/u_inlines.h" 153464ebd5Sriastradh 163464ebd5Sriastradh 173464ebd5Sriastradhstatic int num_iters = 100; 183464ebd5Sriastradh 193464ebd5Sriastradh 203464ebd5Sriastradhenum pipe_format formats[] = { 21af69d88dSmrg PIPE_FORMAT_RGBA8888_UNORM, 22af69d88dSmrg PIPE_FORMAT_BGRA8888_UNORM, 233464ebd5Sriastradh PIPE_FORMAT_NONE 243464ebd5Sriastradh}; 253464ebd5Sriastradh 263464ebd5Sriastradhstatic const int WIDTH = 300; 273464ebd5Sriastradhstatic const int HEIGHT = 300; 283464ebd5Sriastradh 293464ebd5Sriastradhstatic struct pipe_screen *screen = NULL; 303464ebd5Sriastradhstatic struct pipe_context *ctx = NULL; 313464ebd5Sriastradhstatic struct pipe_surface *surf = NULL; 323464ebd5Sriastradhstatic struct pipe_resource *tex = NULL; 333464ebd5Sriastradhstatic void *window = NULL; 343464ebd5Sriastradh 353464ebd5Sriastradhstruct vertex { 363464ebd5Sriastradh float position[4]; 373464ebd5Sriastradh float color[4]; 383464ebd5Sriastradh}; 393464ebd5Sriastradh 403464ebd5Sriastradhstatic struct vertex vertices[1] = 413464ebd5Sriastradh{ 423464ebd5Sriastradh { 433464ebd5Sriastradh { 0.0f, -0.9f, 0.0f, 1.0f }, 443464ebd5Sriastradh { 1.0f, 0.0f, 0.0f, 1.0f } 453464ebd5Sriastradh } 463464ebd5Sriastradh}; 473464ebd5Sriastradh 483464ebd5Sriastradh 493464ebd5Sriastradh 503464ebd5Sriastradh 513464ebd5Sriastradhstatic void set_viewport( float x, float y, 523464ebd5Sriastradh float width, float height, 5301e04c3fSmrg float zNear, float zFar) 543464ebd5Sriastradh{ 5501e04c3fSmrg float z = zFar; 563464ebd5Sriastradh float half_width = (float)width / 2.0f; 573464ebd5Sriastradh float half_height = (float)height / 2.0f; 5801e04c3fSmrg float half_depth = ((float)zFar - (float)zNear) / 2.0f; 593464ebd5Sriastradh struct pipe_viewport_state vp; 603464ebd5Sriastradh 613464ebd5Sriastradh vp.scale[0] = half_width; 623464ebd5Sriastradh vp.scale[1] = half_height; 633464ebd5Sriastradh vp.scale[2] = half_depth; 643464ebd5Sriastradh 653464ebd5Sriastradh vp.translate[0] = half_width + x; 663464ebd5Sriastradh vp.translate[1] = half_height + y; 673464ebd5Sriastradh vp.translate[2] = half_depth + z; 683464ebd5Sriastradh 697ec681f3Smrg vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 707ec681f3Smrg vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 717ec681f3Smrg vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 727ec681f3Smrg vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 737ec681f3Smrg 74af69d88dSmrg ctx->set_viewport_states( ctx, 0, 1, &vp ); 753464ebd5Sriastradh} 763464ebd5Sriastradh 773464ebd5Sriastradhstatic void set_vertices( void ) 783464ebd5Sriastradh{ 793464ebd5Sriastradh struct pipe_vertex_element ve[2]; 803464ebd5Sriastradh struct pipe_vertex_buffer vbuf; 813464ebd5Sriastradh void *handle; 823464ebd5Sriastradh 833464ebd5Sriastradh memset(ve, 0, sizeof ve); 843464ebd5Sriastradh 853464ebd5Sriastradh ve[0].src_offset = Offset(struct vertex, position); 863464ebd5Sriastradh ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 873464ebd5Sriastradh ve[1].src_offset = Offset(struct vertex, color); 883464ebd5Sriastradh ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 893464ebd5Sriastradh 903464ebd5Sriastradh handle = ctx->create_vertex_elements_state(ctx, 2, ve); 913464ebd5Sriastradh ctx->bind_vertex_elements_state(ctx, handle); 923464ebd5Sriastradh 93af69d88dSmrg memset(&vbuf, 0, sizeof vbuf); 943464ebd5Sriastradh 953464ebd5Sriastradh vbuf.stride = sizeof(struct vertex); 963464ebd5Sriastradh vbuf.buffer_offset = 0; 9701e04c3fSmrg vbuf.buffer.resource = pipe_buffer_create_with_data(ctx, 98af69d88dSmrg PIPE_BIND_VERTEX_BUFFER, 99af69d88dSmrg PIPE_USAGE_DEFAULT, 100af69d88dSmrg sizeof(vertices), 101af69d88dSmrg vertices); 1023464ebd5Sriastradh 1037ec681f3Smrg ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); 1043464ebd5Sriastradh} 1053464ebd5Sriastradh 1063464ebd5Sriastradhstatic void set_vertex_shader( void ) 1073464ebd5Sriastradh{ 1083464ebd5Sriastradh void *handle; 1093464ebd5Sriastradh const char *text = 1103464ebd5Sriastradh "VERT\n" 1113464ebd5Sriastradh "DCL IN[0]\n" 1123464ebd5Sriastradh "DCL IN[1]\n" 1133464ebd5Sriastradh "DCL OUT[0], POSITION\n" 1143464ebd5Sriastradh "DCL OUT[1], COLOR\n" 1153464ebd5Sriastradh " 0: MOV OUT[1], IN[1]\n" 1163464ebd5Sriastradh " 1: MOV OUT[0], IN[0]\n" 1173464ebd5Sriastradh " 2: END\n"; 1183464ebd5Sriastradh 1193464ebd5Sriastradh handle = graw_parse_vertex_shader(ctx, text); 1203464ebd5Sriastradh ctx->bind_vs_state(ctx, handle); 1213464ebd5Sriastradh} 1223464ebd5Sriastradh 1233464ebd5Sriastradh 1243464ebd5Sriastradh 1253464ebd5Sriastradhstatic void * 1263464ebd5Sriastradhset_fragment_shader( void ) 1273464ebd5Sriastradh{ 1283464ebd5Sriastradh void *handle; 1293464ebd5Sriastradh const char *text = 1303464ebd5Sriastradh "FRAG\n" 1313464ebd5Sriastradh "DCL IN[0], COLOR, LINEAR\n" 1323464ebd5Sriastradh "DCL OUT[0], COLOR\n" 1333464ebd5Sriastradh "DCL TEMP[0..1]\n" 1343464ebd5Sriastradh " 0: MUL TEMP[0], IN[0], IN[0]\n" 1353464ebd5Sriastradh " 1: ADD TEMP[1], IN[0], IN[0]\n" 1363464ebd5Sriastradh " 2: SUB OUT[0], TEMP[0], TEMP[1]\n" 1373464ebd5Sriastradh " 3: END\n"; 1383464ebd5Sriastradh 1393464ebd5Sriastradh handle = graw_parse_fragment_shader(ctx, text); 1403464ebd5Sriastradh return handle; 1413464ebd5Sriastradh} 1423464ebd5Sriastradh 1433464ebd5Sriastradh 1443464ebd5Sriastradhstatic void draw( void ) 1453464ebd5Sriastradh{ 146af69d88dSmrg union pipe_color_union clear_color = { {0,0,0,1} }; 1473464ebd5Sriastradh int i; 1483464ebd5Sriastradh 1493464ebd5Sriastradh printf("Creating %d shaders\n", num_iters); 1503464ebd5Sriastradh 1513464ebd5Sriastradh for (i = 0; i < num_iters; i++) { 1523464ebd5Sriastradh void *fs = set_fragment_shader(); 1533464ebd5Sriastradh 1543464ebd5Sriastradh ctx->bind_fs_state(ctx, fs); 1553464ebd5Sriastradh 1567ec681f3Smrg ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0); 1573464ebd5Sriastradh util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1); 158af69d88dSmrg ctx->flush(ctx, NULL, 0); 1593464ebd5Sriastradh 1603464ebd5Sriastradh ctx->bind_fs_state(ctx, NULL); 1613464ebd5Sriastradh ctx->delete_fs_state(ctx, fs); 1623464ebd5Sriastradh } 1633464ebd5Sriastradh 1647ec681f3Smrg screen->flush_frontbuffer(screen, ctx, tex, 0, 0, window, NULL); 1653464ebd5Sriastradh ctx->destroy(ctx); 1663464ebd5Sriastradh 1673464ebd5Sriastradh exit(0); 1683464ebd5Sriastradh} 1693464ebd5Sriastradh 1703464ebd5Sriastradh 1713464ebd5Sriastradhstatic void init( void ) 1723464ebd5Sriastradh{ 1733464ebd5Sriastradh struct pipe_framebuffer_state fb; 1743464ebd5Sriastradh struct pipe_resource templat; 1753464ebd5Sriastradh struct pipe_surface surf_tmpl; 1763464ebd5Sriastradh int i; 1773464ebd5Sriastradh 1783464ebd5Sriastradh /* It's hard to say whether window or screen should be created 1793464ebd5Sriastradh * first. Different environments would prefer one or the other. 1803464ebd5Sriastradh * 1813464ebd5Sriastradh * Also, no easy way of querying supported formats if the screen 1823464ebd5Sriastradh * cannot be created first. 1833464ebd5Sriastradh */ 1843464ebd5Sriastradh for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) { 1853464ebd5Sriastradh screen = graw_create_window_and_screen(0, 0, 300, 300, 1863464ebd5Sriastradh formats[i], 1873464ebd5Sriastradh &window); 1883464ebd5Sriastradh if (window && screen) 1893464ebd5Sriastradh break; 1903464ebd5Sriastradh } 1913464ebd5Sriastradh if (!screen || !window) { 1923464ebd5Sriastradh fprintf(stderr, "Unable to create window\n"); 1933464ebd5Sriastradh exit(1); 1943464ebd5Sriastradh } 1953464ebd5Sriastradh 19601e04c3fSmrg ctx = screen->context_create(screen, NULL, 0); 1973464ebd5Sriastradh if (ctx == NULL) 1983464ebd5Sriastradh exit(3); 1993464ebd5Sriastradh 20001e04c3fSmrg memset(&templat, 0, sizeof(templat)); 2013464ebd5Sriastradh templat.target = PIPE_TEXTURE_2D; 2023464ebd5Sriastradh templat.format = formats[i]; 2033464ebd5Sriastradh templat.width0 = WIDTH; 2043464ebd5Sriastradh templat.height0 = HEIGHT; 2053464ebd5Sriastradh templat.depth0 = 1; 2063464ebd5Sriastradh templat.last_level = 0; 2073464ebd5Sriastradh templat.bind = (PIPE_BIND_RENDER_TARGET | 2083464ebd5Sriastradh PIPE_BIND_DISPLAY_TARGET); 2093464ebd5Sriastradh 2103464ebd5Sriastradh tex = screen->resource_create(screen, &templat); 2113464ebd5Sriastradh if (tex == NULL) { 2123464ebd5Sriastradh fprintf(stderr, "Unable to create screen texture!\n"); 2133464ebd5Sriastradh exit(4); 2143464ebd5Sriastradh } 2153464ebd5Sriastradh 2163464ebd5Sriastradh surf_tmpl.format = templat.format; 2173464ebd5Sriastradh surf_tmpl.u.tex.level = 0; 2183464ebd5Sriastradh surf_tmpl.u.tex.first_layer = 0; 2193464ebd5Sriastradh surf_tmpl.u.tex.last_layer = 0; 2203464ebd5Sriastradh surf = ctx->create_surface(ctx, tex, &surf_tmpl); 2213464ebd5Sriastradh if (surf == NULL) { 2223464ebd5Sriastradh fprintf(stderr, "Unable to create tex surface!\n"); 2233464ebd5Sriastradh exit(5); 2243464ebd5Sriastradh } 2253464ebd5Sriastradh 2263464ebd5Sriastradh memset(&fb, 0, sizeof fb); 2273464ebd5Sriastradh fb.nr_cbufs = 1; 2283464ebd5Sriastradh fb.width = WIDTH; 2293464ebd5Sriastradh fb.height = HEIGHT; 2303464ebd5Sriastradh fb.cbufs[0] = surf; 2313464ebd5Sriastradh 2323464ebd5Sriastradh ctx->set_framebuffer_state(ctx, &fb); 2333464ebd5Sriastradh 2343464ebd5Sriastradh { 2353464ebd5Sriastradh struct pipe_blend_state blend; 2363464ebd5Sriastradh void *handle; 2373464ebd5Sriastradh memset(&blend, 0, sizeof blend); 2383464ebd5Sriastradh blend.rt[0].colormask = PIPE_MASK_RGBA; 2393464ebd5Sriastradh handle = ctx->create_blend_state(ctx, &blend); 2403464ebd5Sriastradh ctx->bind_blend_state(ctx, handle); 2413464ebd5Sriastradh } 2423464ebd5Sriastradh 2433464ebd5Sriastradh { 2443464ebd5Sriastradh struct pipe_depth_stencil_alpha_state depthstencil; 2453464ebd5Sriastradh void *handle; 2463464ebd5Sriastradh memset(&depthstencil, 0, sizeof depthstencil); 2473464ebd5Sriastradh handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); 2483464ebd5Sriastradh ctx->bind_depth_stencil_alpha_state(ctx, handle); 2493464ebd5Sriastradh } 2503464ebd5Sriastradh 2513464ebd5Sriastradh { 2523464ebd5Sriastradh struct pipe_rasterizer_state rasterizer; 2533464ebd5Sriastradh void *handle; 2543464ebd5Sriastradh memset(&rasterizer, 0, sizeof rasterizer); 2553464ebd5Sriastradh rasterizer.cull_face = PIPE_FACE_NONE; 256af69d88dSmrg rasterizer.half_pixel_center = 1; 257af69d88dSmrg rasterizer.bottom_edge_rule = 1; 25801e04c3fSmrg rasterizer.depth_clip_near = 1; 25901e04c3fSmrg rasterizer.depth_clip_far = 1; 2603464ebd5Sriastradh handle = ctx->create_rasterizer_state(ctx, &rasterizer); 2613464ebd5Sriastradh ctx->bind_rasterizer_state(ctx, handle); 2623464ebd5Sriastradh } 2633464ebd5Sriastradh 2643464ebd5Sriastradh set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); 2653464ebd5Sriastradh set_vertices(); 2663464ebd5Sriastradh set_vertex_shader(); 2673464ebd5Sriastradh if (0) 2683464ebd5Sriastradh set_fragment_shader(); 2693464ebd5Sriastradh} 2703464ebd5Sriastradh 2713464ebd5Sriastradh 2723464ebd5Sriastradhint main( int argc, char *argv[] ) 2733464ebd5Sriastradh{ 2743464ebd5Sriastradh if (argc > 1) 2753464ebd5Sriastradh num_iters = atoi(argv[1]); 2763464ebd5Sriastradh 2773464ebd5Sriastradh init(); 2783464ebd5Sriastradh 2793464ebd5Sriastradh graw_set_display_func( draw ); 2803464ebd5Sriastradh graw_main_loop(); 2813464ebd5Sriastradh return 0; 2823464ebd5Sriastradh} 283