Home | History | Annotate | Download | only in dri
      1 /**************************************************************************
      2  *
      3  * Copyright 2009, VMware, Inc.
      4  * All Rights Reserved.
      5  * Copyright 2010 George Sapountzis <gsapountzis (at) gmail.com>
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29 #include "pipe/p_compiler.h"
     30 #include "pipe/p_format.h"
     31 #include "util/u_inlines.h"
     32 #include "util/u_format.h"
     33 #include "util/u_math.h"
     34 #include "util/u_memory.h"
     35 
     36 #include "state_tracker/sw_winsys.h"
     37 #include "dri_sw_winsys.h"
     38 
     39 
     40 struct dri_sw_displaytarget
     41 {
     42    enum pipe_format format;
     43    unsigned width;
     44    unsigned height;
     45    unsigned stride;
     46 
     47    void *data;
     48    void *mapped;
     49 };
     50 
     51 struct dri_sw_winsys
     52 {
     53    struct sw_winsys base;
     54 
     55    struct drisw_loader_funcs *lf;
     56 };
     57 
     58 static INLINE struct dri_sw_displaytarget *
     59 dri_sw_displaytarget( struct sw_displaytarget *dt )
     60 {
     61    return (struct dri_sw_displaytarget *)dt;
     62 }
     63 
     64 static INLINE struct dri_sw_winsys *
     65 dri_sw_winsys( struct sw_winsys *ws )
     66 {
     67    return (struct dri_sw_winsys *)ws;
     68 }
     69 
     70 
     71 static boolean
     72 dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
     73                                           unsigned tex_usage,
     74                                           enum pipe_format format )
     75 {
     76    /* TODO: check visuals or other sensible thing here */
     77    return TRUE;
     78 }
     79 
     80 static struct sw_displaytarget *
     81 dri_sw_displaytarget_create(struct sw_winsys *winsys,
     82                             unsigned tex_usage,
     83                             enum pipe_format format,
     84                             unsigned width, unsigned height,
     85                             unsigned alignment,
     86                             unsigned *stride)
     87 {
     88    struct dri_sw_displaytarget *dri_sw_dt;
     89    unsigned nblocksy, size, format_stride;
     90 
     91    dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
     92    if(!dri_sw_dt)
     93       goto no_dt;
     94 
     95    dri_sw_dt->format = format;
     96    dri_sw_dt->width = width;
     97    dri_sw_dt->height = height;
     98 
     99    format_stride = util_format_get_stride(format, width);
    100    dri_sw_dt->stride = align(format_stride, alignment);
    101 
    102    nblocksy = util_format_get_nblocksy(format, height);
    103    size = dri_sw_dt->stride * nblocksy;
    104 
    105    dri_sw_dt->data = align_malloc(size, alignment);
    106    if(!dri_sw_dt->data)
    107       goto no_data;
    108 
    109    *stride = dri_sw_dt->stride;
    110    return (struct sw_displaytarget *)dri_sw_dt;
    111 
    112 no_data:
    113    FREE(dri_sw_dt);
    114 no_dt:
    115    return NULL;
    116 }
    117 
    118 static void
    119 dri_sw_displaytarget_destroy(struct sw_winsys *ws,
    120                              struct sw_displaytarget *dt)
    121 {
    122    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
    123 
    124    if (dri_sw_dt->data) {
    125       FREE(dri_sw_dt->data);
    126    }
    127 
    128    FREE(dri_sw_dt);
    129 }
    130 
    131 static void *
    132 dri_sw_displaytarget_map(struct sw_winsys *ws,
    133                          struct sw_displaytarget *dt,
    134                          unsigned flags)
    135 {
    136    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
    137    dri_sw_dt->mapped = dri_sw_dt->data;
    138    return dri_sw_dt->mapped;
    139 }
    140 
    141 static void
    142 dri_sw_displaytarget_unmap(struct sw_winsys *ws,
    143                            struct sw_displaytarget *dt)
    144 {
    145    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
    146    dri_sw_dt->mapped = NULL;
    147 }
    148 
    149 static struct sw_displaytarget *
    150 dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
    151                                  const struct pipe_resource *templ,
    152                                  struct winsys_handle *whandle,
    153                                  unsigned *stride)
    154 {
    155    assert(0);
    156    return NULL;
    157 }
    158 
    159 static boolean
    160 dri_sw_displaytarget_get_handle(struct sw_winsys *winsys,
    161                                 struct sw_displaytarget *dt,
    162                                 struct winsys_handle *whandle)
    163 {
    164    assert(0);
    165    return FALSE;
    166 }
    167 
    168 static void
    169 dri_sw_displaytarget_display(struct sw_winsys *ws,
    170                              struct sw_displaytarget *dt,
    171                              void *context_private)
    172 {
    173    struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
    174    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
    175    struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
    176    unsigned width, height;
    177 
    178    /* Set the width to 'stride / cpp'.
    179     *
    180     * PutImage correctly clips to the width of the dst drawable.
    181     */
    182    width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
    183 
    184    height = dri_sw_dt->height;
    185 
    186    dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
    187 }
    188 
    189 
    190 static void
    191 dri_destroy_sw_winsys(struct sw_winsys *winsys)
    192 {
    193    FREE(winsys);
    194 }
    195 
    196 struct sw_winsys *
    197 dri_create_sw_winsys(struct drisw_loader_funcs *lf)
    198 {
    199    struct dri_sw_winsys *ws;
    200 
    201    ws = CALLOC_STRUCT(dri_sw_winsys);
    202    if (!ws)
    203       return NULL;
    204 
    205    ws->lf = lf;
    206    ws->base.destroy = dri_destroy_sw_winsys;
    207 
    208    ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
    209 
    210    /* screen texture functions */
    211    ws->base.displaytarget_create = dri_sw_displaytarget_create;
    212    ws->base.displaytarget_destroy = dri_sw_displaytarget_destroy;
    213    ws->base.displaytarget_from_handle = dri_sw_displaytarget_from_handle;
    214    ws->base.displaytarget_get_handle = dri_sw_displaytarget_get_handle;
    215 
    216    /* texture functions */
    217    ws->base.displaytarget_map = dri_sw_displaytarget_map;
    218    ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap;
    219 
    220    ws->base.displaytarget_display = dri_sw_displaytarget_display;
    221 
    222    return &ws->base;
    223 }
    224 
    225 /* vim: set sw=3 ts=8 sts=3 expandtab: */
    226