i915_resource_buffer.c revision 0950086376b1c8b7fb89eda81ed7f2f06dee58bc
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27 /*
28  * Authors:
29  *   Keith Whitwell <keith@tungstengraphics.com>
30  *   Michel Dänzer <michel@tungstengraphics.com>
31  */
32
33#include "pipe/p_context.h"
34#include "pipe/p_defines.h"
35#include "util/u_inlines.h"
36#include "util/u_math.h"
37#include "util/u_memory.h"
38
39#include "i915_context.h"
40#include "i915_resource.h"
41
42
43
44static boolean
45i915_buffer_get_handle(struct pipe_screen *screen,
46		       struct pipe_resource *resource,
47		       struct winsys_handle *handle)
48{
49   return FALSE;
50}
51
52static void
53i915_buffer_destroy(struct pipe_screen *screen,
54		    struct pipe_resource *resource)
55{
56   struct i915_buffer *buffer = i915_buffer(resource);
57   if (buffer->free_on_destroy)
58      align_free(buffer->data);
59   FREE(buffer);
60}
61
62
63static struct pipe_transfer *
64i915_get_transfer(struct pipe_context *pipe,
65                  struct pipe_resource *resource,
66                  unsigned level,
67                  unsigned usage,
68                  const struct pipe_box *box)
69{
70   struct i915_context *i915 = i915_context(pipe);
71   struct pipe_transfer *transfer;
72
73   if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
74      return NULL;
75   }
76
77   transfer = util_slab_alloc(&i915->transfer_pool);
78   if (transfer == NULL)
79      return NULL;
80
81   transfer->resource = resource;
82   transfer->level = level;
83   transfer->usage = usage;
84   transfer->box = *box;
85
86   /* Note strides are zero, this is ok for buffers, but not for
87    * textures 2d & higher at least.
88    */
89   return transfer;
90}
91
92static void
93i915_transfer_destroy(struct pipe_context *pipe,
94                      struct pipe_transfer *transfer)
95{
96   struct i915_context *i915 = i915_context(pipe);
97   util_slab_free(&i915->transfer_pool, transfer);
98}
99
100static void *
101i915_buffer_transfer_map( struct pipe_context *pipe,
102                          struct pipe_transfer *transfer )
103{
104   struct i915_buffer *buffer = i915_buffer(transfer->resource);
105   return buffer->data + transfer->box.x;
106}
107
108
109static void
110i915_buffer_transfer_inline_write( struct pipe_context *rm_ctx,
111                                   struct pipe_resource *resource,
112                                   unsigned level,
113                                   unsigned usage,
114                                   const struct pipe_box *box,
115                                   const void *data,
116                                   unsigned stride,
117                                   unsigned layer_stride)
118{
119   struct i915_buffer *buffer = i915_buffer(resource);
120
121   memcpy(buffer->data + box->x,
122          data,
123          box->width);
124}
125
126
127struct u_resource_vtbl i915_buffer_vtbl =
128{
129   i915_buffer_get_handle,	     /* get_handle */
130   i915_buffer_destroy,		     /* resource_destroy */
131   i915_get_transfer,		     /* get_transfer */
132   i915_transfer_destroy,	     /* transfer_destroy */
133   i915_buffer_transfer_map,	     /* transfer_map */
134   u_default_transfer_flush_region,  /* transfer_flush_region */
135   u_default_transfer_unmap,	     /* transfer_unmap */
136   i915_buffer_transfer_inline_write /* transfer_inline_write */
137};
138
139
140
141struct pipe_resource *
142i915_buffer_create(struct pipe_screen *screen,
143                    const struct pipe_resource *template)
144{
145   struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
146
147   if (!buf)
148      return NULL;
149
150   buf->b.b = *template;
151   buf->b.vtbl = &i915_buffer_vtbl;
152   pipe_reference_init(&buf->b.b.reference, 1);
153   buf->b.b.screen = screen;
154   buf->data = align_malloc(template->width0, 16);
155   buf->free_on_destroy = TRUE;
156
157   if (!buf->data)
158      goto err;
159
160   return &buf->b.b;
161
162err:
163   FREE(buf);
164   return NULL;
165}
166
167
168
169struct pipe_resource *
170i915_user_buffer_create(struct pipe_screen *screen,
171                        void *ptr,
172                        unsigned bytes,
173                        unsigned bind)
174{
175   struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
176
177   if (!buf)
178      return NULL;
179
180   pipe_reference_init(&buf->b.b.reference, 1);
181   buf->b.vtbl = &i915_buffer_vtbl;
182   buf->b.b.screen = screen;
183   buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
184   buf->b.b.usage = PIPE_USAGE_IMMUTABLE;
185   buf->b.b.bind = bind;
186   buf->b.b.flags = 0;
187   buf->b.b.width0 = bytes;
188   buf->b.b.height0 = 1;
189   buf->b.b.depth0 = 1;
190   buf->b.b.array_size = 1;
191
192   buf->data = ptr;
193   buf->free_on_destroy = FALSE;
194
195   return &buf->b.b;
196}
197