glhd_context.c revision f3cc4990a090ee076d8217c83aaf16e036e66686
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
39static void
40galahad_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
50static void
51galahad_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
64static struct pipe_query *
65galahad_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
85static void
86galahad_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
96static void
97galahad_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
107static void
108galahad_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
118static boolean
119galahad_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
133static void *
134galahad_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
151static void
152galahad_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
162static void
163galahad_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
173static void *
174galahad_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
184static void
185galahad_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
212static void
213galahad_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
221static void
222galahad_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
231static void
232galahad_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
242static void *
243galahad_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
263static void
264galahad_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
274static void
275galahad_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
285static void *
286galahad_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
296static void
297galahad_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
307static void
308galahad_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
318static void *
319galahad_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
329static void
330galahad_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
340static void
341galahad_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
351static void *
352galahad_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
362static void
363galahad_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
373static void
374galahad_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
385static void *
386galahad_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
400static void
401galahad_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
411static void
412galahad_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
422static void
423galahad_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
433static void
434galahad_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
444static void
445galahad_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
455static void
456galahad_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
466static void
467galahad_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
501static void
502galahad_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
536static void
537galahad_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
547static void
548galahad_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
558static void
559galahad_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
569static void
570galahad_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
603static void
604galahad_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
612static void
613galahad_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
622static void
623galahad_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
645static void
646galahad_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
678static void
679galahad_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
724static void
725galahad_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
741static void
742galahad_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}
761static void
762galahad_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
787static void
788galahad_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
798static struct pipe_sampler_view *
799galahad_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
818static void
819galahad_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
826static struct pipe_surface *
827galahad_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
846static void
847galahad_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
856static struct pipe_transfer *
857galahad_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
880static void
881galahad_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
888static void *
889galahad_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
907static void
908galahad_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
923static void
924galahad_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
945static void
946galahad_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
971static void
972galahad_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
983struct pipe_context *
984galahad_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