1 /**************************************************************************
2  *
3  * Copyright 2009 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 
29 #include "pipe/p_context.h"
30 
31 #include "util/u_format.h"
32 #include "util/u_memory.h"
33 #include "util/u_inlines.h"
34 
35 #include "glhd_context.h"
36 #include "glhd_objects.h"
37 
38 
39 static void
galahad_context_destroy(struct pipe_context * _pipe)40 galahad_context_destroy(struct pipe_context *_pipe)
41 {
42    struct galahad_context *glhd_pipe = galahad_context(_pipe);
43    struct pipe_context *pipe = glhd_pipe->pipe;
44 
45    pipe->destroy(pipe);
46 
47    FREE(glhd_pipe);
48 }
49 
50 static void
galahad_context_draw_vbo(struct pipe_context * _pipe,const struct pipe_draw_info * info)51 galahad_context_draw_vbo(struct pipe_context *_pipe,
52                  const struct pipe_draw_info *info)
53 {
54    struct galahad_context *glhd_pipe = galahad_context(_pipe);
55    struct pipe_context *pipe = glhd_pipe->pipe;
56 
57    /* XXX we should check that all bound resources are unmapped
58     * before drawing.
59     */
60 
61    pipe->draw_vbo(pipe, info);
62 }
63 
64 static struct pipe_query *
galahad_context_create_query(struct pipe_context * _pipe,unsigned query_type)65 galahad_context_create_query(struct pipe_context *_pipe,
66                       unsigned query_type)
67 {
68    struct galahad_context *glhd_pipe = galahad_context(_pipe);
69    struct pipe_context *pipe = glhd_pipe->pipe;
70 
71    if (query_type == PIPE_QUERY_OCCLUSION_COUNTER &&
72       !pipe->screen->get_param(pipe->screen, PIPE_CAP_OCCLUSION_QUERY)) {
73       glhd_error("Occlusion query requested but not supported");
74    }
75 
76    if (query_type == PIPE_QUERY_TIME_ELAPSED &&
77       !pipe->screen->get_param(pipe->screen, PIPE_CAP_TIMER_QUERY)) {
78       glhd_error("Timer query requested but not supported");
79    }
80 
81    return pipe->create_query(pipe,
82                              query_type);
83 }
84 
85 static void
galahad_context_destroy_query(struct pipe_context * _pipe,struct pipe_query * query)86 galahad_context_destroy_query(struct pipe_context *_pipe,
87                        struct pipe_query *query)
88 {
89    struct galahad_context *glhd_pipe = galahad_context(_pipe);
90    struct pipe_context *pipe = glhd_pipe->pipe;
91 
92    pipe->destroy_query(pipe,
93                        query);
94 }
95 
96 static void
galahad_context_begin_query(struct pipe_context * _pipe,struct pipe_query * query)97 galahad_context_begin_query(struct pipe_context *_pipe,
98                      struct pipe_query *query)
99 {
100    struct galahad_context *glhd_pipe = galahad_context(_pipe);
101    struct pipe_context *pipe = glhd_pipe->pipe;
102 
103    pipe->begin_query(pipe,
104                      query);
105 }
106 
107 static void
galahad_context_end_query(struct pipe_context * _pipe,struct pipe_query * query)108 galahad_context_end_query(struct pipe_context *_pipe,
109                    struct pipe_query *query)
110 {
111    struct galahad_context *glhd_pipe = galahad_context(_pipe);
112    struct pipe_context *pipe = glhd_pipe->pipe;
113 
114    pipe->end_query(pipe,
115                    query);
116 }
117 
118 static boolean
galahad_context_get_query_result(struct pipe_context * _pipe,struct pipe_query * query,boolean wait,union pipe_query_result * result)119 galahad_context_get_query_result(struct pipe_context *_pipe,
120                           struct pipe_query *query,
121                           boolean wait,
122                           union pipe_query_result *result)
123 {
124    struct galahad_context *glhd_pipe = galahad_context(_pipe);
125    struct pipe_context *pipe = glhd_pipe->pipe;
126 
127    return pipe->get_query_result(pipe,
128                                  query,
129                                  wait,
130                                  result);
131 }
132 
133 static void *
galahad_context_create_blend_state(struct pipe_context * _pipe,const struct pipe_blend_state * blend)134 galahad_context_create_blend_state(struct pipe_context *_pipe,
135                             const struct pipe_blend_state *blend)
136 {
137    struct galahad_context *glhd_pipe = galahad_context(_pipe);
138    struct pipe_context *pipe = glhd_pipe->pipe;
139 
140    if (blend->logicop_enable) {
141       if (blend->rt[0].blend_enable) {
142          glhd_warn("Blending enabled for render target 0, but logicops "
143             "are enabled");
144       }
145    }
146 
147    return pipe->create_blend_state(pipe,
148                                    blend);
149 }
150 
151 static void
galahad_context_bind_blend_state(struct pipe_context * _pipe,void * blend)152 galahad_context_bind_blend_state(struct pipe_context *_pipe,
153                           void *blend)
154 {
155    struct galahad_context *glhd_pipe = galahad_context(_pipe);
156    struct pipe_context *pipe = glhd_pipe->pipe;
157 
158    pipe->bind_blend_state(pipe,
159                               blend);
160 }
161 
162 static void
galahad_context_delete_blend_state(struct pipe_context * _pipe,void * blend)163 galahad_context_delete_blend_state(struct pipe_context *_pipe,
164                             void *blend)
165 {
166    struct galahad_context *glhd_pipe = galahad_context(_pipe);
167    struct pipe_context *pipe = glhd_pipe->pipe;
168 
169    pipe->delete_blend_state(pipe,
170                             blend);
171 }
172 
173 static void *
galahad_context_create_sampler_state(struct pipe_context * _pipe,const struct pipe_sampler_state * sampler)174 galahad_context_create_sampler_state(struct pipe_context *_pipe,
175                               const struct pipe_sampler_state *sampler)
176 {
177    struct galahad_context *glhd_pipe = galahad_context(_pipe);
178    struct pipe_context *pipe = glhd_pipe->pipe;
179 
180    return pipe->create_sampler_state(pipe,
181                                      sampler);
182 }
183 
184 static void
galahad_context_bind_sampler_states(struct pipe_context * _pipe,unsigned shader,unsigned start,unsigned num_samplers,void ** samplers)185 galahad_context_bind_sampler_states(struct pipe_context *_pipe,
186                                     unsigned shader,
187                                     unsigned start,
188                                     unsigned num_samplers,
189                                     void **samplers)
190 {
191    struct galahad_context *glhd_pipe = galahad_context(_pipe);
192    struct pipe_context *pipe = glhd_pipe->pipe;
193 
194    if (num_samplers > PIPE_MAX_SAMPLERS) {
195       glhd_error("%u samplers requested, "
196          "but only %u are permitted by API",
197          num_samplers, PIPE_MAX_SAMPLERS);
198    }
199 
200    switch (shader) {
201    case PIPE_SHADER_VERTEX:
202       pipe->bind_vertex_sampler_states(pipe, num_samplers, samplers);
203       break;
204    case PIPE_SHADER_FRAGMENT:
205       pipe->bind_fragment_sampler_states(pipe, num_samplers, samplers);
206       break;
207    default:
208       assert(0);
209    }
210 }
211 
212 static void
galahad_context_bind_vertex_sampler_states(struct pipe_context * _pipe,unsigned num_samplers,void ** samplers)213 galahad_context_bind_vertex_sampler_states(struct pipe_context *_pipe,
214                                            unsigned num_samplers,
215                                            void **samplers)
216 {
217    galahad_context_bind_sampler_states(_pipe, PIPE_SHADER_VERTEX,
218                                        0, num_samplers, samplers);
219 }
220 
221 static void
galahad_context_bind_fragment_sampler_states(struct pipe_context * _pipe,unsigned num_samplers,void ** samplers)222 galahad_context_bind_fragment_sampler_states(struct pipe_context *_pipe,
223                                              unsigned num_samplers,
224                                              void **samplers)
225 {
226    galahad_context_bind_sampler_states(_pipe, PIPE_SHADER_FRAGMENT,
227                                        0, num_samplers, samplers);
228 }
229 
230 
231 static void
galahad_context_delete_sampler_state(struct pipe_context * _pipe,void * sampler)232 galahad_context_delete_sampler_state(struct pipe_context *_pipe,
233                               void *sampler)
234 {
235    struct galahad_context *glhd_pipe = galahad_context(_pipe);
236    struct pipe_context *pipe = glhd_pipe->pipe;
237 
238    pipe->delete_sampler_state(pipe,
239                               sampler);
240 }
241 
242 static void *
galahad_context_create_rasterizer_state(struct pipe_context * _pipe,const struct pipe_rasterizer_state * rasterizer)243 galahad_context_create_rasterizer_state(struct pipe_context *_pipe,
244                                  const struct pipe_rasterizer_state *rasterizer)
245 {
246    struct galahad_context *glhd_pipe = galahad_context(_pipe);
247    struct pipe_context *pipe = glhd_pipe->pipe;
248 
249    if (rasterizer->point_quad_rasterization) {
250        if (rasterizer->point_smooth) {
251            glhd_warn("Point smoothing requested but ignored");
252        }
253    } else {
254        if (rasterizer->sprite_coord_enable) {
255            glhd_warn("Point sprites requested but ignored");
256        }
257    }
258 
259    return pipe->create_rasterizer_state(pipe,
260                                         rasterizer);
261 }
262 
263 static void
galahad_context_bind_rasterizer_state(struct pipe_context * _pipe,void * rasterizer)264 galahad_context_bind_rasterizer_state(struct pipe_context *_pipe,
265                                void *rasterizer)
266 {
267    struct galahad_context *glhd_pipe = galahad_context(_pipe);
268    struct pipe_context *pipe = glhd_pipe->pipe;
269 
270    pipe->bind_rasterizer_state(pipe,
271                                rasterizer);
272 }
273 
274 static void
galahad_context_delete_rasterizer_state(struct pipe_context * _pipe,void * rasterizer)275 galahad_context_delete_rasterizer_state(struct pipe_context *_pipe,
276                                  void *rasterizer)
277 {
278    struct galahad_context *glhd_pipe = galahad_context(_pipe);
279    struct pipe_context *pipe = glhd_pipe->pipe;
280 
281    pipe->delete_rasterizer_state(pipe,
282                                  rasterizer);
283 }
284 
285 static void *
galahad_context_create_depth_stencil_alpha_state(struct pipe_context * _pipe,const struct pipe_depth_stencil_alpha_state * depth_stencil_alpha)286 galahad_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe,
287                                           const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
288 {
289    struct galahad_context *glhd_pipe = galahad_context(_pipe);
290    struct pipe_context *pipe = glhd_pipe->pipe;
291 
292    return pipe->create_depth_stencil_alpha_state(pipe,
293                                                  depth_stencil_alpha);
294 }
295 
296 static void
galahad_context_bind_depth_stencil_alpha_state(struct pipe_context * _pipe,void * depth_stencil_alpha)297 galahad_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,
298                                         void *depth_stencil_alpha)
299 {
300    struct galahad_context *glhd_pipe = galahad_context(_pipe);
301    struct pipe_context *pipe = glhd_pipe->pipe;
302 
303    pipe->bind_depth_stencil_alpha_state(pipe,
304                                         depth_stencil_alpha);
305 }
306 
307 static void
galahad_context_delete_depth_stencil_alpha_state(struct pipe_context * _pipe,void * depth_stencil_alpha)308 galahad_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
309                                           void *depth_stencil_alpha)
310 {
311    struct galahad_context *glhd_pipe = galahad_context(_pipe);
312    struct pipe_context *pipe = glhd_pipe->pipe;
313 
314    pipe->delete_depth_stencil_alpha_state(pipe,
315                                           depth_stencil_alpha);
316 }
317 
318 static void *
galahad_context_create_fs_state(struct pipe_context * _pipe,const struct pipe_shader_state * fs)319 galahad_context_create_fs_state(struct pipe_context *_pipe,
320                          const struct pipe_shader_state *fs)
321 {
322    struct galahad_context *glhd_pipe = galahad_context(_pipe);
323    struct pipe_context *pipe = glhd_pipe->pipe;
324 
325    return pipe->create_fs_state(pipe,
326                                 fs);
327 }
328 
329 static void
galahad_context_bind_fs_state(struct pipe_context * _pipe,void * fs)330 galahad_context_bind_fs_state(struct pipe_context *_pipe,
331                        void *fs)
332 {
333    struct galahad_context *glhd_pipe = galahad_context(_pipe);
334    struct pipe_context *pipe = glhd_pipe->pipe;
335 
336    pipe->bind_fs_state(pipe,
337                        fs);
338 }
339 
340 static void
galahad_context_delete_fs_state(struct pipe_context * _pipe,void * fs)341 galahad_context_delete_fs_state(struct pipe_context *_pipe,
342                          void *fs)
343 {
344    struct galahad_context *glhd_pipe = galahad_context(_pipe);
345    struct pipe_context *pipe = glhd_pipe->pipe;
346 
347    pipe->delete_fs_state(pipe,
348                          fs);
349 }
350 
351 static void *
galahad_context_create_vs_state(struct pipe_context * _pipe,const struct pipe_shader_state * vs)352 galahad_context_create_vs_state(struct pipe_context *_pipe,
353                          const struct pipe_shader_state *vs)
354 {
355    struct galahad_context *glhd_pipe = galahad_context(_pipe);
356    struct pipe_context *pipe = glhd_pipe->pipe;
357 
358    return pipe->create_vs_state(pipe,
359                                 vs);
360 }
361 
362 static void
galahad_context_bind_vs_state(struct pipe_context * _pipe,void * vs)363 galahad_context_bind_vs_state(struct pipe_context *_pipe,
364                        void *vs)
365 {
366    struct galahad_context *glhd_pipe = galahad_context(_pipe);
367    struct pipe_context *pipe = glhd_pipe->pipe;
368 
369    pipe->bind_vs_state(pipe,
370                        vs);
371 }
372 
373 static void
galahad_context_delete_vs_state(struct pipe_context * _pipe,void * vs)374 galahad_context_delete_vs_state(struct pipe_context *_pipe,
375                          void *vs)
376 {
377    struct galahad_context *glhd_pipe = galahad_context(_pipe);
378    struct pipe_context *pipe = glhd_pipe->pipe;
379 
380    pipe->delete_vs_state(pipe,
381                          vs);
382 }
383 
384 
385 static void *
galahad_context_create_vertex_elements_state(struct pipe_context * _pipe,unsigned num_elements,const struct pipe_vertex_element * vertex_elements)386 galahad_context_create_vertex_elements_state(struct pipe_context *_pipe,
387                                       unsigned num_elements,
388                                       const struct pipe_vertex_element *vertex_elements)
389 {
390    struct galahad_context *glhd_pipe = galahad_context(_pipe);
391    struct pipe_context *pipe = glhd_pipe->pipe;
392 
393    /* XXX check if stride lines up with element size, at least for floats */
394 
395    return pipe->create_vertex_elements_state(pipe,
396                                              num_elements,
397                                              vertex_elements);
398 }
399 
400 static void
galahad_context_bind_vertex_elements_state(struct pipe_context * _pipe,void * velems)401 galahad_context_bind_vertex_elements_state(struct pipe_context *_pipe,
402                                     void *velems)
403 {
404    struct galahad_context *glhd_pipe = galahad_context(_pipe);
405    struct pipe_context *pipe = glhd_pipe->pipe;
406 
407    pipe->bind_vertex_elements_state(pipe,
408                                     velems);
409 }
410 
411 static void
galahad_context_delete_vertex_elements_state(struct pipe_context * _pipe,void * velems)412 galahad_context_delete_vertex_elements_state(struct pipe_context *_pipe,
413                                       void *velems)
414 {
415    struct galahad_context *glhd_pipe = galahad_context(_pipe);
416    struct pipe_context *pipe = glhd_pipe->pipe;
417 
418    pipe->delete_vertex_elements_state(pipe,
419                                       velems);
420 }
421 
422 static void
galahad_context_set_blend_color(struct pipe_context * _pipe,const struct pipe_blend_color * blend_color)423 galahad_context_set_blend_color(struct pipe_context *_pipe,
424                          const struct pipe_blend_color *blend_color)
425 {
426    struct galahad_context *glhd_pipe = galahad_context(_pipe);
427    struct pipe_context *pipe = glhd_pipe->pipe;
428 
429    pipe->set_blend_color(pipe,
430                          blend_color);
431 }
432 
433 static void
galahad_context_set_stencil_ref(struct pipe_context * _pipe,const struct pipe_stencil_ref * stencil_ref)434 galahad_context_set_stencil_ref(struct pipe_context *_pipe,
435                          const struct pipe_stencil_ref *stencil_ref)
436 {
437    struct galahad_context *glhd_pipe = galahad_context(_pipe);
438    struct pipe_context *pipe = glhd_pipe->pipe;
439 
440    pipe->set_stencil_ref(pipe,
441                          stencil_ref);
442 }
443 
444 static void
galahad_context_set_clip_state(struct pipe_context * _pipe,const struct pipe_clip_state * clip)445 galahad_context_set_clip_state(struct pipe_context *_pipe,
446                         const struct pipe_clip_state *clip)
447 {
448    struct galahad_context *glhd_pipe = galahad_context(_pipe);
449    struct pipe_context *pipe = glhd_pipe->pipe;
450 
451    pipe->set_clip_state(pipe,
452                         clip);
453 }
454 
455 static void
galahad_context_set_sample_mask(struct pipe_context * _pipe,unsigned sample_mask)456 galahad_context_set_sample_mask(struct pipe_context *_pipe,
457                          unsigned sample_mask)
458 {
459    struct galahad_context *glhd_pipe = galahad_context(_pipe);
460    struct pipe_context *pipe = glhd_pipe->pipe;
461 
462    pipe->set_sample_mask(pipe,
463                          sample_mask);
464 }
465 
466 static void
galahad_context_set_constant_buffer(struct pipe_context * _pipe,uint shader,uint index,struct pipe_constant_buffer * _cb)467 galahad_context_set_constant_buffer(struct pipe_context *_pipe,
468                              uint shader,
469                              uint index,
470                              struct pipe_constant_buffer *_cb)
471 {
472    struct galahad_context *glhd_pipe = galahad_context(_pipe);
473    struct pipe_context *pipe = glhd_pipe->pipe;
474    struct pipe_constant_buffer cb;
475 
476    if (shader >= PIPE_SHADER_TYPES) {
477       glhd_error("Unknown shader type %u", shader);
478    }
479 
480    if (index &&
481       index >=
482          pipe->screen->get_shader_param(pipe->screen, shader, PIPE_SHADER_CAP_MAX_CONST_BUFFERS)) {
483       glhd_error("Access to constant buffer %u requested, "
484          "but only %d are supported",
485          index,
486          pipe->screen->get_shader_param(pipe->screen, shader, PIPE_SHADER_CAP_MAX_CONST_BUFFERS));
487    }
488 
489    /* XXX hmm? unwrap the input state */
490    if (_cb) {
491       cb = *_cb;
492       cb.buffer = galahad_resource_unwrap(_cb->buffer);
493    }
494 
495    pipe->set_constant_buffer(pipe,
496                              shader,
497                              index,
498                              _cb ? &cb : NULL);
499 }
500 
501 static void
galahad_context_set_framebuffer_state(struct pipe_context * _pipe,const struct pipe_framebuffer_state * _state)502 galahad_context_set_framebuffer_state(struct pipe_context *_pipe,
503                                const struct pipe_framebuffer_state *_state)
504 {
505    struct galahad_context *glhd_pipe = galahad_context(_pipe);
506    struct pipe_context *pipe = glhd_pipe->pipe;
507    struct pipe_framebuffer_state unwrapped_state;
508    struct pipe_framebuffer_state *state = NULL;
509    unsigned i;
510 
511    if (_state->nr_cbufs > PIPE_MAX_COLOR_BUFS) {
512       glhd_error("%d render targets bound, but only %d are permitted by API",
513          _state->nr_cbufs, PIPE_MAX_COLOR_BUFS);
514    } else if (_state->nr_cbufs >
515       pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS)) {
516       glhd_warn("%d render targets bound, but only %d are supported",
517          _state->nr_cbufs,
518          pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS));
519    }
520 
521    /* unwrap the input state */
522    if (_state) {
523       memcpy(&unwrapped_state, _state, sizeof(unwrapped_state));
524       for(i = 0; i < _state->nr_cbufs; i++)
525          unwrapped_state.cbufs[i] = galahad_surface_unwrap(_state->cbufs[i]);
526       for (; i < PIPE_MAX_COLOR_BUFS; i++)
527          unwrapped_state.cbufs[i] = NULL;
528       unwrapped_state.zsbuf = galahad_surface_unwrap(_state->zsbuf);
529       state = &unwrapped_state;
530    }
531 
532    pipe->set_framebuffer_state(pipe,
533                                state);
534 }
535 
536 static void
galahad_context_set_polygon_stipple(struct pipe_context * _pipe,const struct pipe_poly_stipple * poly_stipple)537 galahad_context_set_polygon_stipple(struct pipe_context *_pipe,
538                              const struct pipe_poly_stipple *poly_stipple)
539 {
540    struct galahad_context *glhd_pipe = galahad_context(_pipe);
541    struct pipe_context *pipe = glhd_pipe->pipe;
542 
543    pipe->set_polygon_stipple(pipe,
544                              poly_stipple);
545 }
546 
547 static void
galahad_context_set_scissor_state(struct pipe_context * _pipe,const struct pipe_scissor_state * scissor)548 galahad_context_set_scissor_state(struct pipe_context *_pipe,
549                            const struct pipe_scissor_state *scissor)
550 {
551    struct galahad_context *glhd_pipe = galahad_context(_pipe);
552    struct pipe_context *pipe = glhd_pipe->pipe;
553 
554    pipe->set_scissor_state(pipe,
555                            scissor);
556 }
557 
558 static void
galahad_context_set_viewport_state(struct pipe_context * _pipe,const struct pipe_viewport_state * viewport)559 galahad_context_set_viewport_state(struct pipe_context *_pipe,
560                             const struct pipe_viewport_state *viewport)
561 {
562    struct galahad_context *glhd_pipe = galahad_context(_pipe);
563    struct pipe_context *pipe = glhd_pipe->pipe;
564 
565    pipe->set_viewport_state(pipe,
566                             viewport);
567 }
568 
569 static void
galahad_context_set_sampler_views(struct pipe_context * _pipe,unsigned shader,unsigned start,unsigned num,struct pipe_sampler_view ** _views)570 galahad_context_set_sampler_views(struct pipe_context *_pipe,
571                                   unsigned shader,
572                                   unsigned start,
573                                   unsigned num,
574                                   struct pipe_sampler_view **_views)
575 {
576    struct galahad_context *glhd_pipe = galahad_context(_pipe);
577    struct pipe_context *pipe = glhd_pipe->pipe;
578    struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
579    struct pipe_sampler_view **views = NULL;
580    unsigned i;
581 
582    if (_views) {
583       for (i = 0; i < num; i++)
584          unwrapped_views[i] = galahad_sampler_view_unwrap(_views[i]);
585       for (; i < PIPE_MAX_SAMPLERS; i++)
586          unwrapped_views[i] = NULL;
587 
588       views = unwrapped_views;
589    }
590 
591    switch (shader) {
592    case PIPE_SHADER_VERTEX:
593       pipe->set_vertex_sampler_views(pipe, num, views);
594       break;
595    case PIPE_SHADER_FRAGMENT:
596       pipe->set_fragment_sampler_views(pipe, num, views);
597       break;
598    default:
599       assert(0);
600    }
601 }
602 
603 static void
galahad_context_set_vertex_sampler_views(struct pipe_context * _pipe,unsigned num,struct pipe_sampler_view ** _views)604 galahad_context_set_vertex_sampler_views(struct pipe_context *_pipe,
605                                          unsigned num,
606                                          struct pipe_sampler_view **_views)
607 {
608    galahad_context_set_sampler_views(_pipe, PIPE_SHADER_VERTEX,
609                                      0, num, _views);
610 }
611 
612 static void
galahad_context_set_fragment_sampler_views(struct pipe_context * _pipe,unsigned num,struct pipe_sampler_view ** _views)613 galahad_context_set_fragment_sampler_views(struct pipe_context *_pipe,
614                                          unsigned num,
615                                          struct pipe_sampler_view **_views)
616 {
617    galahad_context_set_sampler_views(_pipe, PIPE_SHADER_FRAGMENT,
618                                      0, num, _views);
619 }
620 
621 
622 static void
galahad_context_set_vertex_buffers(struct pipe_context * _pipe,unsigned num_buffers,const struct pipe_vertex_buffer * _buffers)623 galahad_context_set_vertex_buffers(struct pipe_context *_pipe,
624                             unsigned num_buffers,
625                             const struct pipe_vertex_buffer *_buffers)
626 {
627    struct galahad_context *glhd_pipe = galahad_context(_pipe);
628    struct pipe_context *pipe = glhd_pipe->pipe;
629    struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS];
630    struct pipe_vertex_buffer *buffers = NULL;
631    unsigned i;
632 
633    if (num_buffers) {
634       memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers));
635       for (i = 0; i < num_buffers; i++)
636          unwrapped_buffers[i].buffer = galahad_resource_unwrap(_buffers[i].buffer);
637       buffers = unwrapped_buffers;
638    }
639 
640    pipe->set_vertex_buffers(pipe,
641                             num_buffers,
642                             buffers);
643 }
644 
645 static void
galahad_context_set_index_buffer(struct pipe_context * _pipe,const struct pipe_index_buffer * _ib)646 galahad_context_set_index_buffer(struct pipe_context *_pipe,
647                          const struct pipe_index_buffer *_ib)
648 {
649    struct galahad_context *glhd_pipe = galahad_context(_pipe);
650    struct pipe_context *pipe = glhd_pipe->pipe;
651    struct pipe_index_buffer unwrapped_ib, *ib = NULL;
652 
653    if (_ib) {
654       if (_ib->buffer || _ib->user_buffer) {
655          switch (_ib->index_size) {
656          case 1:
657          case 2:
658          case 4:
659             break;
660          default:
661             glhd_warn("unrecognized index size %d", _ib->index_size);
662             break;
663          }
664       }
665       else if (_ib->offset || _ib->index_size) {
666          glhd_warn("non-indexed state with index offset %d and index size %d",
667                _ib->offset, _ib->index_size);
668       }
669 
670       unwrapped_ib = *_ib;
671       unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer);
672       ib = &unwrapped_ib;
673    }
674 
675    pipe->set_index_buffer(pipe, ib);
676 }
677 
678 static void
galahad_context_resource_copy_region(struct pipe_context * _pipe,struct pipe_resource * _dst,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,struct pipe_resource * _src,unsigned src_level,const struct pipe_box * src_box)679 galahad_context_resource_copy_region(struct pipe_context *_pipe,
680                               struct pipe_resource *_dst,
681                               unsigned dst_level,
682                               unsigned dstx,
683                               unsigned dsty,
684                               unsigned dstz,
685                               struct pipe_resource *_src,
686                               unsigned src_level,
687                               const struct pipe_box *src_box)
688 {
689    struct galahad_context *glhd_pipe = galahad_context(_pipe);
690    struct galahad_resource *glhd_resource_dst = galahad_resource(_dst);
691    struct galahad_resource *glhd_resource_src = galahad_resource(_src);
692    struct pipe_context *pipe = glhd_pipe->pipe;
693    struct pipe_resource *dst = glhd_resource_dst->resource;
694    struct pipe_resource *src = glhd_resource_src->resource;
695 
696    if (_dst->format != _src->format) {
697       const struct util_format_description *src_desc =
698          util_format_description(_src->format);
699       const struct util_format_description *dst_desc =
700          util_format_description(_dst->format);
701       if (!util_is_format_compatible(src_desc, dst_desc))
702          glhd_warn("Format mismatch: Source is %s, destination is %s",
703             src_desc->short_name,
704             dst_desc->short_name);
705    }
706 
707    if ((_src->target == PIPE_BUFFER && _dst->target != PIPE_BUFFER) ||
708        (_src->target != PIPE_BUFFER && _dst->target == PIPE_BUFFER)) {
709       glhd_warn("Resource target mismatch: Source is %i, destination is %i",
710                 _src->target, _dst->target);
711    }
712 
713    pipe->resource_copy_region(pipe,
714                               dst,
715                               dst_level,
716                               dstx,
717                               dsty,
718                               dstz,
719                               src,
720                               src_level,
721                               src_box);
722 }
723 
724 static void
galahad_context_clear(struct pipe_context * _pipe,unsigned buffers,const union pipe_color_union * color,double depth,unsigned stencil)725 galahad_context_clear(struct pipe_context *_pipe,
726                unsigned buffers,
727                const union pipe_color_union *color,
728                double depth,
729                unsigned stencil)
730 {
731    struct galahad_context *glhd_pipe = galahad_context(_pipe);
732    struct pipe_context *pipe = glhd_pipe->pipe;
733 
734    pipe->clear(pipe,
735                buffers,
736                color,
737                depth,
738                stencil);
739 }
740 
741 static void
galahad_context_clear_render_target(struct pipe_context * _pipe,struct pipe_surface * _dst,const union pipe_color_union * color,unsigned dstx,unsigned dsty,unsigned width,unsigned height)742 galahad_context_clear_render_target(struct pipe_context *_pipe,
743                              struct pipe_surface *_dst,
744                              const union pipe_color_union *color,
745                              unsigned dstx, unsigned dsty,
746                              unsigned width, unsigned height)
747 {
748    struct galahad_context *glhd_pipe = galahad_context(_pipe);
749    struct galahad_surface *glhd_surface_dst = galahad_surface(_dst);
750    struct pipe_context *pipe = glhd_pipe->pipe;
751    struct pipe_surface *dst = glhd_surface_dst->surface;
752 
753    pipe->clear_render_target(pipe,
754                              dst,
755                              color,
756                              dstx,
757                              dsty,
758                              width,
759                              height);
760 }
761 static void
galahad_context_clear_depth_stencil(struct pipe_context * _pipe,struct pipe_surface * _dst,unsigned clear_flags,double depth,unsigned stencil,unsigned dstx,unsigned dsty,unsigned width,unsigned height)762 galahad_context_clear_depth_stencil(struct pipe_context *_pipe,
763                              struct pipe_surface *_dst,
764                              unsigned clear_flags,
765                              double depth,
766                              unsigned stencil,
767                              unsigned dstx, unsigned dsty,
768                              unsigned width, unsigned height)
769 {
770    struct galahad_context *glhd_pipe = galahad_context(_pipe);
771    struct galahad_surface *glhd_surface_dst = galahad_surface(_dst);
772    struct pipe_context *pipe = glhd_pipe->pipe;
773    struct pipe_surface *dst = glhd_surface_dst->surface;
774 
775    pipe->clear_depth_stencil(pipe,
776                              dst,
777                              clear_flags,
778                              depth,
779                              stencil,
780                              dstx,
781                              dsty,
782                              width,
783                              height);
784 
785 }
786 
787 static void
galahad_context_flush(struct pipe_context * _pipe,struct pipe_fence_handle ** fence)788 galahad_context_flush(struct pipe_context *_pipe,
789                struct pipe_fence_handle **fence)
790 {
791    struct galahad_context *glhd_pipe = galahad_context(_pipe);
792    struct pipe_context *pipe = glhd_pipe->pipe;
793 
794    pipe->flush(pipe,
795                fence);
796 }
797 
798 static struct pipe_sampler_view *
galahad_context_create_sampler_view(struct pipe_context * _pipe,struct pipe_resource * _resource,const struct pipe_sampler_view * templ)799 galahad_context_create_sampler_view(struct pipe_context *_pipe,
800                                      struct pipe_resource *_resource,
801                                      const struct pipe_sampler_view *templ)
802 {
803    struct galahad_context *glhd_context = galahad_context(_pipe);
804    struct galahad_resource *glhd_resource = galahad_resource(_resource);
805    struct pipe_context *pipe = glhd_context->pipe;
806    struct pipe_resource *resource = glhd_resource->resource;
807    struct pipe_sampler_view *result;
808 
809    result = pipe->create_sampler_view(pipe,
810                                       resource,
811                                       templ);
812 
813    if (result)
814       return galahad_sampler_view_create(glhd_context, glhd_resource, result);
815    return NULL;
816 }
817 
818 static void
galahad_context_sampler_view_destroy(struct pipe_context * _pipe,struct pipe_sampler_view * _view)819 galahad_context_sampler_view_destroy(struct pipe_context *_pipe,
820                                       struct pipe_sampler_view *_view)
821 {
822    galahad_sampler_view_destroy(galahad_context(_pipe),
823                                  galahad_sampler_view(_view));
824 }
825 
826 static struct pipe_surface *
galahad_context_create_surface(struct pipe_context * _pipe,struct pipe_resource * _resource,const struct pipe_surface * templ)827 galahad_context_create_surface(struct pipe_context *_pipe,
828                                 struct pipe_resource *_resource,
829                                 const struct pipe_surface *templ)
830 {
831    struct galahad_context *glhd_context = galahad_context(_pipe);
832    struct galahad_resource *glhd_resource = galahad_resource(_resource);
833    struct pipe_context *pipe = glhd_context->pipe;
834    struct pipe_resource *resource = glhd_resource->resource;
835    struct pipe_surface *result;
836 
837    result = pipe->create_surface(pipe,
838                                  resource,
839                                  templ);
840 
841    if (result)
842       return galahad_surface_create(glhd_context, glhd_resource, result);
843    return NULL;
844 }
845 
846 static void
galahad_context_surface_destroy(struct pipe_context * _pipe,struct pipe_surface * _surface)847 galahad_context_surface_destroy(struct pipe_context *_pipe,
848                                 struct pipe_surface *_surface)
849 {
850    galahad_surface_destroy(galahad_context(_pipe),
851                            galahad_surface(_surface));
852 }
853 
854 
855 
856 static struct pipe_transfer *
galahad_context_get_transfer(struct pipe_context * _context,struct pipe_resource * _resource,unsigned level,unsigned usage,const struct pipe_box * box)857 galahad_context_get_transfer(struct pipe_context *_context,
858                               struct pipe_resource *_resource,
859                               unsigned level,
860                               unsigned usage,
861                               const struct pipe_box *box)
862 {
863    struct galahad_context *glhd_context = galahad_context(_context);
864    struct galahad_resource *glhd_resource = galahad_resource(_resource);
865    struct pipe_context *context = glhd_context->pipe;
866    struct pipe_resource *resource = glhd_resource->resource;
867    struct pipe_transfer *result;
868 
869    result = context->get_transfer(context,
870                                   resource,
871                                   level,
872                                   usage,
873                                   box);
874 
875    if (result)
876       return galahad_transfer_create(glhd_context, glhd_resource, result);
877    return NULL;
878 }
879 
880 static void
galahad_context_transfer_destroy(struct pipe_context * _pipe,struct pipe_transfer * _transfer)881 galahad_context_transfer_destroy(struct pipe_context *_pipe,
882                                   struct pipe_transfer *_transfer)
883 {
884    galahad_transfer_destroy(galahad_context(_pipe),
885                              galahad_transfer(_transfer));
886 }
887 
888 static void *
galahad_context_transfer_map(struct pipe_context * _context,struct pipe_transfer * _transfer)889 galahad_context_transfer_map(struct pipe_context *_context,
890                               struct pipe_transfer *_transfer)
891 {
892    struct galahad_context *glhd_context = galahad_context(_context);
893    struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
894    struct pipe_context *context = glhd_context->pipe;
895    struct pipe_transfer *transfer = glhd_transfer->transfer;
896 
897    struct galahad_resource *glhd_resource = galahad_resource(_transfer->resource);
898 
899    glhd_resource->map_count++;
900 
901    return context->transfer_map(context,
902                                 transfer);
903 }
904 
905 
906 
907 static void
galahad_context_transfer_flush_region(struct pipe_context * _context,struct pipe_transfer * _transfer,const struct pipe_box * box)908 galahad_context_transfer_flush_region(struct pipe_context *_context,
909                                        struct pipe_transfer *_transfer,
910                                        const struct pipe_box *box)
911 {
912    struct galahad_context *glhd_context = galahad_context(_context);
913    struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
914    struct pipe_context *context = glhd_context->pipe;
915    struct pipe_transfer *transfer = glhd_transfer->transfer;
916 
917    context->transfer_flush_region(context,
918                                   transfer,
919                                   box);
920 }
921 
922 
923 static void
galahad_context_transfer_unmap(struct pipe_context * _context,struct pipe_transfer * _transfer)924 galahad_context_transfer_unmap(struct pipe_context *_context,
925                                 struct pipe_transfer *_transfer)
926 {
927    struct galahad_context *glhd_context = galahad_context(_context);
928    struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
929    struct pipe_context *context = glhd_context->pipe;
930    struct pipe_transfer *transfer = glhd_transfer->transfer;
931    struct galahad_resource *glhd_resource = galahad_resource(_transfer->resource);
932 
933    if (glhd_resource->map_count < 1) {
934       glhd_warn("context::transfer_unmap() called too many times"
935                 " (count = %d)\n", glhd_resource->map_count);
936    }
937 
938    glhd_resource->map_count--;
939 
940    context->transfer_unmap(context,
941                            transfer);
942 }
943 
944 
945 static void
galahad_context_transfer_inline_write(struct pipe_context * _context,struct pipe_resource * _resource,unsigned level,unsigned usage,const struct pipe_box * box,const void * data,unsigned stride,unsigned slice_stride)946 galahad_context_transfer_inline_write(struct pipe_context *_context,
947                                        struct pipe_resource *_resource,
948                                        unsigned level,
949                                        unsigned usage,
950                                        const struct pipe_box *box,
951                                        const void *data,
952                                        unsigned stride,
953                                        unsigned slice_stride)
954 {
955    struct galahad_context *glhd_context = galahad_context(_context);
956    struct galahad_resource *glhd_resource = galahad_resource(_resource);
957    struct pipe_context *context = glhd_context->pipe;
958    struct pipe_resource *resource = glhd_resource->resource;
959 
960    context->transfer_inline_write(context,
961                                   resource,
962                                   level,
963                                   usage,
964                                   box,
965                                   data,
966                                   stride,
967                                   slice_stride);
968 }
969 
970 
971 static void
galahad_context_render_condition(struct pipe_context * _context,struct pipe_query * query,uint mode)972 galahad_context_render_condition(struct pipe_context *_context,
973                                  struct pipe_query *query,
974                                  uint mode)
975 {
976    struct galahad_context *glhd_context = galahad_context(_context);
977    struct pipe_context *context = glhd_context->pipe;
978 
979    context->render_condition(context, query, mode);
980 }
981 
982 
983 struct pipe_context *
galahad_context_create(struct pipe_screen * _screen,struct pipe_context * pipe)984 galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
985 {
986    struct galahad_context *glhd_pipe;
987    (void)galahad_screen(_screen);
988 
989    glhd_pipe = CALLOC_STRUCT(galahad_context);
990    if (!glhd_pipe) {
991       return NULL;
992    }
993 
994    glhd_pipe->base.screen = _screen;
995    glhd_pipe->base.priv = pipe->priv; /* expose wrapped data */
996    glhd_pipe->base.draw = NULL;
997 
998    glhd_pipe->base.destroy = galahad_context_destroy;
999 
1000 #define GLHD_PIPE_INIT(_member) \
1001    glhd_pipe->base . _member = pipe -> _member ? galahad_context_ ## _member : NULL
1002 
1003    GLHD_PIPE_INIT(draw_vbo);
1004    GLHD_PIPE_INIT(render_condition);
1005    GLHD_PIPE_INIT(create_query);
1006    GLHD_PIPE_INIT(destroy_query);
1007    GLHD_PIPE_INIT(begin_query);
1008    GLHD_PIPE_INIT(end_query);
1009    GLHD_PIPE_INIT(get_query_result);
1010    GLHD_PIPE_INIT(create_blend_state);
1011    GLHD_PIPE_INIT(bind_blend_state);
1012    GLHD_PIPE_INIT(delete_blend_state);
1013    GLHD_PIPE_INIT(create_sampler_state);
1014    GLHD_PIPE_INIT(bind_fragment_sampler_states);
1015    GLHD_PIPE_INIT(bind_vertex_sampler_states);
1016    //GLHD_PIPE_INIT(bind_geometry_sampler_states);
1017    //GLHD_PIPE_INIT(bind_compute_sampler_states);
1018    GLHD_PIPE_INIT(delete_sampler_state);
1019    GLHD_PIPE_INIT(create_rasterizer_state);
1020    GLHD_PIPE_INIT(bind_rasterizer_state);
1021    GLHD_PIPE_INIT(delete_rasterizer_state);
1022    GLHD_PIPE_INIT(create_depth_stencil_alpha_state);
1023    GLHD_PIPE_INIT(bind_depth_stencil_alpha_state);
1024    GLHD_PIPE_INIT(delete_depth_stencil_alpha_state);
1025    GLHD_PIPE_INIT(create_fs_state);
1026    GLHD_PIPE_INIT(bind_fs_state);
1027    GLHD_PIPE_INIT(delete_fs_state);
1028    GLHD_PIPE_INIT(create_vs_state);
1029    GLHD_PIPE_INIT(bind_vs_state);
1030    GLHD_PIPE_INIT(delete_vs_state);
1031    //GLHD_PIPE_INIT(create_gs_state);
1032    //GLHD_PIPE_INIT(bind_gs_state);
1033    //GLHD_PIPE_INIT(delete_gs_state);
1034    GLHD_PIPE_INIT(create_vertex_elements_state);
1035    GLHD_PIPE_INIT(bind_vertex_elements_state);
1036    GLHD_PIPE_INIT(delete_vertex_elements_state);
1037    GLHD_PIPE_INIT(set_blend_color);
1038    GLHD_PIPE_INIT(set_stencil_ref);
1039    GLHD_PIPE_INIT(set_sample_mask);
1040    GLHD_PIPE_INIT(set_clip_state);
1041    GLHD_PIPE_INIT(set_constant_buffer);
1042    GLHD_PIPE_INIT(set_framebuffer_state);
1043    GLHD_PIPE_INIT(set_polygon_stipple);
1044    GLHD_PIPE_INIT(set_scissor_state);
1045    GLHD_PIPE_INIT(set_viewport_state);
1046    GLHD_PIPE_INIT(set_fragment_sampler_views);
1047    GLHD_PIPE_INIT(set_vertex_sampler_views);
1048    //GLHD_PIPE_INIT(set_geometry_sampler_views);
1049    //GLHD_PIPE_INIT(set_compute_sampler_views);
1050    //GLHD_PIPE_INIT(set_shader_resources);
1051    GLHD_PIPE_INIT(set_vertex_buffers);
1052    GLHD_PIPE_INIT(set_index_buffer);
1053    //GLHD_PIPE_INIT(create_stream_output_target);
1054    //GLHD_PIPE_INIT(stream_output_target_destroy);
1055    //GLHD_PIPE_INIT(set_stream_output_targets);
1056    GLHD_PIPE_INIT(resource_copy_region);
1057    //GLHD_PIPE_INIT(resource_resolve);
1058    GLHD_PIPE_INIT(clear);
1059    GLHD_PIPE_INIT(clear_render_target);
1060    GLHD_PIPE_INIT(clear_depth_stencil);
1061    GLHD_PIPE_INIT(flush);
1062    GLHD_PIPE_INIT(create_sampler_view);
1063    GLHD_PIPE_INIT(sampler_view_destroy);
1064    GLHD_PIPE_INIT(create_surface);
1065    GLHD_PIPE_INIT(surface_destroy);
1066    GLHD_PIPE_INIT(get_transfer);
1067    GLHD_PIPE_INIT(transfer_destroy);
1068    GLHD_PIPE_INIT(transfer_map);
1069    GLHD_PIPE_INIT(transfer_flush_region);
1070    GLHD_PIPE_INIT(transfer_unmap);
1071    GLHD_PIPE_INIT(transfer_inline_write);
1072    //GLHD_PIPE_INIT(texture_barrier);
1073    //GLHD_PIPE_INIT(create_video_decoder);
1074    //GLHD_PIPE_INIT(create_video_buffer);
1075    //GLHD_PIPE_INIT(create_compute_state);
1076    //GLHD_PIPE_INIT(bind_compute_state);
1077    //GLHD_PIPE_INIT(delete_compute_state);
1078    //GLHD_PIPE_INIT(set_compute_resources);
1079    //GLHD_PIPE_INIT(set_global_binding);
1080    //GLHD_PIPE_INIT(launch_grid);
1081 
1082 #undef GLHD_PIPE_INIT
1083 
1084    glhd_pipe->pipe = pipe;
1085 
1086    return &glhd_pipe->base;
1087 }
1088