Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 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_states( ctx, 0, 1, &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.    memset(&vbuf, 0, sizeof vbuf);
  91.  
  92.    vbuf.stride = sizeof(struct vertex);
  93.    vbuf.buffer_offset = 0;
  94.    vbuf.buffer = pipe_buffer_create_with_data(ctx,
  95.                                               PIPE_BIND_VERTEX_BUFFER,
  96.                                               PIPE_USAGE_STATIC,
  97.                                               sizeof(vertices),
  98.                                               vertices);
  99.  
  100.    ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
  101. }
  102.  
  103. static void set_vertex_shader( void )
  104. {
  105.    void *handle;
  106.    const char *text =
  107.       "VERT\n"
  108.       "DCL IN[0]\n"
  109.       "DCL IN[1]\n"
  110.       "DCL OUT[0], POSITION\n"
  111.       "DCL OUT[1], COLOR\n"
  112.       "  0: MOV OUT[1], IN[1]\n"
  113.       "  1: MOV OUT[0], IN[0]\n"
  114.       "  2: END\n";
  115.  
  116.    handle = graw_parse_vertex_shader(ctx, text);
  117.    ctx->bind_vs_state(ctx, handle);
  118. }
  119.  
  120.  
  121.  
  122. static void *
  123. set_fragment_shader( void )
  124. {
  125.    void *handle;
  126.    const char *text =
  127.       "FRAG\n"
  128.       "DCL IN[0], COLOR, LINEAR\n"
  129.       "DCL OUT[0], COLOR\n"
  130.       "DCL TEMP[0..1]\n"
  131.       "  0: MUL TEMP[0], IN[0], IN[0]\n"
  132.       "  1: ADD TEMP[1], IN[0], IN[0]\n"
  133.       "  2: SUB OUT[0], TEMP[0], TEMP[1]\n"
  134.       "  3: END\n";
  135.  
  136.    handle = graw_parse_fragment_shader(ctx, text);
  137.    return handle;
  138. }
  139.  
  140.  
  141. static void draw( void )
  142. {
  143.    union pipe_color_union clear_color = { {0,0,0,1} };
  144.    int i;
  145.  
  146.    printf("Creating %d shaders\n", num_iters);
  147.  
  148.    for (i = 0; i < num_iters; i++) {
  149.       void *fs = set_fragment_shader();
  150.  
  151.       ctx->bind_fs_state(ctx, fs);
  152.  
  153.       ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
  154.       util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1);
  155.       ctx->flush(ctx, NULL, 0);
  156.  
  157.       ctx->bind_fs_state(ctx, NULL);
  158.       ctx->delete_fs_state(ctx, fs);
  159.    }
  160.  
  161.    screen->flush_frontbuffer(screen, tex, 0, 0, window);
  162.    ctx->destroy(ctx);
  163.  
  164.    exit(0);
  165. }
  166.  
  167.  
  168. static void init( void )
  169. {
  170.    struct pipe_framebuffer_state fb;
  171.    struct pipe_resource templat;
  172.    struct pipe_surface surf_tmpl;
  173.    int i;
  174.  
  175.    /* It's hard to say whether window or screen should be created
  176.     * first.  Different environments would prefer one or the other.
  177.     *
  178.     * Also, no easy way of querying supported formats if the screen
  179.     * cannot be created first.
  180.     */
  181.    for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
  182.       screen = graw_create_window_and_screen(0, 0, 300, 300,
  183.                                              formats[i],
  184.                                              &window);
  185.       if (window && screen)
  186.          break;
  187.    }
  188.    if (!screen || !window) {
  189.       fprintf(stderr, "Unable to create window\n");
  190.       exit(1);
  191.    }
  192.  
  193.    ctx = screen->context_create(screen, NULL);
  194.    if (ctx == NULL)
  195.       exit(3);
  196.  
  197.    templat.target = PIPE_TEXTURE_2D;
  198.    templat.format = formats[i];
  199.    templat.width0 = WIDTH;
  200.    templat.height0 = HEIGHT;
  201.    templat.depth0 = 1;
  202.    templat.last_level = 0;
  203.    templat.nr_samples = 1;
  204.    templat.bind = (PIPE_BIND_RENDER_TARGET |
  205.                    PIPE_BIND_DISPLAY_TARGET);
  206.    
  207.    tex = screen->resource_create(screen, &templat);
  208.    if (tex == NULL) {
  209.       fprintf(stderr, "Unable to create screen texture!\n");
  210.       exit(4);
  211.    }
  212.  
  213.    surf_tmpl.format = templat.format;
  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.half_pixel_center = 1;
  254.       rasterizer.bottom_edge_rule = 1;
  255.       rasterizer.depth_clip = 1;
  256.       handle = ctx->create_rasterizer_state(ctx, &rasterizer);
  257.       ctx->bind_rasterizer_state(ctx, handle);
  258.    }
  259.  
  260.    set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
  261.    set_vertices();
  262.    set_vertex_shader();
  263.    if (0)
  264.       set_fragment_shader();
  265. }
  266.  
  267.  
  268. int main( int argc, char *argv[] )
  269. {
  270.    if (argc > 1)
  271.       num_iters = atoi(argv[1]);
  272.  
  273.    init();
  274.  
  275.    graw_set_display_func( draw );
  276.    graw_main_loop();
  277.    return 0;
  278. }
  279.