Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / galahad / glhd_context.c
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
40 galahad_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
51 galahad_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 *
65 galahad_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
86 galahad_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
97 galahad_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
108 galahad_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
119 galahad_get_query_result(struct pipe_context *_pipe,
120                           struct pipe_query *query,
121                           boolean wait,
122                           void *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 *
134 galahad_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
152 galahad_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
163 galahad_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 *
174 galahad_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
185 galahad_bind_fragment_sampler_states(struct pipe_context *_pipe,
186                                       unsigned num_samplers,
187                                       void **samplers)
188 {
189    struct galahad_context *glhd_pipe = galahad_context(_pipe);
190    struct pipe_context *pipe = glhd_pipe->pipe;
191
192    if (num_samplers > PIPE_MAX_SAMPLERS) {
193       glhd_error("%u fragment samplers requested, "
194          "but only %u are permitted by API",
195          num_samplers, PIPE_MAX_SAMPLERS);
196    }
197
198    pipe->bind_fragment_sampler_states(pipe,
199                                       num_samplers,
200                                       samplers);
201 }
202
203 static void
204 galahad_bind_vertex_sampler_states(struct pipe_context *_pipe,
205                                     unsigned num_samplers,
206                                     void **samplers)
207 {
208    struct galahad_context *glhd_pipe = galahad_context(_pipe);
209    struct pipe_context *pipe = glhd_pipe->pipe;
210
211    if (num_samplers > PIPE_MAX_VERTEX_SAMPLERS) {
212       glhd_error("%u vertex samplers requested, "
213          "but only %u are permitted by API",
214          num_samplers, PIPE_MAX_VERTEX_SAMPLERS);
215    }
216
217    pipe->bind_vertex_sampler_states(pipe,
218                                     num_samplers,
219                                     samplers);
220 }
221
222 static void
223 galahad_delete_sampler_state(struct pipe_context *_pipe,
224                               void *sampler)
225 {
226    struct galahad_context *glhd_pipe = galahad_context(_pipe);
227    struct pipe_context *pipe = glhd_pipe->pipe;
228
229    pipe->delete_sampler_state(pipe,
230                               sampler);
231 }
232
233 static void *
234 galahad_create_rasterizer_state(struct pipe_context *_pipe,
235                                  const struct pipe_rasterizer_state *rasterizer)
236 {
237    struct galahad_context *glhd_pipe = galahad_context(_pipe);
238    struct pipe_context *pipe = glhd_pipe->pipe;
239
240    if (rasterizer->point_quad_rasterization) {
241        if (rasterizer->point_smooth) {
242            glhd_warn("Point smoothing requested but ignored");
243        }
244    } else {
245        if (rasterizer->sprite_coord_enable) {
246            glhd_warn("Point sprites requested but ignored");
247        }
248    }
249
250    return pipe->create_rasterizer_state(pipe,
251                                         rasterizer);
252 }
253
254 static void
255 galahad_bind_rasterizer_state(struct pipe_context *_pipe,
256                                void *rasterizer)
257 {
258    struct galahad_context *glhd_pipe = galahad_context(_pipe);
259    struct pipe_context *pipe = glhd_pipe->pipe;
260
261    pipe->bind_rasterizer_state(pipe,
262                                rasterizer);
263 }
264
265 static void
266 galahad_delete_rasterizer_state(struct pipe_context *_pipe,
267                                  void *rasterizer)
268 {
269    struct galahad_context *glhd_pipe = galahad_context(_pipe);
270    struct pipe_context *pipe = glhd_pipe->pipe;
271
272    pipe->delete_rasterizer_state(pipe,
273                                  rasterizer);
274 }
275
276 static void *
277 galahad_create_depth_stencil_alpha_state(struct pipe_context *_pipe,
278                                           const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
279 {
280    struct galahad_context *glhd_pipe = galahad_context(_pipe);
281    struct pipe_context *pipe = glhd_pipe->pipe;
282
283    return pipe->create_depth_stencil_alpha_state(pipe,
284                                                  depth_stencil_alpha);
285 }
286
287 static void
288 galahad_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,
289                                         void *depth_stencil_alpha)
290 {
291    struct galahad_context *glhd_pipe = galahad_context(_pipe);
292    struct pipe_context *pipe = glhd_pipe->pipe;
293
294    pipe->bind_depth_stencil_alpha_state(pipe,
295                                         depth_stencil_alpha);
296 }
297
298 static void
299 galahad_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
300                                           void *depth_stencil_alpha)
301 {
302    struct galahad_context *glhd_pipe = galahad_context(_pipe);
303    struct pipe_context *pipe = glhd_pipe->pipe;
304
305    pipe->delete_depth_stencil_alpha_state(pipe,
306                                           depth_stencil_alpha);
307 }
308
309 static void *
310 galahad_create_fs_state(struct pipe_context *_pipe,
311                          const struct pipe_shader_state *fs)
312 {
313    struct galahad_context *glhd_pipe = galahad_context(_pipe);
314    struct pipe_context *pipe = glhd_pipe->pipe;
315
316    return pipe->create_fs_state(pipe,
317                                 fs);
318 }
319
320 static void
321 galahad_bind_fs_state(struct pipe_context *_pipe,
322                        void *fs)
323 {
324    struct galahad_context *glhd_pipe = galahad_context(_pipe);
325    struct pipe_context *pipe = glhd_pipe->pipe;
326
327    pipe->bind_fs_state(pipe,
328                        fs);
329 }
330
331 static void
332 galahad_delete_fs_state(struct pipe_context *_pipe,
333                          void *fs)
334 {
335    struct galahad_context *glhd_pipe = galahad_context(_pipe);
336    struct pipe_context *pipe = glhd_pipe->pipe;
337
338    pipe->delete_fs_state(pipe,
339                          fs);
340 }
341
342 static void *
343 galahad_create_vs_state(struct pipe_context *_pipe,
344                          const struct pipe_shader_state *vs)
345 {
346    struct galahad_context *glhd_pipe = galahad_context(_pipe);
347    struct pipe_context *pipe = glhd_pipe->pipe;
348
349    return pipe->create_vs_state(pipe,
350                                 vs);
351 }
352
353 static void
354 galahad_bind_vs_state(struct pipe_context *_pipe,
355                        void *vs)
356 {
357    struct galahad_context *glhd_pipe = galahad_context(_pipe);
358    struct pipe_context *pipe = glhd_pipe->pipe;
359
360    pipe->bind_vs_state(pipe,
361                        vs);
362 }
363
364 static void
365 galahad_delete_vs_state(struct pipe_context *_pipe,
366                          void *vs)
367 {
368    struct galahad_context *glhd_pipe = galahad_context(_pipe);
369    struct pipe_context *pipe = glhd_pipe->pipe;
370
371    pipe->delete_vs_state(pipe,
372                          vs);
373 }
374
375
376 static void *
377 galahad_create_vertex_elements_state(struct pipe_context *_pipe,
378                                       unsigned num_elements,
379                                       const struct pipe_vertex_element *vertex_elements)
380 {
381    struct galahad_context *glhd_pipe = galahad_context(_pipe);
382    struct pipe_context *pipe = glhd_pipe->pipe;
383
384    /* XXX check if stride lines up with element size, at least for floats */
385
386    return pipe->create_vertex_elements_state(pipe,
387                                              num_elements,
388                                              vertex_elements);
389 }
390
391 static void
392 galahad_bind_vertex_elements_state(struct pipe_context *_pipe,
393                                     void *velems)
394 {
395    struct galahad_context *glhd_pipe = galahad_context(_pipe);
396    struct pipe_context *pipe = glhd_pipe->pipe;
397
398    pipe->bind_vertex_elements_state(pipe,
399                                     velems);
400 }
401
402 static void
403 galahad_delete_vertex_elements_state(struct pipe_context *_pipe,
404                                       void *velems)
405 {
406    struct galahad_context *glhd_pipe = galahad_context(_pipe);
407    struct pipe_context *pipe = glhd_pipe->pipe;
408
409    pipe->delete_vertex_elements_state(pipe,
410                                       velems);
411 }
412
413 static void
414 galahad_set_blend_color(struct pipe_context *_pipe,
415                          const struct pipe_blend_color *blend_color)
416 {
417    struct galahad_context *glhd_pipe = galahad_context(_pipe);
418    struct pipe_context *pipe = glhd_pipe->pipe;
419
420    pipe->set_blend_color(pipe,
421                          blend_color);
422 }
423
424 static void
425 galahad_set_stencil_ref(struct pipe_context *_pipe,
426                          const struct pipe_stencil_ref *stencil_ref)
427 {
428    struct galahad_context *glhd_pipe = galahad_context(_pipe);
429    struct pipe_context *pipe = glhd_pipe->pipe;
430
431    pipe->set_stencil_ref(pipe,
432                          stencil_ref);
433 }
434
435 static void
436 galahad_set_clip_state(struct pipe_context *_pipe,
437                         const struct pipe_clip_state *clip)
438 {
439    struct galahad_context *glhd_pipe = galahad_context(_pipe);
440    struct pipe_context *pipe = glhd_pipe->pipe;
441
442    pipe->set_clip_state(pipe,
443                         clip);
444 }
445
446 static void
447 galahad_set_sample_mask(struct pipe_context *_pipe,
448                          unsigned sample_mask)
449 {
450    struct galahad_context *glhd_pipe = galahad_context(_pipe);
451    struct pipe_context *pipe = glhd_pipe->pipe;
452
453    pipe->set_sample_mask(pipe,
454                          sample_mask);
455 }
456
457 static void
458 galahad_set_constant_buffer(struct pipe_context *_pipe,
459                              uint shader,
460                              uint index,
461                              struct pipe_resource *_resource)
462 {
463    struct galahad_context *glhd_pipe = galahad_context(_pipe);
464    struct pipe_context *pipe = glhd_pipe->pipe;
465    struct pipe_resource *unwrapped_resource;
466    struct pipe_resource *resource = NULL;
467
468    if (shader >= PIPE_SHADER_TYPES) {
469       glhd_error("Unknown shader type %u", shader);
470    }
471
472    if (index &&
473       index >=
474          pipe->screen->get_shader_param(pipe->screen, shader, PIPE_SHADER_CAP_MAX_CONST_BUFFERS)) {
475       glhd_error("Access to constant buffer %u requested, "
476          "but only %d are supported",
477          index,
478          pipe->screen->get_shader_param(pipe->screen, shader, PIPE_SHADER_CAP_MAX_CONST_BUFFERS));
479    }
480
481    /* XXX hmm? unwrap the input state */
482    if (_resource) {
483       unwrapped_resource = galahad_resource_unwrap(_resource);
484       resource = unwrapped_resource;
485    }
486
487    pipe->set_constant_buffer(pipe,
488                              shader,
489                              index,
490                              resource);
491 }
492
493 static void
494 galahad_set_framebuffer_state(struct pipe_context *_pipe,
495                                const struct pipe_framebuffer_state *_state)
496 {
497    struct galahad_context *glhd_pipe = galahad_context(_pipe);
498    struct pipe_context *pipe = glhd_pipe->pipe;
499    struct pipe_framebuffer_state unwrapped_state;
500    struct pipe_framebuffer_state *state = NULL;
501    unsigned i;
502
503    if (_state->nr_cbufs > PIPE_MAX_COLOR_BUFS) {
504       glhd_error("%d render targets bound, but only %d are permitted by API",
505          _state->nr_cbufs, PIPE_MAX_COLOR_BUFS);
506    } else if (_state->nr_cbufs >
507       pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS)) {
508       glhd_warn("%d render targets bound, but only %d are supported",
509          _state->nr_cbufs,
510          pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS));
511    }
512
513    /* unwrap the input state */
514    if (_state) {
515       memcpy(&unwrapped_state, _state, sizeof(unwrapped_state));
516       for(i = 0; i < _state->nr_cbufs; i++)
517          unwrapped_state.cbufs[i] = galahad_surface_unwrap(_state->cbufs[i]);
518       for (; i < PIPE_MAX_COLOR_BUFS; i++)
519          unwrapped_state.cbufs[i] = NULL;
520       unwrapped_state.zsbuf = galahad_surface_unwrap(_state->zsbuf);
521       state = &unwrapped_state;
522    }
523
524    pipe->set_framebuffer_state(pipe,
525                                state);
526 }
527
528 static void
529 galahad_set_polygon_stipple(struct pipe_context *_pipe,
530                              const struct pipe_poly_stipple *poly_stipple)
531 {
532    struct galahad_context *glhd_pipe = galahad_context(_pipe);
533    struct pipe_context *pipe = glhd_pipe->pipe;
534
535    pipe->set_polygon_stipple(pipe,
536                              poly_stipple);
537 }
538
539 static void
540 galahad_set_scissor_state(struct pipe_context *_pipe,
541                            const struct pipe_scissor_state *scissor)
542 {
543    struct galahad_context *glhd_pipe = galahad_context(_pipe);
544    struct pipe_context *pipe = glhd_pipe->pipe;
545
546    pipe->set_scissor_state(pipe,
547                            scissor);
548 }
549
550 static void
551 galahad_set_viewport_state(struct pipe_context *_pipe,
552                             const struct pipe_viewport_state *viewport)
553 {
554    struct galahad_context *glhd_pipe = galahad_context(_pipe);
555    struct pipe_context *pipe = glhd_pipe->pipe;
556
557    pipe->set_viewport_state(pipe,
558                             viewport);
559 }
560
561 static void
562 galahad_set_fragment_sampler_views(struct pipe_context *_pipe,
563                                     unsigned num,
564                                     struct pipe_sampler_view **_views)
565 {
566    struct galahad_context *glhd_pipe = galahad_context(_pipe);
567    struct pipe_context *pipe = glhd_pipe->pipe;
568    struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
569    struct pipe_sampler_view **views = NULL;
570    unsigned i;
571
572    if (_views) {
573       for (i = 0; i < num; i++)
574          unwrapped_views[i] = galahad_sampler_view_unwrap(_views[i]);
575       for (; i < PIPE_MAX_SAMPLERS; i++)
576          unwrapped_views[i] = NULL;
577
578       views = unwrapped_views;
579    }
580
581    pipe->set_fragment_sampler_views(pipe, num, views);
582 }
583
584 static void
585 galahad_set_vertex_sampler_views(struct pipe_context *_pipe,
586                                   unsigned num,
587                                   struct pipe_sampler_view **_views)
588 {
589    struct galahad_context *glhd_pipe = galahad_context(_pipe);
590    struct pipe_context *pipe = glhd_pipe->pipe;
591    struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
592    struct pipe_sampler_view **views = NULL;
593    unsigned i;
594
595    if (_views) {
596       for (i = 0; i < num; i++)
597          unwrapped_views[i] = galahad_sampler_view_unwrap(_views[i]);
598       for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
599          unwrapped_views[i] = NULL;
600
601       views = unwrapped_views;
602    }
603
604    pipe->set_vertex_sampler_views(pipe, num, views);
605 }
606
607 static void
608 galahad_set_vertex_buffers(struct pipe_context *_pipe,
609                             unsigned num_buffers,
610                             const struct pipe_vertex_buffer *_buffers)
611 {
612    struct galahad_context *glhd_pipe = galahad_context(_pipe);
613    struct pipe_context *pipe = glhd_pipe->pipe;
614    struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS];
615    struct pipe_vertex_buffer *buffers = NULL;
616    unsigned i;
617
618    if (num_buffers) {
619       memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers));
620       for (i = 0; i < num_buffers; i++)
621          unwrapped_buffers[i].buffer = galahad_resource_unwrap(_buffers[i].buffer);
622       buffers = unwrapped_buffers;
623    }
624
625    pipe->set_vertex_buffers(pipe,
626                             num_buffers,
627                             buffers);
628 }
629
630 static void
631 galahad_set_index_buffer(struct pipe_context *_pipe,
632                          const struct pipe_index_buffer *_ib)
633 {
634    struct galahad_context *glhd_pipe = galahad_context(_pipe);
635    struct pipe_context *pipe = glhd_pipe->pipe;
636    struct pipe_index_buffer unwrapped_ib, *ib = NULL;
637
638    if (_ib->buffer) {
639       switch (_ib->index_size) {
640       case 1:
641       case 2:
642       case 4:
643          break;
644       default:
645          glhd_warn("index buffer %p has unrecognized index size %d",
646                    (void *) _ib->buffer, _ib->index_size);
647          break;
648       }
649    }
650    else if (_ib->offset || _ib->index_size) {
651       glhd_warn("non-indexed state with index offset %d and index size %d",
652             _ib->offset, _ib->index_size);
653    }
654
655    if (_ib) {
656       unwrapped_ib = *_ib;
657       unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer);
658       ib = &unwrapped_ib;
659    }
660
661    pipe->set_index_buffer(pipe, ib);
662 }
663
664 static void
665 galahad_resource_copy_region(struct pipe_context *_pipe,
666                               struct pipe_resource *_dst,
667                               unsigned dst_level,
668                               unsigned dstx,
669                               unsigned dsty,
670                               unsigned dstz,
671                               struct pipe_resource *_src,
672                               unsigned src_level,
673                               const struct pipe_box *src_box)
674 {
675    struct galahad_context *glhd_pipe = galahad_context(_pipe);
676    struct galahad_resource *glhd_resource_dst = galahad_resource(_dst);
677    struct galahad_resource *glhd_resource_src = galahad_resource(_src);
678    struct pipe_context *pipe = glhd_pipe->pipe;
679    struct pipe_resource *dst = glhd_resource_dst->resource;
680    struct pipe_resource *src = glhd_resource_src->resource;
681
682    if (_dst->format != _src->format) {
683       glhd_warn("Format mismatch: Source is %s, destination is %s",
684          util_format_short_name(_src->format),
685          util_format_short_name(_dst->format));
686    }
687
688    if ((_src->target == PIPE_BUFFER && _dst->target != PIPE_BUFFER) ||
689        (_src->target != PIPE_BUFFER && _dst->target == PIPE_BUFFER)) {
690       glhd_warn("Resource target mismatch: Source is %i, destination is %i",
691                 _src->target, _dst->target);
692    }
693
694    pipe->resource_copy_region(pipe,
695                               dst,
696                               dst_level,
697                               dstx,
698                               dsty,
699                               dstz,
700                               src,
701                               src_level,
702                               src_box);
703 }
704
705 static void
706 galahad_clear(struct pipe_context *_pipe,
707                unsigned buffers,
708                const float *rgba,
709                double depth,
710                unsigned stencil)
711 {
712    struct galahad_context *glhd_pipe = galahad_context(_pipe);
713    struct pipe_context *pipe = glhd_pipe->pipe;
714
715    pipe->clear(pipe,
716                buffers,
717                rgba,
718                depth,
719                stencil);
720 }
721
722 static void
723 galahad_clear_render_target(struct pipe_context *_pipe,
724                              struct pipe_surface *_dst,
725                              const float *rgba,
726                              unsigned dstx, unsigned dsty,
727                              unsigned width, unsigned height)
728 {
729    struct galahad_context *glhd_pipe = galahad_context(_pipe);
730    struct galahad_surface *glhd_surface_dst = galahad_surface(_dst);
731    struct pipe_context *pipe = glhd_pipe->pipe;
732    struct pipe_surface *dst = glhd_surface_dst->surface;
733
734    pipe->clear_render_target(pipe,
735                              dst,
736                              rgba,
737                              dstx,
738                              dsty,
739                              width,
740                              height);
741 }
742 static void
743 galahad_clear_depth_stencil(struct pipe_context *_pipe,
744                              struct pipe_surface *_dst,
745                              unsigned clear_flags,
746                              double depth,
747                              unsigned stencil,
748                              unsigned dstx, unsigned dsty,
749                              unsigned width, unsigned height)
750 {
751    struct galahad_context *glhd_pipe = galahad_context(_pipe);
752    struct galahad_surface *glhd_surface_dst = galahad_surface(_dst);
753    struct pipe_context *pipe = glhd_pipe->pipe;
754    struct pipe_surface *dst = glhd_surface_dst->surface;
755
756    pipe->clear_depth_stencil(pipe,
757                              dst,
758                              clear_flags,
759                              depth,
760                              stencil,
761                              dstx,
762                              dsty,
763                              width,
764                              height);
765
766 }
767
768 static void
769 galahad_flush(struct pipe_context *_pipe,
770                struct pipe_fence_handle **fence)
771 {
772    struct galahad_context *glhd_pipe = galahad_context(_pipe);
773    struct pipe_context *pipe = glhd_pipe->pipe;
774
775    pipe->flush(pipe,
776                fence);
777 }
778
779 static struct pipe_sampler_view *
780 galahad_context_create_sampler_view(struct pipe_context *_pipe,
781                                      struct pipe_resource *_resource,
782                                      const struct pipe_sampler_view *templ)
783 {
784    struct galahad_context *glhd_context = galahad_context(_pipe);
785    struct galahad_resource *glhd_resource = galahad_resource(_resource);
786    struct pipe_context *pipe = glhd_context->pipe;
787    struct pipe_resource *resource = glhd_resource->resource;
788    struct pipe_sampler_view *result;
789
790    result = pipe->create_sampler_view(pipe,
791                                       resource,
792                                       templ);
793
794    if (result)
795       return galahad_sampler_view_create(glhd_context, glhd_resource, result);
796    return NULL;
797 }
798
799 static void
800 galahad_context_sampler_view_destroy(struct pipe_context *_pipe,
801                                       struct pipe_sampler_view *_view)
802 {
803    galahad_sampler_view_destroy(galahad_context(_pipe),
804                                  galahad_sampler_view(_view));
805 }
806
807 static struct pipe_surface *
808 galahad_context_create_surface(struct pipe_context *_pipe,
809                                 struct pipe_resource *_resource,
810                                 const struct pipe_surface *templ)
811 {
812    struct galahad_context *glhd_context = galahad_context(_pipe);
813    struct galahad_resource *glhd_resource = galahad_resource(_resource);
814    struct pipe_context *pipe = glhd_context->pipe;
815    struct pipe_resource *resource = glhd_resource->resource;
816    struct pipe_surface *result;
817
818    result = pipe->create_surface(pipe,
819                                  resource,
820                                  templ);
821
822    if (result)
823       return galahad_surface_create(glhd_context, glhd_resource, result);
824    return NULL;
825 }
826
827 static void
828 galahad_context_surface_destroy(struct pipe_context *_pipe,
829                                 struct pipe_surface *_surface)
830 {
831    galahad_surface_destroy(galahad_context(_pipe),
832                            galahad_surface(_surface));
833 }
834
835
836
837 static struct pipe_transfer *
838 galahad_context_get_transfer(struct pipe_context *_context,
839                               struct pipe_resource *_resource,
840                               unsigned level,
841                               unsigned usage,
842                               const struct pipe_box *box)
843 {
844    struct galahad_context *glhd_context = galahad_context(_context);
845    struct galahad_resource *glhd_resource = galahad_resource(_resource);
846    struct pipe_context *context = glhd_context->pipe;
847    struct pipe_resource *resource = glhd_resource->resource;
848    struct pipe_transfer *result;
849
850    result = context->get_transfer(context,
851                                   resource,
852                                   level,
853                                   usage,
854                                   box);
855
856    if (result)
857       return galahad_transfer_create(glhd_context, glhd_resource, result);
858    return NULL;
859 }
860
861 static void
862 galahad_context_transfer_destroy(struct pipe_context *_pipe,
863                                   struct pipe_transfer *_transfer)
864 {
865    galahad_transfer_destroy(galahad_context(_pipe),
866                              galahad_transfer(_transfer));
867 }
868
869 static void *
870 galahad_context_transfer_map(struct pipe_context *_context,
871                               struct pipe_transfer *_transfer)
872 {
873    struct galahad_context *glhd_context = galahad_context(_context);
874    struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
875    struct pipe_context *context = glhd_context->pipe;
876    struct pipe_transfer *transfer = glhd_transfer->transfer;
877
878    struct galahad_resource *glhd_resource = galahad_resource(_transfer->resource);
879
880    glhd_resource->map_count++;
881
882    return context->transfer_map(context,
883                                 transfer);
884 }
885
886
887
888 static void
889 galahad_context_transfer_flush_region(struct pipe_context *_context,
890                                        struct pipe_transfer *_transfer,
891                                        const struct pipe_box *box)
892 {
893    struct galahad_context *glhd_context = galahad_context(_context);
894    struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
895    struct pipe_context *context = glhd_context->pipe;
896    struct pipe_transfer *transfer = glhd_transfer->transfer;
897
898    context->transfer_flush_region(context,
899                                   transfer,
900                                   box);
901 }
902
903
904 static void
905 galahad_context_transfer_unmap(struct pipe_context *_context,
906                                 struct pipe_transfer *_transfer)
907 {
908    struct galahad_context *glhd_context = galahad_context(_context);
909    struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
910    struct pipe_context *context = glhd_context->pipe;
911    struct pipe_transfer *transfer = glhd_transfer->transfer;
912    struct galahad_resource *glhd_resource = galahad_resource(_transfer->resource);
913
914    if (glhd_resource->map_count < 1) {
915       glhd_warn("context::transfer_unmap() called too many times"
916                 " (count = %d)\n", glhd_resource->map_count);      
917    }
918
919    glhd_resource->map_count--;
920
921    context->transfer_unmap(context,
922                            transfer);
923 }
924
925
926 static void
927 galahad_context_transfer_inline_write(struct pipe_context *_context,
928                                        struct pipe_resource *_resource,
929                                        unsigned level,
930                                        unsigned usage,
931                                        const struct pipe_box *box,
932                                        const void *data,
933                                        unsigned stride,
934                                        unsigned slice_stride)
935 {
936    struct galahad_context *glhd_context = galahad_context(_context);
937    struct galahad_resource *glhd_resource = galahad_resource(_resource);
938    struct pipe_context *context = glhd_context->pipe;
939    struct pipe_resource *resource = glhd_resource->resource;
940
941    context->transfer_inline_write(context,
942                                   resource,
943                                   level,
944                                   usage,
945                                   box,
946                                   data,
947                                   stride,
948                                   slice_stride);
949 }
950
951
952 static void galahad_redefine_user_buffer(struct pipe_context *_context,
953                                          struct pipe_resource *_resource,
954                                          unsigned offset, unsigned size)
955 {
956    struct galahad_context *glhd_context = galahad_context(_context);
957    struct galahad_resource *glhd_resource = galahad_resource(_resource);
958    struct pipe_context *context = glhd_context->pipe;
959    struct pipe_resource *resource = glhd_resource->resource;
960
961    context->redefine_user_buffer(context, resource, offset, size);
962 }
963
964
965 struct pipe_context *
966 galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
967 {
968    struct galahad_context *glhd_pipe;
969    (void)galahad_screen(_screen);
970
971    glhd_pipe = CALLOC_STRUCT(galahad_context);
972    if (!glhd_pipe) {
973       return NULL;
974    }
975
976    glhd_pipe->base.winsys = NULL;
977    glhd_pipe->base.screen = _screen;
978    glhd_pipe->base.priv = pipe->priv; /* expose wrapped data */
979    glhd_pipe->base.draw = NULL;
980
981    glhd_pipe->base.destroy = galahad_destroy;
982    glhd_pipe->base.draw_vbo = galahad_draw_vbo;
983    glhd_pipe->base.create_query = galahad_create_query;
984    glhd_pipe->base.destroy_query = galahad_destroy_query;
985    glhd_pipe->base.begin_query = galahad_begin_query;
986    glhd_pipe->base.end_query = galahad_end_query;
987    glhd_pipe->base.get_query_result = galahad_get_query_result;
988    glhd_pipe->base.create_blend_state = galahad_create_blend_state;
989    glhd_pipe->base.bind_blend_state = galahad_bind_blend_state;
990    glhd_pipe->base.delete_blend_state = galahad_delete_blend_state;
991    glhd_pipe->base.create_sampler_state = galahad_create_sampler_state;
992    glhd_pipe->base.bind_fragment_sampler_states = galahad_bind_fragment_sampler_states;
993    glhd_pipe->base.bind_vertex_sampler_states = galahad_bind_vertex_sampler_states;
994    glhd_pipe->base.delete_sampler_state = galahad_delete_sampler_state;
995    glhd_pipe->base.create_rasterizer_state = galahad_create_rasterizer_state;
996    glhd_pipe->base.bind_rasterizer_state = galahad_bind_rasterizer_state;
997    glhd_pipe->base.delete_rasterizer_state = galahad_delete_rasterizer_state;
998    glhd_pipe->base.create_depth_stencil_alpha_state = galahad_create_depth_stencil_alpha_state;
999    glhd_pipe->base.bind_depth_stencil_alpha_state = galahad_bind_depth_stencil_alpha_state;
1000    glhd_pipe->base.delete_depth_stencil_alpha_state = galahad_delete_depth_stencil_alpha_state;
1001    glhd_pipe->base.create_fs_state = galahad_create_fs_state;
1002    glhd_pipe->base.bind_fs_state = galahad_bind_fs_state;
1003    glhd_pipe->base.delete_fs_state = galahad_delete_fs_state;
1004    glhd_pipe->base.create_vs_state = galahad_create_vs_state;
1005    glhd_pipe->base.bind_vs_state = galahad_bind_vs_state;
1006    glhd_pipe->base.delete_vs_state = galahad_delete_vs_state;
1007    glhd_pipe->base.create_vertex_elements_state = galahad_create_vertex_elements_state;
1008    glhd_pipe->base.bind_vertex_elements_state = galahad_bind_vertex_elements_state;
1009    glhd_pipe->base.delete_vertex_elements_state = galahad_delete_vertex_elements_state;
1010    glhd_pipe->base.set_blend_color = galahad_set_blend_color;
1011    glhd_pipe->base.set_stencil_ref = galahad_set_stencil_ref;
1012    glhd_pipe->base.set_clip_state = galahad_set_clip_state;
1013    glhd_pipe->base.set_sample_mask = galahad_set_sample_mask;
1014    glhd_pipe->base.set_constant_buffer = galahad_set_constant_buffer;
1015    glhd_pipe->base.set_framebuffer_state = galahad_set_framebuffer_state;
1016    glhd_pipe->base.set_polygon_stipple = galahad_set_polygon_stipple;
1017    glhd_pipe->base.set_scissor_state = galahad_set_scissor_state;
1018    glhd_pipe->base.set_viewport_state = galahad_set_viewport_state;
1019    glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views;
1020    glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views;
1021    glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers;
1022    glhd_pipe->base.set_index_buffer = galahad_set_index_buffer;
1023    glhd_pipe->base.resource_copy_region = galahad_resource_copy_region;
1024    glhd_pipe->base.clear = galahad_clear;
1025    glhd_pipe->base.clear_render_target = galahad_clear_render_target;
1026    glhd_pipe->base.clear_depth_stencil = galahad_clear_depth_stencil;
1027    glhd_pipe->base.flush = galahad_flush;
1028    glhd_pipe->base.create_sampler_view = galahad_context_create_sampler_view;
1029    glhd_pipe->base.sampler_view_destroy = galahad_context_sampler_view_destroy;
1030    glhd_pipe->base.create_surface = galahad_context_create_surface;
1031    glhd_pipe->base.surface_destroy = galahad_context_surface_destroy;
1032    glhd_pipe->base.get_transfer = galahad_context_get_transfer;
1033    glhd_pipe->base.transfer_destroy = galahad_context_transfer_destroy;
1034    glhd_pipe->base.transfer_map = galahad_context_transfer_map;
1035    glhd_pipe->base.transfer_unmap = galahad_context_transfer_unmap;
1036    glhd_pipe->base.transfer_flush_region = galahad_context_transfer_flush_region;
1037    glhd_pipe->base.transfer_inline_write = galahad_context_transfer_inline_write;
1038    glhd_pipe->base.redefine_user_buffer = galahad_redefine_user_buffer;
1039
1040    glhd_pipe->pipe = pipe;
1041
1042    glhd_warn("Created context %p", (void *) glhd_pipe);
1043
1044    return &glhd_pipe->base;
1045 }