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. /* u_sampler_view_default_template */
  51. #include "util/u_sampler.h"
  52. /* debug_dump_surface_bmp */
  53. #include "util/u_debug.h"
  54. /* util_draw_vertex_buffer helper */
  55. #include "util/u_draw_quad.h"
  56. /* FREE & CALLOC_STRUCT */
  57. #include "util/u_memory.h"
  58. /* util_make_[fragment|vertex]_passthrough_shader */
  59. #include "util/u_simple_shaders.h"
  60. /* to get a hardware pipe driver */
  61. #include "pipe-loader/pipe_loader.h"
  62.  
  63. struct program
  64. {
  65.         struct pipe_loader_device *dev;
  66.         struct pipe_screen *screen;
  67.         struct pipe_context *pipe;
  68.         struct cso_context *cso;
  69.  
  70.         struct pipe_blend_state blend;
  71.         struct pipe_depth_stencil_alpha_state depthstencil;
  72.         struct pipe_rasterizer_state rasterizer;
  73.         struct pipe_sampler_state sampler;
  74.         struct pipe_viewport_state viewport;
  75.         struct pipe_framebuffer_state framebuffer;
  76.         struct pipe_vertex_element velem[2];
  77.  
  78.         void *vs;
  79.         void *fs;
  80.  
  81.         union pipe_color_union clear_color;
  82.  
  83.         struct pipe_resource *vbuf;
  84.         struct pipe_resource *target;
  85.         struct pipe_resource *tex;
  86.         struct pipe_sampler_view *view;
  87. };
  88.  
  89. static void init_prog(struct program *p)
  90. {
  91.         struct pipe_surface surf_tmpl;
  92.         int ret;
  93.  
  94.         /* find a hardware device */
  95.         ret = pipe_loader_probe(&p->dev, 1);
  96.         assert(ret);
  97.  
  98.         /* init a pipe screen */
  99.         p->screen = pipe_loader_create_screen(p->dev, PIPE_SEARCH_DIR);
  100.         assert(p->screen);
  101.  
  102.         /* create the pipe driver context and cso context */
  103.         p->pipe = p->screen->context_create(p->screen, NULL);
  104.         p->cso = cso_create_context(p->pipe);
  105.  
  106.         /* set clear color */
  107.         p->clear_color.f[0] = 0.3;
  108.         p->clear_color.f[1] = 0.1;
  109.         p->clear_color.f[2] = 0.3;
  110.         p->clear_color.f[3] = 1.0;
  111.  
  112.         /* vertex buffer */
  113.         {
  114.                 float vertices[4][2][4] = {
  115.                         {
  116.                                 { 0.9f, 0.9f, 0.0f, 1.0f },
  117.                                 { 1.0f, 1.0f, 0.0f, 1.0f }
  118.                         },
  119.                         {
  120.                                 { -0.9f, 0.9f, 0.0f, 1.0f },
  121.                                 {  0.0f, 1.0f, 0.0f, 1.0f }
  122.                         },
  123.                         {
  124.                                 { -0.9f, -0.9f, 0.0f, 1.0f },
  125.                                 {  0.0f,  0.0f, 1.0f, 1.0f }
  126.                         },
  127.                         {
  128.                                 { 0.9f, -0.9f, 0.0f, 1.0f },
  129.                                 { 1.0f,  0.0f, 1.0f, 1.0f }
  130.                         }
  131.                 };
  132.  
  133.                 p->vbuf = pipe_buffer_create(p->screen, PIPE_BIND_VERTEX_BUFFER,
  134.                                              PIPE_USAGE_DEFAULT, sizeof(vertices));
  135.                 pipe_buffer_write(p->pipe, p->vbuf, 0, sizeof(vertices), vertices);
  136.         }
  137.  
  138.         /* render target texture */
  139.         {
  140.                 struct pipe_resource tmplt;
  141.                 memset(&tmplt, 0, sizeof(tmplt));
  142.                 tmplt.target = PIPE_TEXTURE_2D;
  143.                 tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */
  144.                 tmplt.width0 = WIDTH;
  145.                 tmplt.height0 = HEIGHT;
  146.                 tmplt.depth0 = 1;
  147.                 tmplt.array_size = 1;
  148.                 tmplt.last_level = 0;
  149.                 tmplt.bind = PIPE_BIND_RENDER_TARGET;
  150.  
  151.                 p->target = p->screen->resource_create(p->screen, &tmplt);
  152.         }
  153.  
  154.         /* sampler texture */
  155.         {
  156.                 uint32_t *ptr;
  157.                 struct pipe_transfer *t;
  158.                 struct pipe_resource t_tmplt;
  159.                 struct pipe_sampler_view v_tmplt;
  160.                 struct pipe_box box;
  161.  
  162.                 memset(&t_tmplt, 0, sizeof(t_tmplt));
  163.                 t_tmplt.target = PIPE_TEXTURE_2D;
  164.                 t_tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */
  165.                 t_tmplt.width0 = 2;
  166.                 t_tmplt.height0 = 2;
  167.                 t_tmplt.depth0 = 1;
  168.                 t_tmplt.array_size = 1;
  169.                 t_tmplt.last_level = 0;
  170.                 t_tmplt.bind = PIPE_BIND_RENDER_TARGET;
  171.  
  172.                 p->tex = p->screen->resource_create(p->screen, &t_tmplt);
  173.  
  174.                 memset(&box, 0, sizeof(box));
  175.                 box.width = 2;
  176.                 box.height = 2;
  177.  
  178.                 ptr = p->pipe->transfer_map(p->pipe, p->tex, 0, PIPE_TRANSFER_WRITE, &box, &t);
  179.                 ptr[0] = 0xffff0000;
  180.                 ptr[1] = 0xff0000ff;
  181.                 ptr[2] = 0xff00ff00;
  182.                 ptr[3] = 0xffffff00;
  183.                 p->pipe->transfer_unmap(p->pipe, t);
  184.  
  185.                 u_sampler_view_default_template(&v_tmplt, p->tex, p->tex->format);
  186.  
  187.                 p->view = p->pipe->create_sampler_view(p->pipe, p->tex, &v_tmplt);
  188.         }
  189.  
  190.         /* disabled blending/masking */
  191.         memset(&p->blend, 0, sizeof(p->blend));
  192.         p->blend.rt[0].colormask = PIPE_MASK_RGBA;
  193.  
  194.         /* no-op depth/stencil/alpha */
  195.         memset(&p->depthstencil, 0, sizeof(p->depthstencil));
  196.  
  197.         /* rasterizer */
  198.         memset(&p->rasterizer, 0, sizeof(p->rasterizer));
  199.         p->rasterizer.cull_face = PIPE_FACE_NONE;
  200.         p->rasterizer.half_pixel_center = 1;
  201.         p->rasterizer.bottom_edge_rule = 1;
  202.         p->rasterizer.depth_clip = 1;
  203.  
  204.         /* sampler */
  205.         memset(&p->sampler, 0, sizeof(p->sampler));
  206.         p->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  207.         p->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  208.         p->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  209.         p->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  210.         p->sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
  211.         p->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
  212.         p->sampler.normalized_coords = 1;
  213.  
  214.         surf_tmpl.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */
  215.         surf_tmpl.u.tex.level = 0;
  216.         surf_tmpl.u.tex.first_layer = 0;
  217.         surf_tmpl.u.tex.last_layer = 0;
  218.         /* drawing destination */
  219.         memset(&p->framebuffer, 0, sizeof(p->framebuffer));
  220.         p->framebuffer.width = WIDTH;
  221.         p->framebuffer.height = HEIGHT;
  222.         p->framebuffer.nr_cbufs = 1;
  223.         p->framebuffer.cbufs[0] = p->pipe->create_surface(p->pipe, p->target, &surf_tmpl);
  224.  
  225.         /* viewport, depth isn't really needed */
  226.         {
  227.                 float x = 0;
  228.                 float y = 0;
  229.                 float z = FAR;
  230.                 float half_width = (float)WIDTH / 2.0f;
  231.                 float half_height = (float)HEIGHT / 2.0f;
  232.                 float half_depth = ((float)FAR - (float)NEAR) / 2.0f;
  233.                 float scale, bias;
  234.  
  235.                 if (FLIP) {
  236.                         scale = -1.0f;
  237.                         bias = (float)HEIGHT;
  238.                 } else {
  239.                         scale = 1.0f;
  240.                         bias = 0.0f;
  241.                 }
  242.  
  243.                 p->viewport.scale[0] = half_width;
  244.                 p->viewport.scale[1] = half_height * scale;
  245.                 p->viewport.scale[2] = half_depth;
  246.  
  247.                 p->viewport.translate[0] = half_width + x;
  248.                 p->viewport.translate[1] = (half_height + y) * scale + bias;
  249.                 p->viewport.translate[2] = half_depth + z;
  250.         }
  251.  
  252.         /* vertex elements state */
  253.         memset(p->velem, 0, sizeof(p->velem));
  254.         p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */
  255.         p->velem[0].instance_divisor = 0;
  256.         p->velem[0].vertex_buffer_index = 0;
  257.         p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  258.  
  259.         p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */
  260.         p->velem[1].instance_divisor = 0;
  261.         p->velem[1].vertex_buffer_index = 0;
  262.         p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  263.  
  264.         /* vertex shader */
  265.         {
  266.                 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  267.                                                 TGSI_SEMANTIC_GENERIC };
  268.                 const uint semantic_indexes[] = { 0, 0 };
  269.                 p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes, FALSE);
  270.         }
  271.  
  272.         /* fragment shader */
  273.         p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
  274. }
  275.  
  276. static void close_prog(struct program *p)
  277. {
  278.         cso_destroy_context(p->cso);
  279.  
  280.         p->pipe->delete_vs_state(p->pipe, p->vs);
  281.         p->pipe->delete_fs_state(p->pipe, p->fs);
  282.  
  283.         pipe_surface_reference(&p->framebuffer.cbufs[0], NULL);
  284.         pipe_sampler_view_reference(&p->view, NULL);
  285.         pipe_resource_reference(&p->target, NULL);
  286.         pipe_resource_reference(&p->tex, NULL);
  287.         pipe_resource_reference(&p->vbuf, NULL);
  288.  
  289.         p->pipe->destroy(p->pipe);
  290.         p->screen->destroy(p->screen);
  291.         pipe_loader_release(&p->dev, 1);
  292.  
  293.         FREE(p);
  294. }
  295.  
  296. static void draw(struct program *p)
  297. {
  298.         /* set the render target */
  299.         cso_set_framebuffer(p->cso, &p->framebuffer);
  300.  
  301.         /* clear the render target */
  302.         p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, &p->clear_color, 0, 0);
  303.  
  304.         /* set misc state we care about */
  305.         cso_set_blend(p->cso, &p->blend);
  306.         cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
  307.         cso_set_rasterizer(p->cso, &p->rasterizer);
  308.         cso_set_viewport(p->cso, &p->viewport);
  309.  
  310.         /* sampler */
  311.         cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler);
  312.         cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT);
  313.  
  314.         /* texture sampler view */
  315.         cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->view);
  316.  
  317.         /* shaders */
  318.         cso_set_fragment_shader_handle(p->cso, p->fs);
  319.         cso_set_vertex_shader_handle(p->cso, p->vs);
  320.  
  321.         /* vertex element data */
  322.         cso_set_vertex_elements(p->cso, 2, p->velem);
  323.  
  324.         util_draw_vertex_buffer(p->pipe, p->cso,
  325.                                 p->vbuf, 0, 0,
  326.                                 PIPE_PRIM_QUADS,
  327.                                 4,  /* verts */
  328.                                 2); /* attribs/vert */
  329.  
  330.         p->pipe->flush(p->pipe, NULL, 0);
  331.  
  332.         debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]);
  333. }
  334.  
  335. int main(int argc, char** argv)
  336. {
  337.         struct program *p = CALLOC_STRUCT(program);
  338.  
  339.         init_prog(p);
  340.         draw(p);
  341.         close_prog(p);
  342.  
  343.         return 0;
  344. }
  345.