1/**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
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 VMWARE 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#include "util/u_inlines.h"
29#include "util/u_memory.h"
30#include "util/simple_list.h"
31
32#include "tgsi/tgsi_parse.h"
33
34#include "rbug_screen.h"
35#include "rbug_objects.h"
36#include "rbug_context.h"
37
38
39
40struct pipe_resource *
41rbug_resource_create(struct rbug_screen *rb_screen,
42                     struct pipe_resource *resource)
43{
44   struct rbug_resource *rb_resource;
45
46   if (!resource)
47      goto error;
48
49   assert(resource->screen == rb_screen->screen);
50
51   rb_resource = CALLOC_STRUCT(rbug_resource);
52   if (!rb_resource)
53      goto error;
54
55   memcpy(&rb_resource->base, resource, sizeof(struct pipe_resource));
56
57   pipe_reference_init(&rb_resource->base.reference, 1);
58   rb_resource->base.screen = &rb_screen->base;
59   rb_resource->resource = resource;
60
61   if (resource->target != PIPE_BUFFER)
62      rbug_screen_add_to_list(rb_screen, resources, rb_resource);
63
64   return &rb_resource->base;
65
66error:
67   pipe_resource_reference(&resource, NULL);
68   return NULL;
69}
70
71void
72rbug_resource_destroy(struct rbug_resource *rb_resource)
73{
74   struct rbug_screen *rb_screen = rbug_screen(rb_resource->base.screen);
75
76   if (rb_resource->base.target != PIPE_BUFFER)
77      rbug_screen_remove_from_list(rb_screen, resources, rb_resource);
78
79   pipe_resource_reference(&rb_resource->resource, NULL);
80   FREE(rb_resource);
81}
82
83
84struct pipe_surface *
85rbug_surface_create(struct rbug_context *rb_context,
86                    struct rbug_resource *rb_resource,
87                    struct pipe_surface *surface)
88{
89   struct rbug_surface *rb_surface;
90
91   if (!surface)
92      goto error;
93
94   assert(surface->texture == rb_resource->resource);
95
96   rb_surface = CALLOC_STRUCT(rbug_surface);
97   if (!rb_surface)
98      goto error;
99
100   memcpy(&rb_surface->base, surface, sizeof(struct pipe_surface));
101
102   pipe_reference_init(&rb_surface->base.reference, 1);
103   rb_surface->base.texture = NULL;
104   rb_surface->base.context = &rb_context->base;
105   rb_surface->surface = surface; /* we own the surface already */
106   pipe_resource_reference(&rb_surface->base.texture, &rb_resource->base);
107
108   return &rb_surface->base;
109
110error:
111   pipe_surface_reference(&surface, NULL);
112   return NULL;
113}
114
115void
116rbug_surface_destroy(struct rbug_context *rb_context,
117                     struct rbug_surface *rb_surface)
118{
119   pipe_resource_reference(&rb_surface->base.texture, NULL);
120   pipe_surface_reference(&rb_surface->surface, NULL);
121   FREE(rb_surface);
122}
123
124
125struct pipe_sampler_view *
126rbug_sampler_view_create(struct rbug_context *rb_context,
127                         struct rbug_resource *rb_resource,
128                         struct pipe_sampler_view *view)
129{
130   struct rbug_sampler_view *rb_view;
131
132   if (!view)
133      goto error;
134
135   assert(view->texture == rb_resource->resource);
136
137   rb_view = MALLOC(sizeof(struct rbug_sampler_view));
138
139   rb_view->base = *view;
140   rb_view->base.reference.count = 1;
141   rb_view->base.texture = NULL;
142   pipe_resource_reference(&rb_view->base.texture, &rb_resource->base);
143   rb_view->base.context = &rb_context->base;
144   rb_view->sampler_view = view;
145
146   return &rb_view->base;
147error:
148   return NULL;
149}
150
151void
152rbug_sampler_view_destroy(struct rbug_context *rb_context,
153                          struct rbug_sampler_view *rb_view)
154{
155   pipe_resource_reference(&rb_view->base.texture, NULL);
156   pipe_sampler_view_reference(&rb_view->sampler_view, NULL);
157   FREE(rb_view);
158}
159
160
161struct pipe_transfer *
162rbug_transfer_create(struct rbug_context *rb_context,
163                     struct rbug_resource *rb_resource,
164                     struct pipe_transfer *transfer)
165{
166   struct rbug_transfer *rb_transfer;
167
168   if (!transfer)
169      goto error;
170
171   assert(transfer->resource == rb_resource->resource);
172
173   rb_transfer = CALLOC_STRUCT(rbug_transfer);
174   if (!rb_transfer)
175      goto error;
176
177   memcpy(&rb_transfer->base, transfer, sizeof(struct pipe_transfer));
178
179   rb_transfer->base.resource = NULL;
180   rb_transfer->transfer = transfer;
181   rb_transfer->pipe = rb_context->pipe;
182
183   pipe_resource_reference(&rb_transfer->base.resource, &rb_resource->base);
184   assert(rb_transfer->base.resource == &rb_resource->base);
185
186   return &rb_transfer->base;
187
188error:
189   rb_context->pipe->transfer_unmap(rb_context->pipe, transfer);
190   return NULL;
191}
192
193void
194rbug_transfer_destroy(struct rbug_context *rb_context,
195                      struct rbug_transfer *rb_transfer)
196{
197   pipe_resource_reference(&rb_transfer->base.resource, NULL);
198   FREE(rb_transfer);
199}
200
201void *
202rbug_shader_create(struct rbug_context *rb_context,
203                   const struct pipe_shader_state *state,
204                   void *result, enum rbug_shader_type type)
205{
206   struct rbug_shader *rb_shader = CALLOC_STRUCT(rbug_shader);
207
208   rb_shader->type = type;
209   rb_shader->shader = result;
210   rb_shader->tokens = tgsi_dup_tokens(state->tokens);
211
212   /* works on context as well since its just a macro */
213   rbug_screen_add_to_list(rb_context, shaders, rb_shader);
214
215   return rb_shader;
216}
217
218void
219rbug_shader_destroy(struct rbug_context *rb_context,
220                    struct rbug_shader *rb_shader)
221{
222   struct pipe_context *pipe = rb_context->pipe;
223
224   /* works on context as well since its just a macro */
225   rbug_screen_remove_from_list(rb_context, shaders, rb_shader);
226
227   switch(rb_shader->type) {
228   case RBUG_SHADER_FRAGMENT:
229      if (rb_shader->replaced_shader)
230         pipe->delete_fs_state(pipe, rb_shader->replaced_shader);
231      pipe->delete_fs_state(pipe, rb_shader->shader);
232      break;
233   case RBUG_SHADER_VERTEX:
234      if (rb_shader->replaced_shader)
235         pipe->delete_vs_state(pipe, rb_shader->replaced_shader);
236      pipe->delete_vs_state(pipe, rb_shader->shader);
237      break;
238   case RBUG_SHADER_GEOM:
239      if (rb_shader->replaced_shader)
240         pipe->delete_gs_state(pipe, rb_shader->replaced_shader);
241      pipe->delete_gs_state(pipe, rb_shader->shader);
242      break;
243   default:
244      assert(0);
245   }
246
247   FREE(rb_shader->replaced_tokens);
248   FREE(rb_shader->tokens);
249   FREE(rb_shader);
250}
251