Subversion Repositories Kolibri OS

Rev

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 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);
  192.    if (ctx == NULL)
  193.       exit(3);
  194.  
  195.    templat.target = PIPE_TEXTURE_2D;
  196.    templat.format = formats[i];
  197.    templat.width0 = WIDTH;
  198.    templat.height0 = HEIGHT;
  199.    templat.depth0 = 1;
  200.    templat.last_level = 0;
  201.    templat.nr_samples = 1;
  202.    templat.bind = (PIPE_BIND_RENDER_TARGET |
  203.                    PIPE_BIND_DISPLAY_TARGET);
  204.    
  205.    tex = screen->resource_create(screen, &templat);
  206.    if (tex == NULL) {
  207.       fprintf(stderr, "Unable to create screen texture!\n");
  208.       exit(4);
  209.    }
  210.  
  211.    surf_tmpl.format = templat.format;
  212.    surf_tmpl.u.tex.level = 0;
  213.    surf_tmpl.u.tex.first_layer = 0;
  214.    surf_tmpl.u.tex.last_layer = 0;
  215.    surf = ctx->create_surface(ctx, tex, &surf_tmpl);
  216.    if (surf == NULL) {
  217.       fprintf(stderr, "Unable to create tex surface!\n");
  218.       exit(5);
  219.    }
  220.  
  221.    memset(&fb, 0, sizeof fb);
  222.    fb.nr_cbufs = 1;
  223.    fb.width = WIDTH;
  224.    fb.height = HEIGHT;
  225.    fb.cbufs[0] = surf;
  226.  
  227.    ctx->set_framebuffer_state(ctx, &fb);
  228.    
  229.    {
  230.       struct pipe_blend_state blend;
  231.       void *handle;
  232.       memset(&blend, 0, sizeof blend);
  233.       blend.rt[0].colormask = PIPE_MASK_RGBA;
  234.       handle = ctx->create_blend_state(ctx, &blend);
  235.       ctx->bind_blend_state(ctx, handle);
  236.    }
  237.  
  238.    {
  239.       struct pipe_depth_stencil_alpha_state depthstencil;
  240.       void *handle;
  241.       memset(&depthstencil, 0, sizeof depthstencil);
  242.       handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
  243.       ctx->bind_depth_stencil_alpha_state(ctx, handle);
  244.    }
  245.  
  246.    {
  247.       struct pipe_rasterizer_state rasterizer;
  248.       void *handle;
  249.       memset(&rasterizer, 0, sizeof rasterizer);
  250.       rasterizer.cull_face = PIPE_FACE_NONE;
  251.       rasterizer.half_pixel_center = 1;
  252.       rasterizer.bottom_edge_rule = 1;
  253.       rasterizer.depth_clip = 1;
  254.       handle = ctx->create_rasterizer_state(ctx, &rasterizer);
  255.       ctx->bind_rasterizer_state(ctx, handle);
  256.    }
  257.  
  258.    set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
  259.    set_vertices();
  260.    set_vertex_shader();
  261.    if (0)
  262.       set_fragment_shader();
  263. }
  264.  
  265.  
  266. int main( int argc, char *argv[] )
  267. {
  268.    if (argc > 1)
  269.       num_iters = atoi(argv[1]);
  270.  
  271.    init();
  272.  
  273.    graw_set_display_func( draw );
  274.    graw_main_loop();
  275.    return 0;
  276. }
  277.