Home | History | Annotate | Download | only in graw
      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_R8G8B8A8_UNORM,
     36       PIPE_FORMAT_B8G8R8A8_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.usage = PIPE_BIND_RENDER_TARGET;
     91       surface_temp.u.tex.level = 0;
     92       surface_temp.u.tex.first_layer = 0;
     93       surface_temp.u.tex.last_layer = 0;
     94       info->color_surf[i] = info->ctx->create_surface(info->ctx,
     95                                                       info->color_buf[i],
     96                                                       &surface_temp);
     97       if (info->color_surf[i] == NULL) {
     98          debug_printf("graw: Failed to get color surface\n");
     99          return FALSE;
    100       }
    101    }
    102 
    103    /* create Z texture (XXX try other Z/S formats if needed) */
    104    resource_temp.target = PIPE_TEXTURE_2D;
    105    resource_temp.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
    106    resource_temp.width0 = width;
    107    resource_temp.height0 = height;
    108    resource_temp.depth0 = 1;
    109    resource_temp.array_size = 1;
    110    resource_temp.last_level = 0;
    111    resource_temp.nr_samples = 1;
    112    resource_temp.bind = PIPE_BIND_DEPTH_STENCIL;
    113    info->zs_buf = info->screen->resource_create(info->screen, &resource_temp);
    114    if (!info->zs_buf) {
    115       debug_printf("graw: Failed to create Z texture\n");
    116       return FALSE;
    117    }
    118 
    119    /* create z surface */
    120    surface_temp.format = resource_temp.format;
    121    surface_temp.usage = PIPE_BIND_DEPTH_STENCIL;
    122    surface_temp.u.tex.level = 0;
    123    surface_temp.u.tex.first_layer = 0;
    124    surface_temp.u.tex.last_layer = 0;
    125    info->zs_surf = info->ctx->create_surface(info->ctx,
    126                                              info->zs_buf,
    127                                              &surface_temp);
    128    if (info->zs_surf == NULL) {
    129       debug_printf("graw: Failed to get Z surface\n");
    130       return FALSE;
    131    }
    132 
    133    {
    134       struct pipe_framebuffer_state fb;
    135       memset(&fb, 0, sizeof fb);
    136       fb.nr_cbufs = num_cbufs;
    137       fb.width = width;
    138       fb.height = height;
    139       for (i = 0; i < num_cbufs; i++)
    140          fb.cbufs[i] = info->color_surf[i];
    141       fb.zsbuf = info->zs_surf;
    142       info->ctx->set_framebuffer_state(info->ctx, &fb);
    143    }
    144 
    145    return TRUE;
    146 }
    147 
    148 
    149 static INLINE void
    150 graw_util_default_state(struct graw_info *info, boolean depth_test)
    151 {
    152    {
    153       struct pipe_blend_state blend;
    154       void *handle;
    155       memset(&blend, 0, sizeof blend);
    156       blend.rt[0].colormask = PIPE_MASK_RGBA;
    157       handle = info->ctx->create_blend_state(info->ctx, &blend);
    158       info->ctx->bind_blend_state(info->ctx, handle);
    159    }
    160 
    161    {
    162       struct pipe_depth_stencil_alpha_state depthStencilAlpha;
    163       void *handle;
    164       memset(&depthStencilAlpha, 0, sizeof depthStencilAlpha);
    165       depthStencilAlpha.depth.enabled = depth_test;
    166       depthStencilAlpha.depth.writemask = 1;
    167       depthStencilAlpha.depth.func = PIPE_FUNC_LESS;
    168       handle = info->ctx->create_depth_stencil_alpha_state(info->ctx,
    169                                                            &depthStencilAlpha);
    170       info->ctx->bind_depth_stencil_alpha_state(info->ctx, handle);
    171    }
    172 
    173    {
    174       struct pipe_rasterizer_state rasterizer;
    175       void *handle;
    176       memset(&rasterizer, 0, sizeof rasterizer);
    177       rasterizer.cull_face = PIPE_FACE_NONE;
    178       rasterizer.gl_rasterization_rules = 1;
    179       handle = info->ctx->create_rasterizer_state(info->ctx, &rasterizer);
    180       info->ctx->bind_rasterizer_state(info->ctx, handle);
    181    }
    182 }
    183 
    184 
    185 static INLINE void
    186 graw_util_viewport(struct graw_info *info,
    187                    float x, float y,
    188                    float width, float height,
    189                    float near, float far)
    190 {
    191    float z = near;
    192    float half_width = width / 2.0f;
    193    float half_height = height / 2.0f;
    194    float half_depth = (far - near) / 2.0f;
    195    struct pipe_viewport_state vp;
    196 
    197    vp.scale[0] = half_width;
    198    vp.scale[1] = half_height;
    199    vp.scale[2] = half_depth;
    200    vp.scale[3] = 1.0f;
    201 
    202    vp.translate[0] = half_width + x;
    203    vp.translate[1] = half_height + y;
    204    vp.translate[2] = half_depth + z;
    205    vp.translate[3] = 0.0f;
    206 
    207    info->ctx->set_viewport_state(info->ctx, &vp);
    208 }
    209 
    210 
    211 static INLINE void
    212 graw_util_flush_front(const struct graw_info *info)
    213 {
    214    info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
    215                                    0, 0, info->window);
    216 }
    217 
    218 
    219 static INLINE struct pipe_resource *
    220 graw_util_create_tex2d(const struct graw_info *info,
    221                        int width, int height, enum pipe_format format,
    222                        const void *data)
    223 {
    224    const int row_stride = width * util_format_get_blocksize(format);
    225    const int image_bytes = row_stride * height;
    226    struct pipe_resource temp, *tex;
    227    struct pipe_box box;
    228 
    229    temp.target = PIPE_TEXTURE_2D;
    230    temp.format = PIPE_FORMAT_B8G8R8A8_UNORM;
    231    temp.width0 = width;
    232    temp.height0 = height;
    233    temp.depth0 = 1;
    234    temp.last_level = 0;
    235    temp.array_size = 1;
    236    temp.nr_samples = 1;
    237    temp.bind = PIPE_BIND_SAMPLER_VIEW;
    238 
    239    tex = info->screen->resource_create(info->screen, &temp);
    240    if (!tex) {
    241       debug_printf("graw: failed to create texture\n");
    242       return NULL;
    243    }
    244 
    245    u_box_2d(0, 0, width, height, &box);
    246 
    247    info->ctx->transfer_inline_write(info->ctx,
    248                                     tex,
    249                                     0,
    250                                     PIPE_TRANSFER_WRITE,
    251                                     &box,
    252                                     data,
    253                                     row_stride,
    254                                     image_bytes);
    255 
    256    /* Possibly read back & compare against original data:
    257     */
    258 #if 0
    259    {
    260       struct pipe_transfer *t;
    261       uint32_t *ptr;
    262       t = pipe_get_transfer(info->ctx, samptex,
    263                             0, 0, /* level, layer */
    264                             PIPE_TRANSFER_READ,
    265                             0, 0, SIZE, SIZE); /* x, y, width, height */
    266 
    267       ptr = info->ctx->transfer_map(info->ctx, t);
    268 
    269       if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
    270          assert(0);
    271          exit(9);
    272       }
    273 
    274       info->ctx->transfer_unmap(info->ctx, t);
    275 
    276       info->ctx->transfer_destroy(info->ctx, t);
    277    }
    278 #endif
    279 
    280    return tex;
    281 }
    282 
    283 
    284 static INLINE void *
    285 graw_util_create_simple_sampler(const struct graw_info *info,
    286                                 unsigned wrap_mode,
    287                                 unsigned img_filter)
    288 {
    289    struct pipe_sampler_state sampler_desc;
    290    void *sampler;
    291 
    292    memset(&sampler_desc, 0, sizeof sampler_desc);
    293    sampler_desc.wrap_s =
    294    sampler_desc.wrap_t =
    295    sampler_desc.wrap_r = wrap_mode;
    296    sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
    297    sampler_desc.min_img_filter =
    298    sampler_desc.mag_img_filter = img_filter;
    299    sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
    300    sampler_desc.compare_func = 0;
    301    sampler_desc.normalized_coords = 1;
    302    sampler_desc.max_anisotropy = 0;
    303 
    304    sampler = info->ctx->create_sampler_state(info->ctx, &sampler_desc);
    305 
    306    return sampler;
    307 }
    308 
    309 
    310 static INLINE struct pipe_sampler_view *
    311 graw_util_create_simple_sampler_view(const struct graw_info *info,
    312                                      struct pipe_resource *texture)
    313 {
    314    struct pipe_sampler_view sv_temp;
    315    struct pipe_sampler_view *sv;
    316 
    317    memset(&sv_temp, 0, sizeof(sv_temp));
    318    sv_temp.format = texture->format;
    319    sv_temp.texture = texture;
    320    sv_temp.swizzle_r = PIPE_SWIZZLE_RED;
    321    sv_temp.swizzle_g = PIPE_SWIZZLE_GREEN;
    322    sv_temp.swizzle_b = PIPE_SWIZZLE_BLUE;
    323    sv_temp.swizzle_a = PIPE_SWIZZLE_ALPHA;
    324 
    325    sv = info->ctx->create_sampler_view(info->ctx, texture, &sv_temp);
    326 
    327    return sv;
    328 }
    329 
    330