Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #include "state_tracker/graw.h"
  3.  
  4. #include "pipe/p_context.h"
  5. #include "pipe/p_defines.h"
  6. #include "pipe/p_screen.h"
  7. #include "pipe/p_shader_tokens.h"
  8. #include "pipe/p_state.h"
  9.  
  10. #include "util/u_box.h"    
  11. #include "util/u_debug.h"
  12. #include "util/u_draw_quad.h"
  13. #include "util/u_format.h"
  14. #include "util/u_inlines.h"
  15. #include "util/u_memory.h"
  16.  
  17.  
  18. struct graw_info
  19. {
  20.    struct pipe_screen *screen;
  21.    struct pipe_context *ctx;
  22.    struct pipe_resource *color_buf[PIPE_MAX_COLOR_BUFS], *zs_buf;
  23.    struct pipe_surface *color_surf[PIPE_MAX_COLOR_BUFS], *zs_surf;
  24.    void *window;
  25. };
  26.  
  27.  
  28.  
  29. static INLINE boolean
  30. graw_util_create_window(struct graw_info *info,
  31.                         int width, int height,
  32.                         int num_cbufs, bool zstencil_buf)
  33. {
  34.    static const enum pipe_format formats[] = {
  35.       PIPE_FORMAT_RGBA8888_UNORM,
  36.       PIPE_FORMAT_BGRA8888_UNORM,
  37.       PIPE_FORMAT_NONE
  38.    };
  39.    enum pipe_format format;
  40.    struct pipe_resource resource_temp;
  41.    struct pipe_surface surface_temp;
  42.    int i;
  43.  
  44.    memset(info, 0, sizeof(*info));
  45.  
  46.    /* It's hard to say whether window or screen should be created
  47.     * first.  Different environments would prefer one or the other.
  48.     *
  49.     * Also, no easy way of querying supported formats if the screen
  50.     * cannot be created first.
  51.     */
  52.    for (i = 0; info->window == NULL && formats[i] != PIPE_FORMAT_NONE; i++) {
  53.       info->screen = graw_create_window_and_screen(0, 0, width, height,
  54.                                                    formats[i],
  55.                                                    &info->window);
  56.       format = formats[i];
  57.    }
  58.    if (!info->screen || !info->window) {
  59.       debug_printf("graw: Failed to create screen/window\n");
  60.       return FALSE;
  61.    }
  62.    
  63.    info->ctx = info->screen->context_create(info->screen, NULL);
  64.    if (info->ctx == NULL) {
  65.       debug_printf("graw: Failed to create context\n");
  66.       return FALSE;
  67.    }
  68.  
  69.    for (i = 0; i < num_cbufs; i++) {
  70.       /* create color texture */
  71.       resource_temp.target = PIPE_TEXTURE_2D;
  72.       resource_temp.format = format;
  73.       resource_temp.width0 = width;
  74.       resource_temp.height0 = height;
  75.       resource_temp.depth0 = 1;
  76.       resource_temp.array_size = 1;
  77.       resource_temp.last_level = 0;
  78.       resource_temp.nr_samples = 1;
  79.       resource_temp.bind = (PIPE_BIND_RENDER_TARGET |
  80.                             PIPE_BIND_DISPLAY_TARGET);
  81.       info->color_buf[i] = info->screen->resource_create(info->screen,
  82.                                                          &resource_temp);
  83.       if (info->color_buf[i] == NULL) {
  84.          debug_printf("graw: Failed to create color texture\n");
  85.          return FALSE;
  86.       }
  87.  
  88.       /* create color surface */
  89.       surface_temp.format = resource_temp.format;
  90.       surface_temp.u.tex.level = 0;
  91.       surface_temp.u.tex.first_layer = 0;
  92.       surface_temp.u.tex.last_layer = 0;
  93.       info->color_surf[i] = info->ctx->create_surface(info->ctx,
  94.                                                       info->color_buf[i],
  95.                                                       &surface_temp);
  96.       if (info->color_surf[i] == NULL) {
  97.          debug_printf("graw: Failed to get color surface\n");
  98.          return FALSE;
  99.       }
  100.    }
  101.  
  102.    /* create Z texture (XXX try other Z/S formats if needed) */
  103.    resource_temp.target = PIPE_TEXTURE_2D;
  104.    resource_temp.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
  105.    resource_temp.width0 = width;
  106.    resource_temp.height0 = height;
  107.    resource_temp.depth0 = 1;
  108.    resource_temp.array_size = 1;
  109.    resource_temp.last_level = 0;
  110.    resource_temp.nr_samples = 1;
  111.    resource_temp.bind = PIPE_BIND_DEPTH_STENCIL;
  112.    info->zs_buf = info->screen->resource_create(info->screen, &resource_temp);
  113.    if (!info->zs_buf) {
  114.       debug_printf("graw: Failed to create Z texture\n");
  115.       return FALSE;
  116.    }
  117.  
  118.    /* create z surface */
  119.    surface_temp.format = resource_temp.format;
  120.    surface_temp.u.tex.level = 0;
  121.    surface_temp.u.tex.first_layer = 0;
  122.    surface_temp.u.tex.last_layer = 0;
  123.    info->zs_surf = info->ctx->create_surface(info->ctx,
  124.                                              info->zs_buf,
  125.                                              &surface_temp);
  126.    if (info->zs_surf == NULL) {
  127.       debug_printf("graw: Failed to get Z surface\n");
  128.       return FALSE;
  129.    }
  130.  
  131.    {
  132.       struct pipe_framebuffer_state fb;
  133.       memset(&fb, 0, sizeof fb);
  134.       fb.nr_cbufs = num_cbufs;
  135.       fb.width = width;
  136.       fb.height = height;
  137.       for (i = 0; i < num_cbufs; i++)
  138.          fb.cbufs[i] = info->color_surf[i];
  139.       fb.zsbuf = info->zs_surf;
  140.       info->ctx->set_framebuffer_state(info->ctx, &fb);
  141.    }
  142.  
  143.    return TRUE;
  144. }
  145.  
  146.  
  147. static INLINE void
  148. graw_util_default_state(struct graw_info *info, boolean depth_test)
  149. {
  150.    {
  151.       struct pipe_blend_state blend;
  152.       void *handle;
  153.       memset(&blend, 0, sizeof blend);
  154.       blend.rt[0].colormask = PIPE_MASK_RGBA;
  155.       handle = info->ctx->create_blend_state(info->ctx, &blend);
  156.       info->ctx->bind_blend_state(info->ctx, handle);
  157.    }
  158.  
  159.    {
  160.       struct pipe_depth_stencil_alpha_state depthStencilAlpha;
  161.       void *handle;
  162.       memset(&depthStencilAlpha, 0, sizeof depthStencilAlpha);
  163.       depthStencilAlpha.depth.enabled = depth_test;
  164.       depthStencilAlpha.depth.writemask = 1;
  165.       depthStencilAlpha.depth.func = PIPE_FUNC_LESS;
  166.       handle = info->ctx->create_depth_stencil_alpha_state(info->ctx,
  167.                                                            &depthStencilAlpha);
  168.       info->ctx->bind_depth_stencil_alpha_state(info->ctx, handle);
  169.    }
  170.  
  171.    {
  172.       struct pipe_rasterizer_state rasterizer;
  173.       void *handle;
  174.       memset(&rasterizer, 0, sizeof rasterizer);
  175.       rasterizer.cull_face = PIPE_FACE_NONE;
  176.       rasterizer.half_pixel_center = 1;
  177.       rasterizer.bottom_edge_rule = 1;
  178.       handle = info->ctx->create_rasterizer_state(info->ctx, &rasterizer);
  179.       info->ctx->bind_rasterizer_state(info->ctx, handle);
  180.    }
  181. }
  182.  
  183.  
  184. static INLINE void
  185. graw_util_viewport(struct graw_info *info,
  186.                    float x, float y,
  187.                    float width, float height,
  188.                    float near, float far)
  189. {
  190.    float z = near;
  191.    float half_width = width / 2.0f;
  192.    float half_height = height / 2.0f;
  193.    float half_depth = (far - near) / 2.0f;
  194.    struct pipe_viewport_state vp;
  195.  
  196.    vp.scale[0] = half_width;
  197.    vp.scale[1] = half_height;
  198.    vp.scale[2] = half_depth;
  199.    vp.scale[3] = 1.0f;
  200.  
  201.    vp.translate[0] = half_width + x;
  202.    vp.translate[1] = half_height + y;
  203.    vp.translate[2] = half_depth + z;
  204.    vp.translate[3] = 0.0f;
  205.  
  206.    info->ctx->set_viewport_states(info->ctx, 0, 1, &vp);
  207. }
  208.  
  209.  
  210. static INLINE void
  211. graw_util_flush_front(const struct graw_info *info)
  212. {
  213.    info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
  214.                                    0, 0, info->window);
  215. }
  216.  
  217.  
  218. static INLINE struct pipe_resource *
  219. graw_util_create_tex2d(const struct graw_info *info,
  220.                        int width, int height, enum pipe_format format,
  221.                        const void *data)
  222. {
  223.    const int row_stride = width * util_format_get_blocksize(format);
  224.    const int image_bytes = row_stride * height;
  225.    struct pipe_resource temp, *tex;
  226.    struct pipe_box box;
  227.  
  228.    temp.target = PIPE_TEXTURE_2D;
  229.    temp.format = format;
  230.    temp.width0 = width;
  231.    temp.height0 = height;
  232.    temp.depth0 = 1;
  233.    temp.last_level = 0;
  234.    temp.array_size = 1;
  235.    temp.nr_samples = 1;
  236.    temp.bind = PIPE_BIND_SAMPLER_VIEW;
  237.    
  238.    tex = info->screen->resource_create(info->screen, &temp);
  239.    if (!tex) {
  240.       debug_printf("graw: failed to create texture\n");
  241.       return NULL;
  242.    }
  243.  
  244.    u_box_2d(0, 0, width, height, &box);
  245.  
  246.    info->ctx->transfer_inline_write(info->ctx,
  247.                                     tex,
  248.                                     0,
  249.                                     PIPE_TRANSFER_WRITE,
  250.                                     &box,
  251.                                     data,
  252.                                     row_stride,
  253.                                     image_bytes);
  254.  
  255.    /* Possibly read back & compare against original data:
  256.     */
  257. #if 0
  258.    {
  259.       struct pipe_transfer *t;
  260.       uint32_t *ptr;
  261.       t = pipe_transfer_map(info->ctx, samptex,
  262.                             0, 0, /* level, layer */
  263.                             PIPE_TRANSFER_READ,
  264.                             0, 0, SIZE, SIZE); /* x, y, width, height */
  265.  
  266.       ptr = info->ctx->transfer_map(info->ctx, t);
  267.  
  268.       if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
  269.          assert(0);
  270.          exit(9);
  271.       }
  272.  
  273.       info->ctx->transfer_unmap(info->ctx, t);
  274.  
  275.       info->ctx->transfer_destroy(info->ctx, t);
  276.    }
  277. #endif
  278.  
  279.    return tex;
  280. }
  281.  
  282.  
  283. static INLINE void *
  284. graw_util_create_simple_sampler(const struct graw_info *info,
  285.                                 unsigned wrap_mode,
  286.                                 unsigned img_filter)
  287. {
  288.    struct pipe_sampler_state sampler_desc;
  289.    void *sampler;
  290.  
  291.    memset(&sampler_desc, 0, sizeof sampler_desc);
  292.    sampler_desc.wrap_s =
  293.    sampler_desc.wrap_t =
  294.    sampler_desc.wrap_r = wrap_mode;
  295.    sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  296.    sampler_desc.min_img_filter =
  297.    sampler_desc.mag_img_filter = img_filter;
  298.    sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
  299.    sampler_desc.compare_func = 0;
  300.    sampler_desc.normalized_coords = 1;
  301.    sampler_desc.max_anisotropy = 0;
  302.    
  303.    sampler = info->ctx->create_sampler_state(info->ctx, &sampler_desc);
  304.  
  305.    return sampler;
  306. }
  307.  
  308.  
  309. static INLINE struct pipe_sampler_view *
  310. graw_util_create_simple_sampler_view(const struct graw_info *info,
  311.                                      struct pipe_resource *texture)
  312. {
  313.    struct pipe_sampler_view sv_temp;
  314.    struct pipe_sampler_view *sv;
  315.  
  316.    memset(&sv_temp, 0, sizeof(sv_temp));
  317.    sv_temp.format = texture->format;
  318.    sv_temp.texture = texture;
  319.    sv_temp.swizzle_r = PIPE_SWIZZLE_RED;
  320.    sv_temp.swizzle_g = PIPE_SWIZZLE_GREEN;
  321.    sv_temp.swizzle_b = PIPE_SWIZZLE_BLUE;
  322.    sv_temp.swizzle_a = PIPE_SWIZZLE_ALPHA;
  323.  
  324.    sv = info->ctx->create_sampler_view(info->ctx, texture, &sv_temp);
  325.  
  326.    return sv;
  327. }
  328.  
  329.