Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / gallium / state_trackers / g3dvl / vl_basic_csc.c
1 #define VL_INTERNAL
2 #include "vl_basic_csc.h"
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <pipe/p_context.h>
6 #include <pipe/p_winsys.h>
7 #include <pipe/p_state.h>
8 #include <pipe/p_inlines.h>
9 #include <tgsi/tgsi_parse.h>
10 #include <tgsi/tgsi_build.h>
11 #include "vl_csc.h"
12 #include "vl_surface.h"
13 #include "vl_shader_build.h"
14 #include "vl_types.h"
15
16 struct vlVertexShaderConsts
17 {
18 struct vlVertex4f dst_scale;
19 struct vlVertex4f dst_trans;
20 struct vlVertex4f src_scale;
21 struct vlVertex4f src_trans;
22 };
23
24 struct vlFragmentShaderConsts
25 {
26 struct vlVertex4f bias;
27 float matrix[16];
28 };
29
30 struct vlBasicCSC
31 {
32 struct vlCSC base;
33
34 struct pipe_context *pipe;
35 struct pipe_viewport_state viewport;
36 struct pipe_framebuffer_state framebuffer;
37 struct pipe_texture *framebuffer_tex;
38 void *sampler;
39 void *vertex_shader, *fragment_shader;
40 struct pipe_vertex_buffer vertex_bufs[2];
41 struct pipe_vertex_element vertex_elems[2];
42 struct pipe_constant_buffer vs_const_buf, fs_const_buf;
43 };
44
45 static int vlResizeFrameBuffer
46 (
47 struct vlCSC *csc,
48 unsigned int width,
49 unsigned int height
50 )
51 {
52 struct vlBasicCSC *basic_csc;
53 struct pipe_context *pipe;
54 struct pipe_texture template;
55
56 assert(csc);
57
58 basic_csc = (struct vlBasicCSC*)csc;
59 pipe = basic_csc->pipe;
60
61 if (basic_csc->framebuffer.width == width && basic_csc->framebuffer.height == height)
62 return 0;
63
64 basic_csc->viewport.scale[0] = width;
65 basic_csc->viewport.scale[1] = height;
66 basic_csc->viewport.scale[2] = 1;
67 basic_csc->viewport.scale[3] = 1;
68 basic_csc->viewport.translate[0] = 0;
69 basic_csc->viewport.translate[1] = 0;
70 basic_csc->viewport.translate[2] = 0;
71 basic_csc->viewport.translate[3] = 0;
72
73 if (basic_csc->framebuffer_tex)
74 pipe_texture_release(&basic_csc->framebuffer_tex);
75
76 memset(&template, 0, sizeof(struct pipe_texture));
77 template.target = PIPE_TEXTURE_2D;
78 template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
79 template.last_level = 0;
80 template.width[0] = width;
81 template.height[0] = height;
82 template.depth[0] = 1;
83 template.compressed = 0;
84 pf_get_block(template.format, &template.block);
85 template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
86
87 basic_csc->framebuffer_tex = pipe->screen->texture_create(pipe->screen, &template);
88
89 basic_csc->framebuffer.width = width;
90 basic_csc->framebuffer.height = height;
91 basic_csc->framebuffer.cbufs[0] = pipe->screen->get_tex_surface
92 (
93 pipe->screen,
94 basic_csc->framebuffer_tex,
95 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE
96 );
97
98 /* Clear to black, in case video doesn't fill the entire window */
99 pipe->clear(pipe, basic_csc->framebuffer.cbufs[0], 0);
100
101 return 0;
102 }
103
104 static int vlBegin
105 (
106 struct vlCSC *csc
107 )
108 {
109 struct vlBasicCSC *basic_csc;
110 struct pipe_context *pipe;
111
112 assert(csc);
113
114 basic_csc = (struct vlBasicCSC*)csc;
115 pipe = basic_csc->pipe;
116
117 pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer);
118 pipe->set_viewport_state(pipe, &basic_csc->viewport);
119 pipe->bind_sampler_states(pipe, 1, (void**)&basic_csc->sampler);
120 /* Source texture set in vlPutPictureCSC() */
121 pipe->bind_vs_state(pipe, basic_csc->vertex_shader);
122 pipe->bind_fs_state(pipe, basic_csc->fragment_shader);
123 pipe->set_vertex_buffers(pipe, 2, basic_csc->vertex_bufs);
124 pipe->set_vertex_elements(pipe, 2, basic_csc->vertex_elems);
125 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &basic_csc->vs_const_buf);
126 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &basic_csc->fs_const_buf);
127
128 return 0;
129 }
130
131 static int vlPutPictureCSC
132 (
133 struct vlCSC *csc,
134 struct vlSurface *surface,
135 int srcx,
136 int srcy,
137 int srcw,
138 int srch,
139 int destx,
140 int desty,
141 int destw,
142 int desth,
143 enum vlPictureType picture_type
144 )
145 {
146 struct vlBasicCSC *basic_csc;
147 struct pipe_context *pipe;
148 struct vlVertexShaderConsts *vs_consts;
149
150 assert(csc);
151 assert(surface);
152
153 basic_csc = (struct vlBasicCSC*)csc;
154 pipe = basic_csc->pipe;
155
156 vs_consts = pipe->winsys->buffer_map
157 (
158 pipe->winsys,
159 basic_csc->vs_const_buf.buffer,
160 PIPE_BUFFER_USAGE_CPU_WRITE
161 );
162
163 vs_consts->dst_scale.x = destw / (float)basic_csc->framebuffer.cbufs[0]->width;
164 vs_consts->dst_scale.y = desth / (float)basic_csc->framebuffer.cbufs[0]->height;
165 vs_consts->dst_scale.z = 1;
166 vs_consts->dst_scale.w = 1;
167 vs_consts->dst_trans.x = destx / (float)basic_csc->framebuffer.cbufs[0]->width;
168 vs_consts->dst_trans.y = desty / (float)basic_csc->framebuffer.cbufs[0]->height;
169 vs_consts->dst_trans.z = 0;
170 vs_consts->dst_trans.w = 0;
171
172 vs_consts->src_scale.x = srcw / (float)surface->texture->width[0];
173 vs_consts->src_scale.y = srch / (float)surface->texture->height[0];
174 vs_consts->src_scale.z = 1;
175 vs_consts->src_scale.w = 1;
176 vs_consts->src_trans.x = srcx / (float)surface->texture->width[0];
177 vs_consts->src_trans.y = srcy / (float)surface->texture->height[0];
178 vs_consts->src_trans.z = 0;
179 vs_consts->src_trans.w = 0;
180
181 pipe->winsys->buffer_unmap(pipe->winsys, basic_csc->vs_const_buf.buffer);
182
183 pipe->set_sampler_textures(pipe, 1, &surface->texture);
184 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
185
186 return 0;
187 }
188
189 static int vlEnd
190 (
191 struct vlCSC *csc
192 )
193 {
194 assert(csc);
195
196 return 0;
197 }
198
199 static struct pipe_surface* vlGetFrameBuffer
200 (
201 struct vlCSC *csc
202 )
203 {
204 struct vlBasicCSC *basic_csc;
205
206 assert(csc);
207
208 basic_csc = (struct vlBasicCSC*)csc;
209
210 return basic_csc->framebuffer.cbufs[0];
211 }
212
213 static int vlDestroy
214 (
215 struct vlCSC *csc
216 )
217 {
218 struct vlBasicCSC *basic_csc;
219 struct pipe_context *pipe;
220 unsigned int i;
221
222 assert(csc);
223
224 basic_csc = (struct vlBasicCSC*)csc;
225 pipe = basic_csc->pipe;
226
227 if (basic_csc->framebuffer_tex)
228 pipe_texture_release(&basic_csc->framebuffer_tex);
229
230 pipe->delete_sampler_state(pipe, basic_csc->sampler);
231 pipe->delete_vs_state(pipe, basic_csc->vertex_shader);
232 pipe->delete_fs_state(pipe, basic_csc->fragment_shader);
233
234 for (i = 0; i < 2; ++i)
235 pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vertex_bufs[i].buffer);
236
237 pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vs_const_buf.buffer);
238 pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->fs_const_buf.buffer);
239
240 free(basic_csc);
241
242 return 0;
243 }
244
245 /*
246 * Represents 2 triangles in a strip in normalized coords.
247 * Used to render the surface onto the frame buffer.
248 */
249 static const struct vlVertex2f surface_verts[4] =
250 {
251 {0.0f, 0.0f},
252 {0.0f, 1.0f},
253 {1.0f, 0.0f},
254 {1.0f, 1.0f}
255 };
256
257 /*
258 * Represents texcoords for the above. We can use the position values directly.
259 * TODO: Duplicate these in the shader, no need to create a buffer.
260 */
261 static const struct vlVertex2f *surface_texcoords = surface_verts;
262
263 /*
264 * Identity color conversion constants, for debugging
265 */
266 static const struct vlFragmentShaderConsts identity =
267 {
268 {
269 0.0f, 0.0f, 0.0f, 0.0f
270 },
271 {
272 1.0f, 0.0f, 0.0f, 0.0f,
273 0.0f, 1.0f, 0.0f, 0.0f,
274 0.0f, 0.0f, 1.0f, 0.0f,
275 0.0f, 0.0f, 0.0f, 1.0f
276 }
277 };
278
279 /*
280 * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
281 * Y is in [16,235], Cb and Cr are in [16,240]
282 * R, G, and B are in [16,235]
283 */
284 static const struct vlFragmentShaderConsts bt_601 =
285 {
286 {
287 0.0f, 0.501960784f, 0.501960784f, 0.0f
288 },
289 {
290 1.0f, 0.0f, 1.371f, 0.0f,
291 1.0f, -0.336f, -0.698f, 0.0f,
292 1.0f, 1.732f, 0.0f, 0.0f,
293 0.0f, 0.0f, 0.0f, 1.0f
294 }
295 };
296
297 /*
298 * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
299 * Y is in [16,235], Cb and Cr are in [16,240]
300 * R, G, and B are in [0,255]
301 */
302 static const struct vlFragmentShaderConsts bt_601_full =
303 {
304 {
305 0.062745098f, 0.501960784f, 0.501960784f, 0.0f
306 },
307 {
308 1.164f, 0.0f, 1.596f, 0.0f,
309 1.164f, -0.391f, -0.813f, 0.0f,
310 1.164f, 2.018f, 0.0f, 0.0f,
311 0.0f, 0.0f, 0.0f, 1.0f
312 }
313 };
314
315 /*
316 * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
317 * Y is in [16,235], Cb and Cr are in [16,240]
318 * R, G, and B are in [16,235]
319 */
320 static const struct vlFragmentShaderConsts bt_709 =
321 {
322 {
323 0.0f, 0.501960784f, 0.501960784f, 0.0f
324 },
325 {
326 1.0f, 0.0f, 1.540f, 0.0f,
327 1.0f, -0.183f, -0.459f, 0.0f,
328 1.0f, 1.816f, 0.0f, 0.0f,
329 0.0f, 0.0f, 0.0f, 1.0f
330 }
331 };
332
333 /*
334 * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
335 * Y is in [16,235], Cb and Cr are in [16,240]
336 * R, G, and B are in [0,255]
337 */
338 const struct vlFragmentShaderConsts bt_709_full =
339 {
340 {
341 0.062745098f, 0.501960784f, 0.501960784f, 0.0f
342 },
343 {
344 1.164f, 0.0f, 1.793f, 0.0f,
345 1.164f, -0.213f, -0.534f, 0.0f,
346 1.164f, 2.115f, 0.0f, 0.0f,
347 0.0f, 0.0f, 0.0f, 1.0f
348 }
349 };
350
351 static int vlCreateVertexShader
352 (
353 struct vlBasicCSC *csc
354 )
355 {
356 const unsigned int max_tokens = 50;
357
358 struct pipe_context *pipe;
359 struct pipe_shader_state vs;
360 struct tgsi_token *tokens;
361 struct tgsi_header *header;
362
363 struct tgsi_full_declaration decl;
364 struct tgsi_full_instruction inst;
365
366 unsigned int ti;
367 unsigned int i;
368
369 assert(context);
370
371 pipe = csc->pipe;
372 tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
373
374 /* Version */
375 *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
376 /* Header */
377 header = (struct tgsi_header*)&tokens[1];
378 *header = tgsi_build_header();
379 /* Processor */
380 *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
381
382 ti = 3;
383
384 /*
385 * decl i0 ; Vertex pos
386 * decl i1 ; Vertex texcoords
387 */
388 for (i = 0; i < 2; i++)
389 {
390 decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
391 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
392 }
393
394 /*
395 * decl c0 ; Scaling vector to scale vertex pos rect to destination size
396 * decl c1 ; Translation vector to move vertex pos rect into position
397 * decl c2 ; Scaling vector to scale texcoord rect to source size
398 * decl c3 ; Translation vector to move texcoord rect into position
399 */
400 decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3);
401 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
402
403 /*
404 * decl o0 ; Vertex pos
405 * decl o1 ; Vertex texcoords
406 */
407 for (i = 0; i < 2; i++)
408 {
409 decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
410 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
411 }
412
413 /* decl t0, t1 */
414 decl = vl_decl_temps(0, 1);
415 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
416
417 /*
418 * madd o0, i0, c0, c1 ; Scale and translate unit output rect to destination size and pos
419 * madd o1, i1, c2, c3 ; Scale and translate unit texcoord rect to source size and pos
420 */
421 for (i = 0; i < 2; ++i)
422 {
423 inst = vl_inst4(TGSI_OPCODE_MADD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1);
424 ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
425 }
426
427 /* end */
428 inst = vl_end();
429 ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
430
431 vs.tokens = tokens;
432 csc->vertex_shader = pipe->create_vs_state(pipe, &vs);
433 free(tokens);
434
435 return 0;
436 }
437
438 static int vlCreateFragmentShader
439 (
440 struct vlBasicCSC *csc
441 )
442 {
443 const unsigned int max_tokens = 50;
444
445 struct pipe_context *pipe;
446 struct pipe_shader_state fs;
447 struct tgsi_token *tokens;
448 struct tgsi_header *header;
449
450 struct tgsi_full_declaration decl;
451 struct tgsi_full_instruction inst;
452
453 unsigned int ti;
454 unsigned int i;
455
456 assert(context);
457
458 pipe = csc->pipe;
459 tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
460
461 /* Version */
462 *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
463 /* Header */
464 header = (struct tgsi_header*)&tokens[1];
465 *header = tgsi_build_header();
466 /* Processor */
467 *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
468
469 ti = 3;
470
471 /* decl i0 ; Texcoords for s0 */
472 decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR);
473 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
474
475 /*
476 * decl c0 ; Bias vector for CSC
477 * decl c1-c4 ; CSC matrix c1-c4
478 */
479 decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4);
480 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
481
482 /* decl o0 ; Fragment color */
483 decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
484 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
485
486 /* decl t0 */
487 decl = vl_decl_temps(0, 0);
488 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
489
490 /* decl s0 ; Sampler for tex containing picture to display */
491 decl = vl_decl_samplers(0, 0);
492 ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
493
494 /* tex2d t0, i0, s0 ; Read src pixel */
495 inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0);
496 ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
497
498 /* sub t0, t0, c0 ; Subtract bias vector from pixel */
499 inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
500 ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
501
502 /*
503 * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix
504 * dp4 o0.y, t0, c2
505 * dp4 o0.z, t0, c3
506 */
507 for (i = 0; i < 3; ++i)
508 {
509 inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1);
510 inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
511 ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
512 }
513
514 /* end */
515 inst = vl_end();
516 ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
517
518 fs.tokens = tokens;
519 csc->fragment_shader = pipe->create_fs_state(pipe, &fs);
520 free(tokens);
521
522 return 0;
523 }
524
525 static int vlCreateDataBufs
526 (
527 struct vlBasicCSC *csc
528 )
529 {
530 struct pipe_context *pipe;
531
532 assert(csc);
533
534 pipe = csc->pipe;
535
536 /*
537 * Create our vertex buffer and vertex buffer element
538 * VB contains 4 vertices that render a quad covering the entire window
539 * to display a rendered surface
540 * Quad is rendered as a tri strip
541 */
542 csc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f);
543 csc->vertex_bufs[0].max_index = 3;
544 csc->vertex_bufs[0].buffer_offset = 0;
545 csc->vertex_bufs[0].buffer = pipe->winsys->buffer_create
546 (
547 pipe->winsys,
548 1,
549 PIPE_BUFFER_USAGE_VERTEX,
550 sizeof(struct vlVertex2f) * 4
551 );
552
553 memcpy
554 (
555 pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
556 surface_verts,
557 sizeof(struct vlVertex2f) * 4
558 );
559
560 pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[0].buffer);
561
562 csc->vertex_elems[0].src_offset = 0;
563 csc->vertex_elems[0].vertex_buffer_index = 0;
564 csc->vertex_elems[0].nr_components = 2;
565 csc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
566
567 /*
568 * Create our texcoord buffer and texcoord buffer element
569 * Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices
570 */
571 csc->vertex_bufs[1].pitch = sizeof(struct vlVertex2f);
572 csc->vertex_bufs[1].max_index = 3;
573 csc->vertex_bufs[1].buffer_offset = 0;
574 csc->vertex_bufs[1].buffer = pipe->winsys->buffer_create
575 (
576 pipe->winsys,
577 1,
578 PIPE_BUFFER_USAGE_VERTEX,
579 sizeof(struct vlVertex2f) * 4
580 );
581
582 memcpy
583 (
584 pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
585 surface_texcoords,
586 sizeof(struct vlVertex2f) * 4
587 );
588
589 pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[1].buffer);
590
591 csc->vertex_elems[1].src_offset = 0;
592 csc->vertex_elems[1].vertex_buffer_index = 1;
593 csc->vertex_elems[1].nr_components = 2;
594 csc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
595
596 /*
597 * Create our vertex shader's constant buffer
598 * Const buffer contains scaling and translation vectors
599 */
600 csc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
601 csc->vs_const_buf.buffer = pipe->winsys->buffer_create
602 (
603 pipe->winsys,
604 1,
605 PIPE_BUFFER_USAGE_CONSTANT,
606 csc->vs_const_buf.size
607 );
608
609 /*
610 * Create our fragment shader's constant buffer
611 * Const buffer contains the color conversion matrix and bias vectors
612 */
613 csc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
614 csc->fs_const_buf.buffer = pipe->winsys->buffer_create
615 (
616 pipe->winsys,
617 1,
618 PIPE_BUFFER_USAGE_CONSTANT,
619 csc->fs_const_buf.size
620 );
621
622 /*
623 * TODO: Refactor this into a seperate function,
624 * allow changing the CSC matrix at runtime to switch between regular & full versions
625 */
626 memcpy
627 (
628 pipe->winsys->buffer_map(pipe->winsys, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
629 &bt_601,
630 sizeof(struct vlFragmentShaderConsts)
631 );
632
633 pipe->winsys->buffer_unmap(pipe->winsys, csc->fs_const_buf.buffer);
634
635 return 0;
636 }
637
638 static int vlInit
639 (
640 struct vlBasicCSC *csc
641 )
642 {
643 struct pipe_context *pipe;
644 struct pipe_sampler_state sampler;
645
646 assert(csc);
647
648 pipe = csc->pipe;
649
650 /* Delay creating the FB until vlPutPictureCSC() so we know window size */
651 csc->framebuffer_tex = NULL;
652 csc->framebuffer.width = 0;
653 csc->framebuffer.height = 0;
654 csc->framebuffer.num_cbufs = 1;
655 csc->framebuffer.cbufs[0] = NULL;
656 csc->framebuffer.zsbuf = NULL;
657
658 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
659 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
660 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
661 sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
662 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
663 sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
664 sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
665 sampler.compare_func = PIPE_FUNC_ALWAYS;
666 sampler.normalized_coords = 1;
667 /*sampler.prefilter = ;*/
668 /*sampler.shadow_ambient = ;*/
669 /*sampler.lod_bias = ;*/
670 /*sampler.min_lod = ;*/
671 /*sampler.max_lod = ;*/
672 /*sampler.border_color[i] = ;*/
673 /*sampler.max_anisotropy = ;*/
674 csc->sampler = pipe->create_sampler_state(pipe, &sampler);
675
676 vlCreateVertexShader(csc);
677 vlCreateFragmentShader(csc);
678 vlCreateDataBufs(csc);
679
680 return 0;
681 }
682
683 int vlCreateBasicCSC
684 (
685 struct pipe_context *pipe,
686 struct vlCSC **csc
687 )
688 {
689 struct vlBasicCSC *basic_csc;
690
691 assert(pipe);
692 assert(csc);
693
694 basic_csc = calloc(1, sizeof(struct vlBasicCSC));
695
696 if (!basic_csc)
697 return 1;
698
699 basic_csc->base.vlResizeFrameBuffer = &vlResizeFrameBuffer;
700 basic_csc->base.vlBegin = &vlBegin;
701 basic_csc->base.vlPutPicture = &vlPutPictureCSC;
702 basic_csc->base.vlEnd = &vlEnd;
703 basic_csc->base.vlGetFrameBuffer = &vlGetFrameBuffer;
704 basic_csc->base.vlDestroy = &vlDestroy;
705 basic_csc->pipe = pipe;
706
707 vlInit(basic_csc);
708
709 *csc = &basic_csc->base;
710
711 return 0;
712 }