Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 2009-2011 VMware, Inc. All rights reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person
  5.  * obtaining a copy of this software and associated documentation
  6.  * files (the "Software"), to deal in the Software without
  7.  * restriction, including without limitation the rights to use, copy,
  8.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  9.  * of the Software, and to permit persons to whom the Software is
  10.  * furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  *********************************************************
  25.  * Authors:
  26.  * Zack Rusin <zackr-at-vmware-dot-com>
  27.  * Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  28.  */
  29. #include "xa_context.h"
  30. #include "xa_priv.h"
  31. #include "cso_cache/cso_context.h"
  32. #include "util/u_inlines.h"
  33. #include "util/u_rect.h"
  34. #include "util/u_surface.h"
  35. #include "pipe/p_context.h"
  36.  
  37. XA_EXPORT void
  38. xa_context_flush(struct xa_context *ctx)
  39. {
  40.         ctx->pipe->flush(ctx->pipe, &ctx->last_fence, 0);
  41. }
  42.  
  43. XA_EXPORT struct xa_context *
  44. xa_context_default(struct xa_tracker *xa)
  45. {
  46.     return xa->default_ctx;
  47. }
  48.  
  49. XA_EXPORT struct xa_context *
  50. xa_context_create(struct xa_tracker *xa)
  51. {
  52.     struct xa_context *ctx = calloc(1, sizeof(*ctx));
  53.  
  54.     ctx->xa = xa;
  55.     ctx->pipe = xa->screen->context_create(xa->screen, NULL);
  56.     ctx->cso = cso_create_context(ctx->pipe);
  57.     ctx->shaders = xa_shaders_create(ctx);
  58.     renderer_init_state(ctx);
  59.  
  60.     return ctx;
  61. }
  62.  
  63. XA_EXPORT void
  64. xa_context_destroy(struct xa_context *r)
  65. {
  66.     struct pipe_resource **vsbuf = &r->vs_const_buffer;
  67.     struct pipe_resource **fsbuf = &r->fs_const_buffer;
  68.  
  69.     if (*vsbuf)
  70.         pipe_resource_reference(vsbuf, NULL);
  71.  
  72.     if (*fsbuf)
  73.         pipe_resource_reference(fsbuf, NULL);
  74.  
  75.     if (r->shaders) {
  76.         xa_shaders_destroy(r->shaders);
  77.         r->shaders = NULL;
  78.     }
  79.  
  80.     xa_ctx_sampler_views_destroy(r);
  81.     if (r->srf)
  82.         pipe_surface_reference(&r->srf, NULL);
  83.  
  84.     if (r->cso) {
  85.         cso_destroy_context(r->cso);
  86.         r->cso = NULL;
  87.     }
  88.  
  89.     r->pipe->destroy(r->pipe);
  90. }
  91.  
  92. XA_EXPORT int
  93. xa_surface_dma(struct xa_context *ctx,
  94.                struct xa_surface *srf,
  95.                void *data,
  96.                unsigned int pitch,
  97.                int to_surface, struct xa_box *boxes, unsigned int num_boxes)
  98. {
  99.     struct pipe_transfer *transfer;
  100.     void *map;
  101.     int w, h, i;
  102.     enum pipe_transfer_usage transfer_direction;
  103.     struct pipe_context *pipe = ctx->pipe;
  104.  
  105.     transfer_direction = (to_surface ? PIPE_TRANSFER_WRITE :
  106.                           PIPE_TRANSFER_READ);
  107.  
  108.     for (i = 0; i < num_boxes; ++i, ++boxes) {
  109.         w = boxes->x2 - boxes->x1;
  110.         h = boxes->y2 - boxes->y1;
  111.  
  112.         map = pipe_transfer_map(pipe, srf->tex, 0, 0,
  113.                                 transfer_direction, boxes->x1, boxes->y1,
  114.                                 w, h, &transfer);
  115.         if (!map)
  116.             return -XA_ERR_NORES;
  117.  
  118.         if (to_surface) {
  119.             util_copy_rect(map, srf->tex->format, transfer->stride,
  120.                            0, 0, w, h, data, pitch, boxes->x1, boxes->y1);
  121.         } else {
  122.             util_copy_rect(data, srf->tex->format, pitch,
  123.                            boxes->x1, boxes->y1, w, h, map, transfer->stride, 0,
  124.                            0);
  125.         }
  126.         pipe->transfer_unmap(pipe, transfer);
  127.     }
  128.     return XA_ERR_NONE;
  129. }
  130.  
  131. XA_EXPORT void *
  132. xa_surface_map(struct xa_context *ctx,
  133.                struct xa_surface *srf, unsigned int usage)
  134. {
  135.     void *map;
  136.     unsigned int gallium_usage = 0;
  137.     struct pipe_context *pipe = ctx->pipe;
  138.  
  139.     /*
  140.      * A surface may only have a single map.
  141.      */
  142.     if (srf->transfer)
  143.         return NULL;
  144.  
  145.     if (usage & XA_MAP_READ)
  146.         gallium_usage |= PIPE_TRANSFER_READ;
  147.     if (usage & XA_MAP_WRITE)
  148.         gallium_usage |= PIPE_TRANSFER_WRITE;
  149.     if (usage & XA_MAP_MAP_DIRECTLY)
  150.         gallium_usage |= PIPE_TRANSFER_MAP_DIRECTLY;
  151.     if (usage & XA_MAP_UNSYNCHRONIZED)
  152.         gallium_usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
  153.     if (usage & XA_MAP_DONTBLOCK)
  154.         gallium_usage |= PIPE_TRANSFER_DONTBLOCK;
  155.     if (usage & XA_MAP_DISCARD_WHOLE_RESOURCE)
  156.         gallium_usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
  157.  
  158.     if (!(gallium_usage & (PIPE_TRANSFER_READ_WRITE)))
  159.         return NULL;
  160.  
  161.     map = pipe_transfer_map(pipe, srf->tex, 0, 0,
  162.                             gallium_usage, 0, 0,
  163.                             srf->tex->width0, srf->tex->height0,
  164.                             &srf->transfer);
  165.     if (!map)
  166.         return NULL;
  167.  
  168.     srf->mapping_pipe = pipe;
  169.     return map;
  170. }
  171.  
  172. XA_EXPORT void
  173. xa_surface_unmap(struct xa_surface *srf)
  174. {
  175.     if (srf->transfer) {
  176.         struct pipe_context *pipe = srf->mapping_pipe;
  177.  
  178.         pipe->transfer_unmap(pipe, srf->transfer);
  179.         srf->transfer = NULL;
  180.     }
  181. }
  182.  
  183. int
  184. xa_ctx_srf_create(struct xa_context *ctx, struct xa_surface *dst)
  185. {
  186.     struct pipe_screen *screen = ctx->pipe->screen;
  187.     struct pipe_surface srf_templ;
  188.  
  189.     /*
  190.      * Cache surfaces unless we change render target
  191.      */
  192.     if (ctx->srf) {
  193.         if (ctx->srf->texture == dst->tex)
  194.             return XA_ERR_NONE;
  195.  
  196.         pipe_surface_reference(&ctx->srf, NULL);
  197.     }
  198.  
  199.     if (!screen->is_format_supported(screen,  dst->tex->format,
  200.                                      PIPE_TEXTURE_2D, 0,
  201.                                      PIPE_BIND_RENDER_TARGET))
  202.         return -XA_ERR_INVAL;
  203.  
  204.     u_surface_default_template(&srf_templ, dst->tex);
  205.     ctx->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ);
  206.     if (!ctx->srf)
  207.         return -XA_ERR_NORES;
  208.  
  209.     return XA_ERR_NONE;
  210. }
  211.  
  212. void
  213. xa_ctx_srf_destroy(struct xa_context *ctx)
  214. {
  215.     /*
  216.      * Cache surfaces unless we change render target.
  217.      * Final destruction on context destroy.
  218.      */
  219. }
  220.  
  221. XA_EXPORT int
  222. xa_copy_prepare(struct xa_context *ctx,
  223.                 struct xa_surface *dst, struct xa_surface *src)
  224. {
  225.     if (src == dst)
  226.         return -XA_ERR_INVAL;
  227.  
  228.     if (src->tex->format != dst->tex->format) {
  229.         int ret = xa_ctx_srf_create(ctx, dst);
  230.         if (ret != XA_ERR_NONE)
  231.             return ret;
  232.         renderer_copy_prepare(ctx, ctx->srf, src->tex,
  233.                               src->fdesc.xa_format,
  234.                               dst->fdesc.xa_format);
  235.         ctx->simple_copy = 0;
  236.     } else
  237.         ctx->simple_copy = 1;
  238.  
  239.     ctx->src = src;
  240.     ctx->dst = dst;
  241.     xa_ctx_srf_destroy(ctx);
  242.  
  243.     return 0;
  244. }
  245.  
  246. XA_EXPORT void
  247. xa_copy(struct xa_context *ctx,
  248.         int dx, int dy, int sx, int sy, int width, int height)
  249. {
  250.     struct pipe_box src_box;
  251.  
  252.     xa_scissor_update(ctx, dx, dy, dx + width, dy + height);
  253.  
  254.     if (ctx->simple_copy) {
  255.         u_box_2d(sx, sy, width, height, &src_box);
  256.         ctx->pipe->resource_copy_region(ctx->pipe,
  257.                                         ctx->dst->tex, 0, dx, dy, 0,
  258.                                         ctx->src->tex,
  259.                                         0, &src_box);
  260.     } else
  261.         renderer_copy(ctx, dx, dy, sx, sy, width, height,
  262.                       (float) ctx->src->tex->width0,
  263.                       (float) ctx->src->tex->height0);
  264. }
  265.  
  266. XA_EXPORT void
  267. xa_copy_done(struct xa_context *ctx)
  268. {
  269.     if (!ctx->simple_copy) {
  270.         renderer_draw_flush(ctx);
  271.     }
  272. }
  273.  
  274. static void
  275. bind_solid_blend_state(struct xa_context *ctx)
  276. {
  277.     struct pipe_blend_state blend;
  278.  
  279.     memset(&blend, 0, sizeof(struct pipe_blend_state));
  280.     blend.rt[0].blend_enable = 0;
  281.     blend.rt[0].colormask = PIPE_MASK_RGBA;
  282.  
  283.     blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
  284.     blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  285.     blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
  286.     blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  287.  
  288.     cso_set_blend(ctx->cso, &blend);
  289. }
  290.  
  291. XA_EXPORT int
  292. xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
  293.                  uint32_t fg)
  294. {
  295.     unsigned vs_traits, fs_traits;
  296.     struct xa_shader shader;
  297.     int ret;
  298.  
  299.     ret = xa_ctx_srf_create(ctx, dst);
  300.     if (ret != XA_ERR_NONE)
  301.         return ret;
  302.  
  303.     if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
  304.         xa_pixel_to_float4_a8(fg, ctx->solid_color);
  305.     else
  306.         xa_pixel_to_float4(fg, ctx->solid_color);
  307.     ctx->has_solid_color = 1;
  308.  
  309.     ctx->dst = dst;
  310.  
  311. #if 0
  312.     debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
  313.                  (fg >> 24) & 0xff, (fg >> 16) & 0xff,
  314.                  (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
  315.                  exa->solid_color[0], exa->solid_color[1],
  316.                  exa->solid_color[2], exa->solid_color[3]);
  317. #endif
  318.  
  319.     vs_traits = VS_SOLID_FILL;
  320.     fs_traits = FS_SOLID_FILL;
  321.  
  322.     renderer_bind_destination(ctx, ctx->srf);
  323.     bind_solid_blend_state(ctx);
  324.     cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
  325.     cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
  326.  
  327.     shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
  328.     cso_set_vertex_shader_handle(ctx->cso, shader.vs);
  329.     cso_set_fragment_shader_handle(ctx->cso, shader.fs);
  330.  
  331.     renderer_begin_solid(ctx);
  332.  
  333.     xa_ctx_srf_destroy(ctx);
  334.     return XA_ERR_NONE;
  335. }
  336.  
  337. XA_EXPORT void
  338. xa_solid(struct xa_context *ctx, int x, int y, int width, int height)
  339. {
  340.     xa_scissor_update(ctx, x, y, x + width, y + height);
  341.     renderer_solid(ctx, x, y, x + width, y + height, ctx->solid_color);
  342. }
  343.  
  344. XA_EXPORT void
  345. xa_solid_done(struct xa_context *ctx)
  346. {
  347.     renderer_draw_flush(ctx);
  348.     ctx->comp = NULL;
  349.     ctx->has_solid_color = FALSE;
  350.     ctx->num_bound_samplers = 0;
  351. }
  352.  
  353. XA_EXPORT struct xa_fence *
  354. xa_fence_get(struct xa_context *ctx)
  355. {
  356.     struct xa_fence *fence = calloc(1, sizeof(*fence));
  357.     struct pipe_screen *screen = ctx->xa->screen;
  358.  
  359.     if (!fence)
  360.         return NULL;
  361.  
  362.     fence->xa = ctx->xa;
  363.  
  364.     if (ctx->last_fence == NULL)
  365.         fence->pipe_fence = NULL;
  366.     else
  367.         screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence);
  368.  
  369.     return fence;
  370. }
  371.  
  372. XA_EXPORT int
  373. xa_fence_wait(struct xa_fence *fence, uint64_t timeout)
  374. {
  375.     if (!fence)
  376.         return XA_ERR_NONE;
  377.  
  378.     if (fence->pipe_fence) {
  379.         struct pipe_screen *screen = fence->xa->screen;
  380.         boolean timed_out;
  381.  
  382.         timed_out = !screen->fence_finish(screen, fence->pipe_fence, timeout);
  383.         if (timed_out)
  384.             return -XA_ERR_BUSY;
  385.  
  386.         screen->fence_reference(screen, &fence->pipe_fence, NULL);
  387.     }
  388.     return XA_ERR_NONE;
  389. }
  390.  
  391. XA_EXPORT void
  392. xa_fence_destroy(struct xa_fence *fence)
  393. {
  394.     if (!fence)
  395.         return;
  396.  
  397.     if (fence->pipe_fence) {
  398.         struct pipe_screen *screen = fence->xa->screen;
  399.  
  400.         screen->fence_reference(screen, &fence->pipe_fence, NULL);
  401.     }
  402.  
  403.     free(fence);
  404. }
  405.  
  406. void
  407. xa_ctx_sampler_views_destroy(struct xa_context *ctx)
  408. {
  409.     int i;
  410.  
  411.     for (i = 0; i < ctx->num_bound_samplers; ++i)
  412.         pipe_sampler_view_reference(&ctx->bound_sampler_views[i], NULL);
  413.     ctx->num_bound_samplers = 0;
  414. }
  415.