Home | History | Annotate | Download | only in graw
      1 /**
      2  * Create shaders in a loop to test memory usage.
      3  */
      4 
      5 #include <stdio.h>
      6 #include "state_tracker/graw.h"
      7 #include "pipe/p_screen.h"
      8 #include "pipe/p_context.h"
      9 #include "pipe/p_state.h"
     10 #include "pipe/p_defines.h"
     11 
     12 #include "util/u_memory.h"      /* Offset() */
     13 #include "util/u_draw_quad.h"
     14 #include "util/u_inlines.h"
     15 
     16 
     17 static int num_iters = 100;
     18 
     19 
     20 enum pipe_format formats[] = {
     21    PIPE_FORMAT_RGBA8888_UNORM,
     22    PIPE_FORMAT_BGRA8888_UNORM,
     23    PIPE_FORMAT_NONE
     24 };
     25 
     26 static const int WIDTH = 300;
     27 static const int HEIGHT = 300;
     28 
     29 static struct pipe_screen *screen = NULL;
     30 static struct pipe_context *ctx = NULL;
     31 static struct pipe_surface *surf = NULL;
     32 static struct pipe_resource *tex = NULL;
     33 static void *window = NULL;
     34 
     35 struct vertex {
     36    float position[4];
     37    float color[4];
     38 };
     39 
     40 static struct vertex vertices[1] =
     41 {
     42    {
     43       { 0.0f, -0.9f, 0.0f, 1.0f },
     44       { 1.0f, 0.0f, 0.0f, 1.0f }
     45    }
     46 };
     47 
     48 
     49 
     50 
     51 static void set_viewport( float x, float y,
     52                           float width, float height,
     53                           float zNear, float zFar)
     54 {
     55    float z = zFar;
     56    float half_width = (float)width / 2.0f;
     57    float half_height = (float)height / 2.0f;
     58    float half_depth = ((float)zFar - (float)zNear) / 2.0f;
     59    struct pipe_viewport_state vp;
     60 
     61    vp.scale[0] = half_width;
     62    vp.scale[1] = half_height;
     63    vp.scale[2] = half_depth;
     64 
     65    vp.translate[0] = half_width + x;
     66    vp.translate[1] = half_height + y;
     67    vp.translate[2] = half_depth + z;
     68 
     69    ctx->set_viewport_states( ctx, 0, 1, &vp );
     70 }
     71 
     72 static void set_vertices( void )
     73 {
     74    struct pipe_vertex_element ve[2];
     75    struct pipe_vertex_buffer vbuf;
     76    void *handle;
     77 
     78    memset(ve, 0, sizeof ve);
     79 
     80    ve[0].src_offset = Offset(struct vertex, position);
     81    ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
     82    ve[1].src_offset = Offset(struct vertex, color);
     83    ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
     84 
     85    handle = ctx->create_vertex_elements_state(ctx, 2, ve);
     86    ctx->bind_vertex_elements_state(ctx, handle);
     87 
     88    memset(&vbuf, 0, sizeof vbuf);
     89 
     90    vbuf.stride = sizeof(struct vertex);
     91    vbuf.buffer_offset = 0;
     92    vbuf.buffer = pipe_buffer_create_with_data(ctx,
     93                                               PIPE_BIND_VERTEX_BUFFER,
     94                                               PIPE_USAGE_DEFAULT,
     95                                               sizeof(vertices),
     96                                               vertices);
     97 
     98    ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
     99 }
    100 
    101 static void set_vertex_shader( void )
    102 {
    103    void *handle;
    104    const char *text =
    105       "VERT\n"
    106       "DCL IN[0]\n"
    107       "DCL IN[1]\n"
    108       "DCL OUT[0], POSITION\n"
    109       "DCL OUT[1], COLOR\n"
    110       "  0: MOV OUT[1], IN[1]\n"
    111       "  1: MOV OUT[0], IN[0]\n"
    112       "  2: END\n";
    113 
    114    handle = graw_parse_vertex_shader(ctx, text);
    115    ctx->bind_vs_state(ctx, handle);
    116 }
    117 
    118 
    119 
    120 static void *
    121 set_fragment_shader( void )
    122 {
    123    void *handle;
    124    const char *text =
    125       "FRAG\n"
    126       "DCL IN[0], COLOR, LINEAR\n"
    127       "DCL OUT[0], COLOR\n"
    128       "DCL TEMP[0..1]\n"
    129       "  0: MUL TEMP[0], IN[0], IN[0]\n"
    130       "  1: ADD TEMP[1], IN[0], IN[0]\n"
    131       "  2: SUB OUT[0], TEMP[0], TEMP[1]\n"
    132       "  3: END\n";
    133 
    134    handle = graw_parse_fragment_shader(ctx, text);
    135    return handle;
    136 }
    137 
    138 
    139 static void draw( void )
    140 {
    141    union pipe_color_union clear_color = { {0,0,0,1} };
    142    int i;
    143 
    144    printf("Creating %d shaders\n", num_iters);
    145 
    146    for (i = 0; i < num_iters; i++) {
    147       void *fs = set_fragment_shader();
    148 
    149       ctx->bind_fs_state(ctx, fs);
    150 
    151       ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
    152       util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1);
    153       ctx->flush(ctx, NULL, 0);
    154 
    155       ctx->bind_fs_state(ctx, NULL);
    156       ctx->delete_fs_state(ctx, fs);
    157    }
    158 
    159    screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
    160    ctx->destroy(ctx);
    161 
    162    exit(0);
    163 }
    164 
    165 
    166 static void init( void )
    167 {
    168    struct pipe_framebuffer_state fb;
    169    struct pipe_resource templat;
    170    struct pipe_surface surf_tmpl;
    171    int i;
    172 
    173    /* It's hard to say whether window or screen should be created
    174     * first.  Different environments would prefer one or the other.
    175     *
    176     * Also, no easy way of querying supported formats if the screen
    177     * cannot be created first.
    178     */
    179    for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
    180       screen = graw_create_window_and_screen(0, 0, 300, 300,
    181                                              formats[i],
    182                                              &window);
    183       if (window && screen)
    184          break;
    185    }
    186    if (!screen || !window) {
    187       fprintf(stderr, "Unable to create window\n");
    188       exit(1);
    189    }
    190 
    191    ctx = screen->context_create(screen, NULL, 0);
    192    if (ctx == NULL)
    193       exit(3);
    194 
    195    memset(&templat, 0, sizeof(templat));
    196    templat.target = PIPE_TEXTURE_2D;
    197    templat.format = formats[i];
    198    templat.width0 = WIDTH;
    199    templat.height0 = HEIGHT;
    200    templat.depth0 = 1;
    201    templat.last_level = 0;
    202    templat.nr_samples = 1;
    203    templat.bind = (PIPE_BIND_RENDER_TARGET |
    204                    PIPE_BIND_DISPLAY_TARGET);
    205 
    206    tex = screen->resource_create(screen, &templat);
    207    if (tex == NULL) {
    208       fprintf(stderr, "Unable to create screen texture!\n");
    209       exit(4);
    210    }
    211 
    212    surf_tmpl.format = templat.format;
    213    surf_tmpl.u.tex.level = 0;
    214    surf_tmpl.u.tex.first_layer = 0;
    215    surf_tmpl.u.tex.last_layer = 0;
    216    surf = ctx->create_surface(ctx, tex, &surf_tmpl);
    217    if (surf == NULL) {
    218       fprintf(stderr, "Unable to create tex surface!\n");
    219       exit(5);
    220    }
    221 
    222    memset(&fb, 0, sizeof fb);
    223    fb.nr_cbufs = 1;
    224    fb.width = WIDTH;
    225    fb.height = HEIGHT;
    226    fb.cbufs[0] = surf;
    227 
    228    ctx->set_framebuffer_state(ctx, &fb);
    229 
    230    {
    231       struct pipe_blend_state blend;
    232       void *handle;
    233       memset(&blend, 0, sizeof blend);
    234       blend.rt[0].colormask = PIPE_MASK_RGBA;
    235       handle = ctx->create_blend_state(ctx, &blend);
    236       ctx->bind_blend_state(ctx, handle);
    237    }
    238 
    239    {
    240       struct pipe_depth_stencil_alpha_state depthstencil;
    241       void *handle;
    242       memset(&depthstencil, 0, sizeof depthstencil);
    243       handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
    244       ctx->bind_depth_stencil_alpha_state(ctx, handle);
    245    }
    246 
    247    {
    248       struct pipe_rasterizer_state rasterizer;
    249       void *handle;
    250       memset(&rasterizer, 0, sizeof rasterizer);
    251       rasterizer.cull_face = PIPE_FACE_NONE;
    252       rasterizer.half_pixel_center = 1;
    253       rasterizer.bottom_edge_rule = 1;
    254       rasterizer.depth_clip = 1;
    255       handle = ctx->create_rasterizer_state(ctx, &rasterizer);
    256       ctx->bind_rasterizer_state(ctx, handle);
    257    }
    258 
    259    set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
    260    set_vertices();
    261    set_vertex_shader();
    262    if (0)
    263       set_fragment_shader();
    264 }
    265 
    266 
    267 int main( int argc, char *argv[] )
    268 {
    269    if (argc > 1)
    270       num_iters = atoi(argv[1]);
    271 
    272    init();
    273 
    274    graw_set_display_func( draw );
    275    graw_main_loop();
    276    return 0;
    277 }
    278