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_R8G8B8A8_UNORM,
     22    PIPE_FORMAT_B8G8R8A8_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 near, float far)
     54 {
     55    float z = far;
     56    float half_width = (float)width / 2.0f;
     57    float half_height = (float)height / 2.0f;
     58    float half_depth = ((float)far - (float)near) / 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    vp.scale[3] = 1.0f;
     65 
     66    vp.translate[0] = half_width + x;
     67    vp.translate[1] = half_height + y;
     68    vp.translate[2] = half_depth + z;
     69    vp.translate[3] = 0.0f;
     70 
     71    ctx->set_viewport_state( ctx, &vp );
     72 }
     73 
     74 static void set_vertices( void )
     75 {
     76    struct pipe_vertex_element ve[2];
     77    struct pipe_vertex_buffer vbuf;
     78    void *handle;
     79 
     80    memset(ve, 0, sizeof ve);
     81 
     82    ve[0].src_offset = Offset(struct vertex, position);
     83    ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
     84    ve[1].src_offset = Offset(struct vertex, color);
     85    ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
     86 
     87    handle = ctx->create_vertex_elements_state(ctx, 2, ve);
     88    ctx->bind_vertex_elements_state(ctx, handle);
     89 
     90 
     91    vbuf.stride = sizeof(struct vertex);
     92    vbuf.buffer_offset = 0;
     93    vbuf.buffer = pipe_buffer_create_with_data(ctx,
     94                                               PIPE_BIND_VERTEX_BUFFER,
     95                                               PIPE_USAGE_STATIC,
     96                                               sizeof(vertices),
     97                                               vertices);
     98 
     99    ctx->set_vertex_buffers(ctx, 1, &vbuf);
    100 }
    101 
    102 static void set_vertex_shader( void )
    103 {
    104    void *handle;
    105    const char *text =
    106       "VERT\n"
    107       "DCL IN[0]\n"
    108       "DCL IN[1]\n"
    109       "DCL OUT[0], POSITION\n"
    110       "DCL OUT[1], COLOR\n"
    111       "  0: MOV OUT[1], IN[1]\n"
    112       "  1: MOV OUT[0], IN[0]\n"
    113       "  2: END\n";
    114 
    115    handle = graw_parse_vertex_shader(ctx, text);
    116    ctx->bind_vs_state(ctx, handle);
    117 }
    118 
    119 
    120 
    121 static void *
    122 set_fragment_shader( void )
    123 {
    124    void *handle;
    125    const char *text =
    126       "FRAG\n"
    127       "DCL IN[0], COLOR, LINEAR\n"
    128       "DCL OUT[0], COLOR\n"
    129       "DCL TEMP[0..1]\n"
    130       "  0: MUL TEMP[0], IN[0], IN[0]\n"
    131       "  1: ADD TEMP[1], IN[0], IN[0]\n"
    132       "  2: SUB OUT[0], TEMP[0], TEMP[1]\n"
    133       "  3: END\n";
    134 
    135    handle = graw_parse_fragment_shader(ctx, text);
    136    return handle;
    137 }
    138 
    139 
    140 static void draw( void )
    141 {
    142    union pipe_color_union clear_color = { {0,0,0,1} };
    143    int i;
    144 
    145    printf("Creating %d shaders\n", num_iters);
    146 
    147    for (i = 0; i < num_iters; i++) {
    148       void *fs = set_fragment_shader();
    149 
    150       ctx->bind_fs_state(ctx, fs);
    151 
    152       ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
    153       util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1);
    154       ctx->flush(ctx, NULL);
    155 
    156       ctx->bind_fs_state(ctx, NULL);
    157       ctx->delete_fs_state(ctx, fs);
    158    }
    159 
    160    screen->flush_frontbuffer(screen, tex, 0, 0, window);
    161    ctx->destroy(ctx);
    162 
    163    exit(0);
    164 }
    165 
    166 
    167 static void init( void )
    168 {
    169    struct pipe_framebuffer_state fb;
    170    struct pipe_resource templat;
    171    struct pipe_surface surf_tmpl;
    172    int i;
    173 
    174    /* It's hard to say whether window or screen should be created
    175     * first.  Different environments would prefer one or the other.
    176     *
    177     * Also, no easy way of querying supported formats if the screen
    178     * cannot be created first.
    179     */
    180    for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
    181       screen = graw_create_window_and_screen(0, 0, 300, 300,
    182                                              formats[i],
    183                                              &window);
    184       if (window && screen)
    185          break;
    186    }
    187    if (!screen || !window) {
    188       fprintf(stderr, "Unable to create window\n");
    189       exit(1);
    190    }
    191 
    192    ctx = screen->context_create(screen, NULL);
    193    if (ctx == NULL)
    194       exit(3);
    195 
    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.usage = PIPE_BIND_RENDER_TARGET;
    214    surf_tmpl.u.tex.level = 0;
    215    surf_tmpl.u.tex.first_layer = 0;
    216    surf_tmpl.u.tex.last_layer = 0;
    217    surf = ctx->create_surface(ctx, tex, &surf_tmpl);
    218    if (surf == NULL) {
    219       fprintf(stderr, "Unable to create tex surface!\n");
    220       exit(5);
    221    }
    222 
    223    memset(&fb, 0, sizeof fb);
    224    fb.nr_cbufs = 1;
    225    fb.width = WIDTH;
    226    fb.height = HEIGHT;
    227    fb.cbufs[0] = surf;
    228 
    229    ctx->set_framebuffer_state(ctx, &fb);
    230 
    231    {
    232       struct pipe_blend_state blend;
    233       void *handle;
    234       memset(&blend, 0, sizeof blend);
    235       blend.rt[0].colormask = PIPE_MASK_RGBA;
    236       handle = ctx->create_blend_state(ctx, &blend);
    237       ctx->bind_blend_state(ctx, handle);
    238    }
    239 
    240    {
    241       struct pipe_depth_stencil_alpha_state depthstencil;
    242       void *handle;
    243       memset(&depthstencil, 0, sizeof depthstencil);
    244       handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
    245       ctx->bind_depth_stencil_alpha_state(ctx, handle);
    246    }
    247 
    248    {
    249       struct pipe_rasterizer_state rasterizer;
    250       void *handle;
    251       memset(&rasterizer, 0, sizeof rasterizer);
    252       rasterizer.cull_face = PIPE_FACE_NONE;
    253       rasterizer.gl_rasterization_rules = 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