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/u_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   rbug_screen_add_to_list(rb_screen, resources, rb_resource);
62
63   return &rb_resource->base;
64
65error:
66   pipe_resource_reference(&resource, NULL);
67   return NULL;
68}
69
70void
71rbug_resource_destroy(struct rbug_resource *rb_resource)
72{
73   struct rbug_screen *rb_screen = rbug_screen(rb_resource->base.screen);
74   rbug_screen_remove_from_list(rb_screen, resources, rb_resource);
75
76   pipe_resource_reference(&rb_resource->resource, NULL);
77   FREE(rb_resource);
78}
79
80
81struct pipe_surface *
82rbug_surface_create(struct rbug_context *rb_context,
83                    struct rbug_resource *rb_resource,
84                    struct pipe_surface *surface)
85{
86   struct rbug_surface *rb_surface;
87
88   if(!surface)
89      goto error;
90
91   assert(surface->texture == rb_resource->resource);
92
93   rb_surface = CALLOC_STRUCT(rbug_surface);
94   if(!rb_surface)
95      goto error;
96
97   memcpy(&rb_surface->base, surface, sizeof(struct pipe_surface));
98
99   pipe_reference_init(&rb_surface->base.reference, 1);
100   rb_surface->base.texture = NULL;
101   rb_surface->base.context = &rb_context->base;
102   rb_surface->surface = surface; /* we own the surface already */
103   pipe_resource_reference(&rb_surface->base.texture, &rb_resource->base);
104
105   return &rb_surface->base;
106
107error:
108   pipe_surface_reference(&surface, NULL);
109   return NULL;
110}
111
112void
113rbug_surface_destroy(struct rbug_context *rb_context,
114                     struct rbug_surface *rb_surface)
115{
116   pipe_resource_reference(&rb_surface->base.texture, NULL);
117   pipe_surface_reference(&rb_surface->surface, NULL);
118   FREE(rb_surface);
119}
120
121
122struct pipe_sampler_view *
123rbug_sampler_view_create(struct rbug_context *rb_context,
124                         struct rbug_resource *rb_resource,
125                         struct pipe_sampler_view *view)
126{
127   struct rbug_sampler_view *rb_view;
128
129   if (!view)
130      goto error;
131
132   assert(view->texture == rb_resource->resource);
133
134   rb_view = MALLOC(sizeof(struct rbug_sampler_view));
135
136   rb_view->base = *view;
137   rb_view->base.reference.count = 1;
138   rb_view->base.texture = NULL;
139   pipe_resource_reference(&rb_view->base.texture, &rb_resource->base);
140   rb_view->base.context = rb_context->pipe;
141   rb_view->sampler_view = view;
142
143   return &rb_view->base;
144error:
145   return NULL;
146}
147
148void
149rbug_sampler_view_destroy(struct rbug_context *rb_context,
150                          struct rbug_sampler_view *rb_view)
151{
152   pipe_resource_reference(&rb_view->base.texture, NULL);
153   rb_context->pipe->sampler_view_destroy(rb_context->pipe,
154                                          rb_view->sampler_view);
155   FREE(rb_view);
156}
157
158
159struct pipe_transfer *
160rbug_transfer_create(struct rbug_context *rb_context,
161                     struct rbug_resource *rb_resource,
162                     struct pipe_transfer *transfer)
163{
164   struct rbug_transfer *rb_transfer;
165
166   if(!transfer)
167      goto error;
168
169   assert(transfer->resource == rb_resource->resource);
170
171   rb_transfer = CALLOC_STRUCT(rbug_transfer);
172   if(!rb_transfer)
173      goto error;
174
175   memcpy(&rb_transfer->base, transfer, sizeof(struct pipe_transfer));
176
177   rb_transfer->base.resource = NULL;
178   rb_transfer->transfer = transfer;
179   rb_transfer->pipe = rb_context->pipe;
180
181   pipe_resource_reference(&rb_transfer->base.resource, &rb_resource->base);
182   assert(rb_transfer->base.resource == &rb_resource->base);
183
184   return &rb_transfer->base;
185
186error:
187   rb_context->pipe->transfer_destroy(rb_context->pipe, transfer);
188   return NULL;
189}
190
191void
192rbug_transfer_destroy(struct rbug_context *rb_context,
193                      struct rbug_transfer *rb_transfer)
194{
195   pipe_resource_reference(&rb_transfer->base.resource, NULL);
196   rb_transfer->pipe->transfer_destroy(rb_context->pipe,
197                                       rb_transfer->transfer);
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