Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright © 2010 Jakob Bornecrantz
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  **************************************************************************/
  25.  
  26.  
  27. #define USE_TRACE 0
  28. #define WIDTH 300
  29. #define HEIGHT 300
  30. #define NEAR 30
  31. #define FAR 1000
  32. #define FLIP 0
  33.  
  34. /* pipe_*_state structs */
  35. #include "pipe/p_state.h"
  36. /* pipe_context */
  37. #include "pipe/p_context.h"
  38. /* pipe_screen */
  39. #include "pipe/p_screen.h"
  40. /* PIPE_* */
  41. #include "pipe/p_defines.h"
  42. /* TGSI_SEMANTIC_{POSITION|GENERIC} */
  43. #include "pipe/p_shader_tokens.h"
  44. /* pipe_buffer_* helpers */
  45. #include "util/u_inlines.h"
  46.  
  47. /* constant state object helper */
  48. #include "cso_cache/cso_context.h"
  49.  
  50. /* debug_dump_surface_bmp */
  51. #include "util/u_debug.h"
  52. /* util_draw_vertex_buffer helper */
  53. #include "util/u_draw_quad.h"
  54. /* FREE & CALLOC_STRUCT */
  55. #include "util/u_memory.h"
  56. /* util_make_[fragment|vertex]_passthrough_shader */
  57. #include "util/u_simple_shaders.h"
  58. /* to get a hardware pipe driver */
  59. #include "pipe-loader/pipe_loader.h"
  60.  
  61. struct program
  62. {
  63.         struct pipe_loader_device *dev;
  64.         struct pipe_screen *screen;
  65.         struct pipe_context *pipe;
  66.         struct cso_context *cso;
  67.  
  68.         struct pipe_blend_state blend;
  69.         struct pipe_depth_stencil_alpha_state depthstencil;
  70.         struct pipe_rasterizer_state rasterizer;
  71.         struct pipe_viewport_state viewport;
  72.         struct pipe_framebuffer_state framebuffer;
  73.         struct pipe_vertex_element velem[2];
  74.  
  75.         void *vs;
  76.         void *fs;
  77.  
  78.         union pipe_color_union clear_color;
  79.  
  80.         struct pipe_resource *vbuf;
  81.         struct pipe_resource *target;
  82. };
  83.  
  84. static void init_prog(struct program *p)
  85. {
  86.         struct pipe_surface surf_tmpl;
  87.         int ret;
  88.  
  89.         /* find a hardware device */
  90.         ret = pipe_loader_probe(&p->dev, 1);
  91.         assert(ret);
  92.  
  93.         /* init a pipe screen */
  94.         p->screen = pipe_loader_create_screen(p->dev, PIPE_SEARCH_DIR);
  95.         assert(p->screen);
  96.  
  97.         /* create the pipe driver context and cso context */
  98.         p->pipe = p->screen->context_create(p->screen, NULL);
  99.         p->cso = cso_create_context(p->pipe);
  100.  
  101.         /* set clear color */
  102.         p->clear_color.f[0] = 0.3;
  103.         p->clear_color.f[1] = 0.1;
  104.         p->clear_color.f[2] = 0.3;
  105.         p->clear_color.f[3] = 1.0;
  106.  
  107.         /* vertex buffer */
  108.         {
  109.                 float vertices[4][2][4] = {
  110.                         {
  111.                                 { 0.0f, -0.9f, 0.0f, 1.0f },
  112.                                 { 1.0f, 0.0f, 0.0f, 1.0f }
  113.                         },
  114.                         {
  115.                                 { -0.9f, 0.9f, 0.0f, 1.0f },
  116.                                 { 0.0f, 1.0f, 0.0f, 1.0f }
  117.                         },
  118.                         {
  119.                                 { 0.9f, 0.9f, 0.0f, 1.0f },
  120.                                 { 0.0f, 0.0f, 1.0f, 1.0f }
  121.                         }
  122.                 };
  123.  
  124.                 p->vbuf = pipe_buffer_create(p->screen, PIPE_BIND_VERTEX_BUFFER,
  125.                                              PIPE_USAGE_DEFAULT, sizeof(vertices));
  126.                 pipe_buffer_write(p->pipe, p->vbuf, 0, sizeof(vertices), vertices);
  127.         }
  128.  
  129.         /* render target texture */
  130.         {
  131.                 struct pipe_resource tmplt;
  132.                 memset(&tmplt, 0, sizeof(tmplt));
  133.                 tmplt.target = PIPE_TEXTURE_2D;
  134.                 tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */
  135.                 tmplt.width0 = WIDTH;
  136.                 tmplt.height0 = HEIGHT;
  137.                 tmplt.depth0 = 1;
  138.                 tmplt.array_size = 1;
  139.                 tmplt.last_level = 0;
  140.                 tmplt.bind = PIPE_BIND_RENDER_TARGET;
  141.  
  142.                 p->target = p->screen->resource_create(p->screen, &tmplt);
  143.         }
  144.  
  145.         /* disabled blending/masking */
  146.         memset(&p->blend, 0, sizeof(p->blend));
  147.         p->blend.rt[0].colormask = PIPE_MASK_RGBA;
  148.  
  149.         /* no-op depth/stencil/alpha */
  150.         memset(&p->depthstencil, 0, sizeof(p->depthstencil));
  151.  
  152.         /* rasterizer */
  153.         memset(&p->rasterizer, 0, sizeof(p->rasterizer));
  154.         p->rasterizer.cull_face = PIPE_FACE_NONE;
  155.         p->rasterizer.half_pixel_center = 1;
  156.         p->rasterizer.bottom_edge_rule = 1;
  157.         p->rasterizer.depth_clip = 1;
  158.  
  159.         surf_tmpl.format = PIPE_FORMAT_B8G8R8A8_UNORM;
  160.         surf_tmpl.u.tex.level = 0;
  161.         surf_tmpl.u.tex.first_layer = 0;
  162.         surf_tmpl.u.tex.last_layer = 0;
  163.         /* drawing destination */
  164.         memset(&p->framebuffer, 0, sizeof(p->framebuffer));
  165.         p->framebuffer.width = WIDTH;
  166.         p->framebuffer.height = HEIGHT;
  167.         p->framebuffer.nr_cbufs = 1;
  168.         p->framebuffer.cbufs[0] = p->pipe->create_surface(p->pipe, p->target, &surf_tmpl);
  169.  
  170.         /* viewport, depth isn't really needed */
  171.         {
  172.                 float x = 0;
  173.                 float y = 0;
  174.                 float z = FAR;
  175.                 float half_width = (float)WIDTH / 2.0f;
  176.                 float half_height = (float)HEIGHT / 2.0f;
  177.                 float half_depth = ((float)FAR - (float)NEAR) / 2.0f;
  178.                 float scale, bias;
  179.  
  180.                 if (FLIP) {
  181.                         scale = -1.0f;
  182.                         bias = (float)HEIGHT;
  183.                 } else {
  184.                         scale = 1.0f;
  185.                         bias = 0.0f;
  186.                 }
  187.  
  188.                 p->viewport.scale[0] = half_width;
  189.                 p->viewport.scale[1] = half_height * scale;
  190.                 p->viewport.scale[2] = half_depth;
  191.  
  192.                 p->viewport.translate[0] = half_width + x;
  193.                 p->viewport.translate[1] = (half_height + y) * scale + bias;
  194.                 p->viewport.translate[2] = half_depth + z;
  195.         }
  196.  
  197.         /* vertex elements state */
  198.         memset(p->velem, 0, sizeof(p->velem));
  199.         p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */
  200.         p->velem[0].instance_divisor = 0;
  201.         p->velem[0].vertex_buffer_index = 0;
  202.         p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  203.  
  204.         p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */
  205.         p->velem[1].instance_divisor = 0;
  206.         p->velem[1].vertex_buffer_index = 0;
  207.         p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  208.  
  209.         /* vertex shader */
  210.         {
  211.                         const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  212.                                                         TGSI_SEMANTIC_COLOR };
  213.                         const uint semantic_indexes[] = { 0, 0 };
  214.                         p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes, FALSE);
  215.         }
  216.  
  217.         /* fragment shader */
  218.         p->fs = util_make_fragment_passthrough_shader(p->pipe,
  219.                     TGSI_SEMANTIC_COLOR, TGSI_INTERPOLATE_PERSPECTIVE, TRUE);
  220. }
  221.  
  222. static void close_prog(struct program *p)
  223. {
  224.         cso_destroy_context(p->cso);
  225.  
  226.         p->pipe->delete_vs_state(p->pipe, p->vs);
  227.         p->pipe->delete_fs_state(p->pipe, p->fs);
  228.  
  229.         pipe_surface_reference(&p->framebuffer.cbufs[0], NULL);
  230.         pipe_resource_reference(&p->target, NULL);
  231.         pipe_resource_reference(&p->vbuf, NULL);
  232.  
  233.         p->pipe->destroy(p->pipe);
  234.         p->screen->destroy(p->screen);
  235.         pipe_loader_release(&p->dev, 1);
  236.  
  237.         FREE(p);
  238. }
  239.  
  240. static void draw(struct program *p)
  241. {
  242.         /* set the render target */
  243.         cso_set_framebuffer(p->cso, &p->framebuffer);
  244.  
  245.         /* clear the render target */
  246.         p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, &p->clear_color, 0, 0);
  247.  
  248.         /* set misc state we care about */
  249.         cso_set_blend(p->cso, &p->blend);
  250.         cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
  251.         cso_set_rasterizer(p->cso, &p->rasterizer);
  252.         cso_set_viewport(p->cso, &p->viewport);
  253.  
  254.         /* shaders */
  255.         cso_set_fragment_shader_handle(p->cso, p->fs);
  256.         cso_set_vertex_shader_handle(p->cso, p->vs);
  257.  
  258.         /* vertex element data */
  259.         cso_set_vertex_elements(p->cso, 2, p->velem);
  260.  
  261.         util_draw_vertex_buffer(p->pipe, p->cso,
  262.                                 p->vbuf, 0, 0,
  263.                                 PIPE_PRIM_TRIANGLES,
  264.                                 3,  /* verts */
  265.                                 2); /* attribs/vert */
  266.  
  267.         p->pipe->flush(p->pipe, NULL, 0);
  268.  
  269.         debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]);
  270. }
  271.  
  272. int main(int argc, char** argv)
  273. {
  274.         struct program *p = CALLOC_STRUCT(program);
  275.  
  276.         init_prog(p);
  277.         draw(p);
  278.         close_prog(p);
  279.  
  280.         return 0;
  281. }
  282.