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 
40 struct pipe_resource *
rbug_resource_create(struct rbug_screen * rb_screen,struct pipe_resource * resource)41 rbug_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 
65 error:
66    pipe_resource_reference(&resource, NULL);
67    return NULL;
68 }
69 
70 void
rbug_resource_destroy(struct rbug_resource * rb_resource)71 rbug_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 
81 struct pipe_surface *
rbug_surface_create(struct rbug_context * rb_context,struct rbug_resource * rb_resource,struct pipe_surface * surface)82 rbug_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 
107 error:
108    pipe_surface_reference(&surface, NULL);
109    return NULL;
110 }
111 
112 void
rbug_surface_destroy(struct rbug_context * rb_context,struct rbug_surface * rb_surface)113 rbug_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 
122 struct pipe_sampler_view *
rbug_sampler_view_create(struct rbug_context * rb_context,struct rbug_resource * rb_resource,struct pipe_sampler_view * view)123 rbug_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;
144 error:
145    return NULL;
146 }
147 
148 void
rbug_sampler_view_destroy(struct rbug_context * rb_context,struct rbug_sampler_view * rb_view)149 rbug_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 
159 struct pipe_transfer *
rbug_transfer_create(struct rbug_context * rb_context,struct rbug_resource * rb_resource,struct pipe_transfer * transfer)160 rbug_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 
186 error:
187    rb_context->pipe->transfer_destroy(rb_context->pipe, transfer);
188    return NULL;
189 }
190 
191 void
rbug_transfer_destroy(struct rbug_context * rb_context,struct rbug_transfer * rb_transfer)192 rbug_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 
201 void *
rbug_shader_create(struct rbug_context * rb_context,const struct pipe_shader_state * state,void * result,enum rbug_shader_type type)202 rbug_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 
218 void
rbug_shader_destroy(struct rbug_context * rb_context,struct rbug_shader * rb_shader)219 rbug_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