Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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_STATIC, 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.                 p->viewport.scale[3] = 1.0f;
  247.  
  248.                 p->viewport.translate[0] = half_width + x;
  249.                 p->viewport.translate[1] = (half_height + y) * scale + bias;
  250.                 p->viewport.translate[2] = half_depth + z;
  251.                 p->viewport.translate[3] = 0.0f;
  252.         }
  253.  
  254.         /* vertex elements state */
  255.         memset(p->velem, 0, sizeof(p->velem));
  256.         p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */
  257.         p->velem[0].instance_divisor = 0;
  258.         p->velem[0].vertex_buffer_index = 0;
  259.         p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  260.  
  261.         p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */
  262.         p->velem[1].instance_divisor = 0;
  263.         p->velem[1].vertex_buffer_index = 0;
  264.         p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  265.  
  266.         /* vertex shader */
  267.         {
  268.                 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  269.                                                 TGSI_SEMANTIC_GENERIC };
  270.                 const uint semantic_indexes[] = { 0, 0 };
  271.                 p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes);
  272.         }
  273.  
  274.         /* fragment shader */
  275.         p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
  276. }
  277.  
  278. static void close_prog(struct program *p)
  279. {
  280.         /* unset bound textures as well */
  281.         cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
  282.  
  283.         /* unset all state */
  284.         cso_release_all(p->cso);
  285.  
  286.         p->pipe->delete_vs_state(p->pipe, p->vs);
  287.         p->pipe->delete_fs_state(p->pipe, p->fs);
  288.  
  289.         pipe_surface_reference(&p->framebuffer.cbufs[0], NULL);
  290.         pipe_sampler_view_reference(&p->view, NULL);
  291.         pipe_resource_reference(&p->target, NULL);
  292.         pipe_resource_reference(&p->tex, NULL);
  293.         pipe_resource_reference(&p->vbuf, NULL);
  294.  
  295.         cso_destroy_context(p->cso);
  296.         p->pipe->destroy(p->pipe);
  297.         p->screen->destroy(p->screen);
  298.         pipe_loader_release(&p->dev, 1);
  299.  
  300.         FREE(p);
  301. }
  302.  
  303. static void draw(struct program *p)
  304. {
  305.         /* set the render target */
  306.         cso_set_framebuffer(p->cso, &p->framebuffer);
  307.  
  308.         /* clear the render target */
  309.         p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, &p->clear_color, 0, 0);
  310.  
  311.         /* set misc state we care about */
  312.         cso_set_blend(p->cso, &p->blend);
  313.         cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
  314.         cso_set_rasterizer(p->cso, &p->rasterizer);
  315.         cso_set_viewport(p->cso, &p->viewport);
  316.  
  317.         /* sampler */
  318.         cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler);
  319.         cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT);
  320.  
  321.         /* texture sampler view */
  322.         cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->view);
  323.  
  324.         /* shaders */
  325.         cso_set_fragment_shader_handle(p->cso, p->fs);
  326.         cso_set_vertex_shader_handle(p->cso, p->vs);
  327.  
  328.         /* vertex element data */
  329.         cso_set_vertex_elements(p->cso, 2, p->velem);
  330.  
  331.         util_draw_vertex_buffer(p->pipe, p->cso,
  332.                                 p->vbuf, 0, 0,
  333.                                 PIPE_PRIM_QUADS,
  334.                                 4,  /* verts */
  335.                                 2); /* attribs/vert */
  336.  
  337.         p->pipe->flush(p->pipe, NULL, 0);
  338.  
  339.         debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]);
  340. }
  341.  
  342. int main(int argc, char** argv)
  343. {
  344.         struct program *p = CALLOC_STRUCT(program);
  345.  
  346.         init_prog(p);
  347.         draw(p);
  348.         close_prog(p);
  349.  
  350.         return 0;
  351. }
  352.