Home | History | Annotate | Download | only in nine
      1 /*
      2  * Copyright 2011 Joakim Sindholt <opensource (at) zhasha.com>
      3  * Copyright 2015 Patrick Rudolph <siro (at) das-labor.org>
      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  * on the rights to use, copy, modify, merge, publish, distribute, sub
      9  * license, and/or sell copies of the Software, and to permit persons to whom
     10  * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     22  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
     23 
     24 #ifndef _NINE_BUFFER9_H_
     25 #define _NINE_BUFFER9_H_
     26 
     27 #include "device9.h"
     28 #include "nine_buffer_upload.h"
     29 #include "nine_state.h"
     30 #include "resource9.h"
     31 #include "pipe/p_context.h"
     32 #include "pipe/p_state.h"
     33 #include "util/list.h"
     34 
     35 struct pipe_screen;
     36 struct pipe_context;
     37 struct pipe_transfer;
     38 
     39 struct NineTransfer {
     40     struct pipe_transfer *transfer;
     41     bool is_pipe_secondary;
     42     struct nine_subbuffer *buf; /* NULL unless subbuffer are used */
     43     bool should_destroy_buf; /* If the subbuffer should be destroyed */
     44 };
     45 
     46 struct NineBuffer9
     47 {
     48     struct NineResource9 base;
     49 
     50     /* G3D */
     51     struct NineTransfer *maps;
     52     int nmaps, maxmaps;
     53     UINT size;
     54 
     55     int16_t bind_count; /* to Device9->state.stream */
     56     /* Whether only discard and nooverwrite were used so far
     57      * for this buffer. Allows some optimization. */
     58     boolean discard_nooverwrite_only;
     59     struct nine_subbuffer *buf;
     60 
     61     /* Specific to managed buffers */
     62     struct {
     63         void *data;
     64         boolean dirty;
     65         struct pipe_box dirty_box;
     66         struct list_head list; /* for update_buffers */
     67         struct list_head list2; /* for managed_buffers */
     68         unsigned pending_upload; /* for uploads */
     69     } managed;
     70 };
     71 static inline struct NineBuffer9 *
     72 NineBuffer9( void *data )
     73 {
     74     return (struct NineBuffer9 *)data;
     75 }
     76 
     77 HRESULT
     78 NineBuffer9_ctor( struct NineBuffer9 *This,
     79                         struct NineUnknownParams *pParams,
     80                         D3DRESOURCETYPE Type,
     81                         DWORD Usage,
     82                         UINT Size,
     83                         D3DPOOL Pool );
     84 
     85 void
     86 NineBuffer9_dtor( struct NineBuffer9 *This );
     87 
     88 struct pipe_resource *
     89 NineBuffer9_GetResource( struct NineBuffer9 *This, unsigned *offset );
     90 
     91 HRESULT NINE_WINAPI
     92 NineBuffer9_Lock( struct NineBuffer9 *This,
     93                         UINT OffsetToLock,
     94                         UINT SizeToLock,
     95                         void **ppbData,
     96                         DWORD Flags );
     97 
     98 HRESULT NINE_WINAPI
     99 NineBuffer9_Unlock( struct NineBuffer9 *This );
    100 
    101 static inline void
    102 NineBuffer9_Upload( struct NineBuffer9 *This )
    103 {
    104     struct NineDevice9 *device = This->base.base.device;
    105 
    106     assert(This->base.pool == D3DPOOL_MANAGED && This->managed.dirty);
    107     nine_context_range_upload(device, &This->managed.pending_upload, This->base.resource,
    108                               This->managed.dirty_box.x,
    109                               This->managed.dirty_box.width,
    110                               (char *)This->managed.data + This->managed.dirty_box.x);
    111     This->managed.dirty = FALSE;
    112 }
    113 
    114 static void inline
    115 NineBindBufferToDevice( struct NineDevice9 *device,
    116                         struct NineBuffer9 **slot,
    117                         struct NineBuffer9 *buf )
    118 {
    119     struct NineBuffer9 *old = *slot;
    120 
    121     if (buf) {
    122         if ((buf->managed.dirty) && LIST_IS_EMPTY(&buf->managed.list))
    123             list_add(&buf->managed.list, &device->update_buffers);
    124         buf->bind_count++;
    125     }
    126     if (old)
    127         old->bind_count--;
    128 
    129     nine_bind(slot, buf);
    130 }
    131 
    132 void
    133 NineBuffer9_SetDirty( struct NineBuffer9 *This );
    134 
    135 #define BASEBUF_REGISTER_UPDATE(b) { \
    136     if ((b)->managed.dirty && (b)->bind_count) \
    137         if (LIST_IS_EMPTY(&(b)->managed.list)) \
    138             list_add(&(b)->managed.list, &(b)->base.base.device->update_buffers); \
    139     }
    140 
    141 #endif /* _NINE_BUFFER9_H_ */
    142