ReactOS 0.4.15-dev-7788-g1ad9096
glsl_shader.c
Go to the documentation of this file.
1/*
2 * GLSL pixel and vertex shader implementation
3 *
4 * Copyright 2006 Jason Green
5 * Copyright 2006-2007 Henri Verbeet
6 * Copyright 2007-2009, 2013 Stefan Dösinger for CodeWeavers
7 * Copyright 2009-2011 Henri Verbeet for CodeWeavers
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24/*
25 * D3D shader asm has swizzles on source parameters, and write masks for
26 * destination parameters. GLSL uses swizzles for both. The result of this is
27 * that for example "mov dst.xw, src.zyxw" becomes "dst.xw = src.zw" in GLSL.
28 * Ie, to generate a proper GLSL source swizzle, we need to take the D3D write
29 * mask for the destination parameter into account.
30 */
31
32#include "config.h"
33#include "wine/port.h"
34
35#include <limits.h>
36#include <stdio.h>
37#ifdef HAVE_FLOAT_H
38# include <float.h>
39#endif
40
41#include "wined3d_private.h"
42
46
47#define WINED3D_GLSL_SAMPLE_PROJECTED 0x01
48#define WINED3D_GLSL_SAMPLE_LOD 0x02
49#define WINED3D_GLSL_SAMPLE_GRAD 0x04
50#define WINED3D_GLSL_SAMPLE_LOAD 0x08
51#define WINED3D_GLSL_SAMPLE_OFFSET 0x10
52
53static const struct
54{
55 unsigned int coord_size;
56 unsigned int resinfo_size;
57 const char *type_part;
58}
60{
61 {0, 0, ""}, /* WINED3D_SHADER_RESOURCE_NONE */
62 {1, 1, "Buffer"}, /* WINED3D_SHADER_RESOURCE_BUFFER */
63 {1, 1, "1D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */
64 {2, 2, "2D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */
65 {2, 2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */
66 {3, 3, "3D"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */
67 {3, 2, "Cube"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */
68 {2, 2, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */
69 {3, 3, "2DArray"}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */
70 {3, 3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */
71 {4, 3, ""}, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */
72};
73
75{
76 char reg_name[150];
77 char mask_str[6];
78};
79
81{
82 char reg_name[150];
83 char param_str[200];
84};
85
87{
89 unsigned int coord_mask;
90 unsigned int deriv_mask;
93 unsigned int offset_size;
95};
96
98{
102};
103
105{
106 unsigned int idx;
107 unsigned int version;
108};
109
111{
114 unsigned int *positions;
115 unsigned int size;
116};
117
118/* GLSL shader private data */
120{
126 unsigned char *stack;
128
135};
136
138{
146
157 struct
158 {
179};
180
182{
185};
186
188{
191
193};
194
196{
199
201};
202
204{
225};
226
228{
231};
232
233/* Struct to maintain data about a linked GLSL program */
235{
245 unsigned int constant_version;
247 DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
249};
250
252{
259};
260
267};
268
270{
274};
275
277{
281};
282
284{
287};
288
290{
292};
293
295{
298};
299
301{
304};
305
307{
309};
310
312{
313 union
314 {
323};
324
326{
330};
331
333{
337};
338
340{
343};
344
346
348{
349 switch (type)
350 {
351#define WINED3D_TO_STR(u) case u: return #u
358#undef WINED3D_TO_STR
359 default:
360 return wine_dbg_sprintf("UNKNOWN(%#x)", type);
361 }
362}
363
365{
366 switch (type)
367 {
369 return "vs";
370
372 return "hs";
373
375 return "ds";
376
378 return "gs";
379
381 return "ps";
382
384 return "cs";
385
386 default:
387 FIXME("Unhandled shader type %#x.\n", type);
388 return "unknown";
389 }
390}
391
392static unsigned int shader_glsl_get_version(const struct wined3d_gl_info *gl_info)
393{
394 if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 40))
395 return 440;
396 else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50))
397 return 150;
398 else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30))
399 return 130;
400 else
401 return 120;
402}
403
405 const struct wined3d_gl_info *gl_info)
406{
407 shader_addline(buffer, "#version %u\n", shader_glsl_get_version(gl_info));
408}
409
411{
412 char str[4][17];
413
414 wined3d_ftoa(values[0], str[0]);
415 wined3d_ftoa(values[1], str[1]);
416 wined3d_ftoa(values[2], str[2]);
417 wined3d_ftoa(values[3], str[3]);
418 shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]);
419}
420
422 const int *values, unsigned int size)
423{
424 int i;
425
426 if (!size || size > 4)
427 {
428 ERR("Invalid vector size %u.\n", size);
429 return;
430 }
431
432 if (size > 1)
433 shader_addline(buffer, "ivec%u(", size);
434
435 for (i = 0; i < size; ++i)
436 shader_addline(buffer, i ? ", %#x" : "%#x", values[i]);
437
438 if (size > 1)
440}
441
442static const char *get_info_log_line(const char **ptr)
443{
444 const char *p, *q;
445
446 p = *ptr;
447 if (!(q = strstr(p, "\n")))
448 {
449 if (!*p) return NULL;
450 *ptr += strlen(p);
451 return p;
452 }
453 *ptr = q + 1;
454
455 return p;
456}
457
458/* Context activation is done by the caller. */
459void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
460{
461 int length = 0;
462 char *log;
463
464 if (!WARN_ON(d3d_shader) && !FIXME_ON(d3d_shader))
465 return;
466
467 if (program)
468 GL_EXTCALL(glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length));
469 else
470 GL_EXTCALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length));
471
472 /* A size of 1 is just a null-terminated string, so the log should be bigger than
473 * that if there are errors. */
474 if (length > 1)
475 {
476 const char *ptr, *line;
477
479 /* The info log is supposed to be zero-terminated, but at least some
480 * versions of fglrx don't terminate the string properly. The reported
481 * length does include the terminator, so explicitly set it to zero
482 * here. */
483 log[length - 1] = 0;
484 if (program)
485 GL_EXTCALL(glGetProgramInfoLog(id, length, NULL, log));
486 else
487 GL_EXTCALL(glGetShaderInfoLog(id, length, NULL, log));
488
489 ptr = log;
490 if (gl_info->quirks & WINED3D_QUIRK_INFO_LOG_SPAM)
491 {
492 WARN("Info log received from GLSL shader #%u:\n", id);
493 while ((line = get_info_log_line(&ptr))) WARN(" %.*s", (int)(ptr - line), line);
494 }
495 else
496 {
497 FIXME("Info log received from GLSL shader #%u:\n", id);
498 while ((line = get_info_log_line(&ptr))) FIXME(" %.*s", (int)(ptr - line), line);
499 }
500 heap_free(log);
501 }
502}
503
504/* Context activation is done by the caller. */
505static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLuint shader, const char *src)
506{
507 const char *ptr, *line;
508
509 TRACE("Compiling shader object %u.\n", shader);
510
511 if (TRACE_ON(d3d_shader))
512 {
513 ptr = src;
514 while ((line = get_info_log_line(&ptr))) TRACE_(d3d_shader)(" %.*s", (int)(ptr - line), line);
515 }
516
517 GL_EXTCALL(glShaderSource(shader, 1, &src, NULL));
518 checkGLcall("glShaderSource");
519 GL_EXTCALL(glCompileShader(shader));
520 checkGLcall("glCompileShader");
522}
523
524/* Context activation is done by the caller. */
526{
527 GLint i, shader_count, source_size = -1;
529 char *source = NULL;
530
531 GL_EXTCALL(glGetProgramiv(program, GL_ATTACHED_SHADERS, &shader_count));
532 if (!(shaders = heap_calloc(shader_count, sizeof(*shaders))))
533 {
534 ERR("Failed to allocate shader array memory.\n");
535 return;
536 }
537
538 GL_EXTCALL(glGetAttachedShaders(program, shader_count, NULL, shaders));
539 for (i = 0; i < shader_count; ++i)
540 {
541 const char *ptr, *line;
542 GLint tmp;
543
544 GL_EXTCALL(glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &tmp));
545
546 if (source_size < tmp)
547 {
549
550 if (!(source = heap_alloc_zero(tmp)))
551 {
552 ERR("Failed to allocate %d bytes for shader source.\n", tmp);
554 return;
555 }
556 source_size = tmp;
557 }
558
559 FIXME("Shader %u:\n", shaders[i]);
560 GL_EXTCALL(glGetShaderiv(shaders[i], GL_SHADER_TYPE, &tmp));
561 FIXME(" GL_SHADER_TYPE: %s.\n", debug_gl_shader_type(tmp));
562 GL_EXTCALL(glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &tmp));
563 FIXME(" GL_COMPILE_STATUS: %d.\n", tmp);
564 FIXME("\n");
565
566 ptr = source;
567 GL_EXTCALL(glGetShaderSource(shaders[i], source_size, NULL, source));
568 while ((line = get_info_log_line(&ptr))) FIXME(" %.*s", (int)(ptr - line), line);
569 FIXME("\n");
570 }
571
574}
575
576/* Context activation is done by the caller. */
578{
579 GLint tmp;
580
581 if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader))
582 return;
583
584 GL_EXTCALL(glGetProgramiv(program, GL_LINK_STATUS, &tmp));
585 if (!tmp)
586 {
587 FIXME("Program %u link status invalid.\n", program);
589 }
590
592}
593
595{
596 /* Layout qualifiers were introduced in GLSL 1.40. The Nvidia Legacy GPU
597 * driver (series 340.xx) doesn't parse layout qualifiers in older GLSL
598 * versions. */
599 return shader_glsl_get_version(gl_info) >= 140;
600}
601
603{
605}
606
608 struct shader_glsl_priv *priv, GLuint program_id,
609 const struct wined3d_shader_reg_maps *reg_maps)
610{
611 const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
613 unsigned int i, base, count;
614 GLuint block_idx;
615
617 return;
618
621 for (i = 0; i < count; ++i)
622 {
623 if (!reg_maps->cb_sizes[i])
624 continue;
625
626 string_buffer_sprintf(name, "block_%s_cb%u", prefix, i);
627 block_idx = GL_EXTCALL(glGetUniformBlockIndex(program_id, name->buffer));
628 GL_EXTCALL(glUniformBlockBinding(program_id, block_idx, base + i));
629 }
630 checkGLcall("glUniformBlockBinding");
632}
633
634/* Context activation is done by the caller. */
635static void shader_glsl_load_samplers_range(const struct wined3d_gl_info *gl_info,
636 struct shader_glsl_priv *priv, GLuint program_id, const char *prefix,
637 unsigned int base, unsigned int count, const DWORD *tex_unit_map)
638{
639 struct wined3d_string_buffer *sampler_name = string_buffer_get(&priv->string_buffers);
640 unsigned int i, mapped_unit;
641 GLint name_loc;
642
643 for (i = 0; i < count; ++i)
644 {
645 string_buffer_sprintf(sampler_name, "%s_sampler%u", prefix, i);
646 name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name->buffer));
647 if (name_loc == -1)
648 continue;
649
650 mapped_unit = tex_unit_map ? tex_unit_map[base + i] : base + i;
651 if (mapped_unit == WINED3D_UNMAPPED_STAGE || mapped_unit >= gl_info->limits.combined_samplers)
652 {
653 ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name->buffer, mapped_unit);
654 continue;
655 }
656
657 TRACE("Loading sampler %s on unit %u.\n", sampler_name->buffer, mapped_unit);
658 GL_EXTCALL(glUniform1i(name_loc, mapped_unit));
659 }
660 checkGLcall("Load sampler bindings");
661 string_buffer_release(&priv->string_buffers, sampler_name);
662}
663
664static unsigned int shader_glsl_map_tex_unit(const struct wined3d_context *context,
665 const struct wined3d_shader_version *shader_version, unsigned int sampler_idx)
666{
667 const DWORD *tex_unit_map;
668 unsigned int base, count;
669
670 tex_unit_map = context_get_tex_unit_mapping(context, shader_version, &base, &count);
671 if (sampler_idx >= count)
673 if (!tex_unit_map)
674 return base + sampler_idx;
675 return tex_unit_map[base + sampler_idx];
676}
677
679 const struct wined3d_context *context, const struct wined3d_shader_version *shader_version,
680 unsigned int sampler_idx)
681{
682 unsigned int mapped_unit = shader_glsl_map_tex_unit(context, shader_version, sampler_idx);
683 if (mapped_unit != WINED3D_UNMAPPED_STAGE)
684 shader_addline(buffer, "layout(binding = %u)\n", mapped_unit);
685 else
686 ERR("Unmapped sampler %u.\n", sampler_idx);
687}
688
689/* Context activation is done by the caller. */
691 struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
692{
693 const struct wined3d_gl_info *gl_info = context->gl_info;
694 const struct wined3d_shader_version *shader_version;
695 const DWORD *tex_unit_map;
696 unsigned int base, count;
697 const char *prefix;
698
700 return;
701
702 shader_version = reg_maps ? &reg_maps->shader_version : NULL;
703 prefix = shader_glsl_get_prefix(shader_version ? shader_version->type : WINED3D_SHADER_TYPE_PIXEL);
704 tex_unit_map = context_get_tex_unit_mapping(context, shader_version, &base, &count);
705 shader_glsl_load_samplers_range(gl_info, priv, program_id, prefix, base, count, tex_unit_map);
706}
707
708static void shader_glsl_load_icb(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv,
709 GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
710{
711 const struct wined3d_shader_immediate_constant_buffer *icb = reg_maps->icb;
712
713 if (icb)
714 {
715 struct wined3d_string_buffer *icb_name = string_buffer_get(&priv->string_buffers);
716 const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
717 GLint icb_location;
718
719 string_buffer_sprintf(icb_name, "%s_icb", prefix);
720 icb_location = GL_EXTCALL(glGetUniformLocation(program_id, icb_name->buffer));
721 GL_EXTCALL(glUniform4fv(icb_location, icb->vec4_count, (const GLfloat *)icb->data));
722 checkGLcall("Load immediate constant buffer");
723
724 string_buffer_release(&priv->string_buffers, icb_name);
725 }
726}
727
728/* Context activation is done by the caller. */
729static void shader_glsl_load_images(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv,
730 GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
731{
732 const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
735 unsigned int i;
736
738 return;
739
741 for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i)
742 {
743 if (!reg_maps->uav_resource_info[i].type)
744 continue;
745
746 string_buffer_sprintf(name, "%s_image%u", prefix, i);
747 location = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
748 if (location == -1)
749 continue;
750
751 TRACE("Loading image %s on unit %u.\n", name->buffer, i);
752 GL_EXTCALL(glUniform1i(location, i));
753 }
754 checkGLcall("Load image bindings");
756}
757
758/* Context activation is done by the caller. */
760 struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
761{
762 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
763
764 shader_glsl_init_uniform_block_bindings(context->gl_info, priv, program_id, reg_maps);
765 shader_glsl_load_icb(context->gl_info, priv, program_id, reg_maps);
766 /* Texture unit mapping is set up to be the same each time the shader
767 * program is used so we can hardcode the sampler uniform values. */
768 shader_glsl_load_samplers(context, priv, program_id, reg_maps);
769}
770
771static void append_transform_feedback_varying(const char **varyings, unsigned int *varying_count,
772 char **strings, unsigned int *strings_length, struct wined3d_string_buffer *buffer)
773{
774 if (varyings && *strings)
775 {
776 char *ptr = *strings;
777
778 varyings[*varying_count] = ptr;
779
780 memcpy(ptr, buffer->buffer, buffer->content_size + 1);
781 ptr += buffer->content_size + 1;
782
783 *strings = ptr;
784 }
785
786 *strings_length += buffer->content_size + 1;
787 ++(*varying_count);
788}
789
791 unsigned int *varying_count, char **strings, unsigned int *strings_length,
792 struct wined3d_string_buffer *buffer, unsigned int component_count)
793{
794 unsigned int j;
795
796 for (j = 0; j < component_count / 4; ++j)
797 {
798 string_buffer_sprintf(buffer, "gl_SkipComponents4");
799 append_transform_feedback_varying(varyings, varying_count, strings, strings_length, buffer);
800 }
801 if (component_count % 4)
802 {
803 string_buffer_sprintf(buffer, "gl_SkipComponents%u", component_count % 4);
804 append_transform_feedback_varying(varyings, varying_count, strings, strings_length, buffer);
805 }
806}
807
809 struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count,
810 char *strings, unsigned int *strings_length, GLenum buffer_mode)
811{
812 unsigned int i, buffer_idx, count, length, highest_output_slot, stride;
813
814 count = length = 0;
815 highest_output_slot = 0;
816 for (buffer_idx = 0; buffer_idx < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++buffer_idx)
817 {
818 stride = 0;
819
820 for (i = 0; i < so_desc->element_count; ++i)
821 {
822 const struct wined3d_stream_output_element *e = &so_desc->elements[i];
823
824 highest_output_slot = max(highest_output_slot, e->output_slot);
825 if (e->output_slot != buffer_idx)
826 continue;
827
828 if (e->stream_idx)
829 {
830 FIXME("Unhandled stream %u.\n", e->stream_idx);
831 continue;
832 }
833
834 stride += e->component_count;
835
836 if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
837 {
839 &strings, &length, buffer, e->component_count);
840 continue;
841 }
842
843 if (e->component_idx || e->component_count != 4)
844 {
846 {
847 FIXME("Unsupported component range %u-%u.\n", e->component_idx, e->component_count);
849 &strings, &length, buffer, e->component_count);
850 continue;
851 }
852
853 string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u",
854 e->register_idx, e->component_idx, e->component_idx + e->component_count - 1);
856 }
857 else
858 {
859 string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx);
861 }
862 }
863
864 if (buffer_idx < so_desc->buffer_stride_count
865 && stride < so_desc->buffer_strides[buffer_idx] / 4)
866 {
867 unsigned int component_count = so_desc->buffer_strides[buffer_idx] / 4 - stride;
870 }
871
872 if (highest_output_slot <= buffer_idx)
873 break;
874
875 if (buffer_mode == GL_INTERLEAVED_ATTRIBS)
876 {
877 string_buffer_sprintf(buffer, "gl_NextBuffer");
879 }
880 }
881
882 if (varying_count)
883 *varying_count = count;
884 if (strings_length)
885 *strings_length = length;
886}
887
889 struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
890{
891 const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
892 const struct wined3d_gl_info *gl_info = context->gl_info;
894 unsigned int i, count, length;
895 const char **varyings;
896 char *strings;
897 GLenum mode;
898
899 if (!so_desc->element_count)
900 return;
901
903 {
905 }
906 else
907 {
908 unsigned int element_count[WINED3D_MAX_STREAM_OUTPUT_BUFFERS] = {0};
909
910 for (i = 0; i < so_desc->element_count; ++i)
911 {
912 if (so_desc->elements[i].register_idx == WINED3D_STREAM_OUTPUT_GAP)
913 {
914 FIXME("ARB_transform_feedback3 is needed for stream output gaps.\n");
915 return;
916 }
917 ++element_count[so_desc->elements[i].output_slot];
918 }
919
920 if (element_count[0] == so_desc->element_count)
921 {
923 }
924 else
925 {
927 for (i = 0; i < ARRAY_SIZE(element_count); ++i)
928 {
929 if (element_count[i] != 1)
930 break;
931 }
932 for (; i < ARRAY_SIZE(element_count); ++i)
933 {
934 if (element_count[i])
935 {
936 FIXME("Only single element per buffer is allowed in separate mode.\n");
937 return;
938 }
939 }
940 }
941 }
942
944
946
947 if (!(varyings = heap_calloc(count, sizeof(*varyings))))
948 {
949 ERR("Out of memory.\n");
951 return;
952 }
953 if (!(strings = heap_calloc(length, sizeof(*strings))))
954 {
955 ERR("Out of memory.\n");
958 return;
959 }
960
962 GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode));
963 checkGLcall("glTransformFeedbackVaryings");
964
968}
969
970/* Context activation is done by the caller. */
971static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const struct wined3d_vec4 *constants,
972 const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
973{
974 unsigned int start = ~0U, end = 0;
975 int stack_idx = 0;
976 unsigned int heap_idx = 1;
977 unsigned int idx;
978
979 if (heap->entries[heap_idx].version <= version) return;
980
981 idx = heap->entries[heap_idx].idx;
982 if (constant_locations[idx] != -1)
983 start = end = idx;
984 stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
985
986 while (stack_idx >= 0)
987 {
988 /* Note that we fall through to the next case statement. */
989 switch(stack[stack_idx])
990 {
992 {
993 unsigned int left_idx = heap_idx << 1;
994 if (left_idx < heap->size && heap->entries[left_idx].version > version)
995 {
996 heap_idx = left_idx;
997 idx = heap->entries[heap_idx].idx;
998 if (constant_locations[idx] != -1)
999 {
1000 if (start > idx)
1001 start = idx;
1002 if (end < idx)
1003 end = idx;
1004 }
1005
1006 stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
1007 stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
1008 break;
1009 }
1010 }
1011
1013 {
1014 unsigned int right_idx = (heap_idx << 1) + 1;
1015 if (right_idx < heap->size && heap->entries[right_idx].version > version)
1016 {
1017 heap_idx = right_idx;
1018 idx = heap->entries[heap_idx].idx;
1019 if (constant_locations[idx] != -1)
1020 {
1021 if (start > idx)
1022 start = idx;
1023 if (end < idx)
1024 end = idx;
1025 }
1026
1027 stack[stack_idx++] = HEAP_NODE_POP;
1028 stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
1029 break;
1030 }
1031 }
1032
1033 case HEAP_NODE_POP:
1034 heap_idx >>= 1;
1035 --stack_idx;
1036 break;
1037 }
1038 }
1039 if (start <= end)
1040 GL_EXTCALL(glUniform4fv(constant_locations[start], end - start + 1, &constants[start].x));
1041 checkGLcall("walk_constant_heap()");
1042}
1043
1044/* Context activation is done by the caller. */
1045static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info,
1046 GLint location, const struct wined3d_vec4 *data)
1047{
1048 GLfloat clamped_constant[4];
1049
1050 if (location == -1) return;
1051
1052 clamped_constant[0] = data->x < -1.0f ? -1.0f : data->x > 1.0f ? 1.0f : data->x;
1053 clamped_constant[1] = data->y < -1.0f ? -1.0f : data->y > 1.0f ? 1.0f : data->y;
1054 clamped_constant[2] = data->z < -1.0f ? -1.0f : data->z > 1.0f ? 1.0f : data->z;
1055 clamped_constant[3] = data->w < -1.0f ? -1.0f : data->w > 1.0f ? 1.0f : data->w;
1056
1057 GL_EXTCALL(glUniform4fv(location, 1, clamped_constant));
1058}
1059
1060/* Context activation is done by the caller. */
1061static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info,
1062 const struct wined3d_vec4 *constants, const GLint *constant_locations,
1063 const struct constant_heap *heap, unsigned char *stack, DWORD version)
1064{
1065 int stack_idx = 0;
1066 unsigned int heap_idx = 1;
1067 unsigned int idx;
1068
1069 if (heap->entries[heap_idx].version <= version) return;
1070
1071 idx = heap->entries[heap_idx].idx;
1072 apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx]);
1073 stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
1074
1075 while (stack_idx >= 0)
1076 {
1077 /* Note that we fall through to the next case statement. */
1078 switch(stack[stack_idx])
1079 {
1081 {
1082 unsigned int left_idx = heap_idx << 1;
1083 if (left_idx < heap->size && heap->entries[left_idx].version > version)
1084 {
1085 heap_idx = left_idx;
1086 idx = heap->entries[heap_idx].idx;
1087 apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx]);
1088
1089 stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
1090 stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
1091 break;
1092 }
1093 }
1094
1096 {
1097 unsigned int right_idx = (heap_idx << 1) + 1;
1098 if (right_idx < heap->size && heap->entries[right_idx].version > version)
1099 {
1100 heap_idx = right_idx;
1101 idx = heap->entries[heap_idx].idx;
1102 apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx]);
1103
1104 stack[stack_idx++] = HEAP_NODE_POP;
1105 stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
1106 break;
1107 }
1108 }
1109
1110 case HEAP_NODE_POP:
1111 heap_idx >>= 1;
1112 --stack_idx;
1113 break;
1114 }
1115 }
1116 checkGLcall("walk_constant_heap_clamped()");
1117}
1118
1119/* Context activation is done by the caller. */
1120static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
1121 const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap,
1122 unsigned char *stack, unsigned int version)
1123{
1124 const struct wined3d_shader_lconst *lconst;
1125
1126 /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
1127 if (shader->reg_maps.shader_version.major == 1
1128 && shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
1129 walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
1130 else
1131 walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
1132
1133 if (!shader->load_local_constsF)
1134 {
1135 TRACE("No need to load local float constants for this shader.\n");
1136 return;
1137 }
1138
1139 /* Immediate constants are clamped to [-1;1] at shader creation time if needed */
1140 LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
1141 {
1142 GL_EXTCALL(glUniform4fv(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value));
1143 }
1144 checkGLcall("glUniform4fv()");
1145}
1146
1147/* Context activation is done by the caller. */
1148static void shader_glsl_load_constants_i(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
1149 const struct wined3d_ivec4 *constants, const GLint locations[WINED3D_MAX_CONSTS_I], WORD constants_set)
1150{
1151 unsigned int i;
1152 struct list* ptr;
1153
1154 for (i = 0; constants_set; constants_set >>= 1, ++i)
1155 {
1156 if (!(constants_set & 1)) continue;
1157
1158 /* We found this uniform name in the program - go ahead and send the data */
1159 GL_EXTCALL(glUniform4iv(locations[i], 1, &constants[i].x));
1160 }
1161
1162 /* Load immediate constants */
1163 ptr = list_head(&shader->constantsI);
1164 while (ptr)
1165 {
1166 const struct wined3d_shader_lconst *lconst = LIST_ENTRY(ptr, const struct wined3d_shader_lconst, entry);
1167 unsigned int idx = lconst->idx;
1168 const GLint *values = (const GLint *)lconst->value;
1169
1170 /* We found this uniform name in the program - go ahead and send the data */
1171 GL_EXTCALL(glUniform4iv(locations[idx], 1, values));
1172 ptr = list_next(&shader->constantsI, ptr);
1173 }
1174 checkGLcall("glUniform4iv()");
1175}
1176
1177/* Context activation is done by the caller. */
1178static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
1179 const GLint locations[WINED3D_MAX_CONSTS_B], const BOOL *constants, WORD constants_set)
1180{
1181 unsigned int i;
1182 struct list* ptr;
1183
1184 for (i = 0; constants_set; constants_set >>= 1, ++i)
1185 {
1186 if (!(constants_set & 1)) continue;
1187
1188 GL_EXTCALL(glUniform1iv(locations[i], 1, &constants[i]));
1189 }
1190
1191 /* Load immediate constants */
1192 ptr = list_head(&shader->constantsB);
1193 while (ptr)
1194 {
1195 const struct wined3d_shader_lconst *lconst = LIST_ENTRY(ptr, const struct wined3d_shader_lconst, entry);
1196 unsigned int idx = lconst->idx;
1197 const GLint *values = (const GLint *)lconst->value;
1198
1199 GL_EXTCALL(glUniform1iv(locations[idx], 1, values));
1200 ptr = list_next(&shader->constantsB, ptr);
1201 }
1202 checkGLcall("glUniform1iv()");
1203}
1204
1206{
1207 WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry)->constant_version = 0;
1208}
1209
1210/* Context activation is done by the caller (state handler). */
1212 const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
1213{
1214 struct
1215 {
1216 float sx, sy;
1217 }
1218 np2fixup_constants[MAX_FRAGMENT_SAMPLERS];
1219 UINT fixup = ps->np2_fixup_info->active;
1220 UINT i;
1221
1222 for (i = 0; fixup; fixup >>= 1, ++i)
1223 {
1224 const struct wined3d_texture *tex = state->textures[i];
1225 unsigned char idx = ps->np2_fixup_info->idx[i];
1226
1227 if (!tex)
1228 {
1229 ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
1230 continue;
1231 }
1232
1233 np2fixup_constants[idx].sx = tex->pow2_matrix[0];
1234 np2fixup_constants[idx].sy = tex->pow2_matrix[5];
1235 }
1236
1237 GL_EXTCALL(glUniform4fv(ps->np2_fixup_location, ps->np2_fixup_info->num_consts, &np2fixup_constants[0].sx));
1238}
1239
1241 const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog)
1242{
1243 const struct wined3d_gl_info *gl_info = context->gl_info;
1244 struct wined3d_matrix mat;
1245
1246 if (tex >= MAX_TEXTURES)
1247 return;
1248 if (prog->vs.texture_matrix_location[tex] == -1)
1249 return;
1250
1252 GL_EXTCALL(glUniformMatrix4fv(prog->vs.texture_matrix_location[tex], 1, FALSE, &mat._11));
1253 checkGLcall("glUniformMatrix4fv");
1254}
1255
1257 const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
1258{
1259 const struct wined3d_gl_info *gl_info = context->gl_info;
1260
1261 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1262 {
1263 GL_EXTCALL(glUniform4fv(prog->vs.material_specular_location, 1, &state->material.specular.r));
1264 GL_EXTCALL(glUniform1f(prog->vs.material_shininess_location, state->material.power));
1265 }
1266 else
1267 {
1268 static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1269
1270 GL_EXTCALL(glUniform4fv(prog->vs.material_specular_location, 1, black));
1271 }
1272 GL_EXTCALL(glUniform4fv(prog->vs.material_ambient_location, 1, &state->material.ambient.r));
1273 GL_EXTCALL(glUniform4fv(prog->vs.material_diffuse_location, 1, &state->material.diffuse.r));
1274 GL_EXTCALL(glUniform4fv(prog->vs.material_emissive_location, 1, &state->material.emissive.r));
1275 checkGLcall("setting FFP material uniforms");
1276}
1277
1279 const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
1280{
1281 const struct wined3d_gl_info *gl_info = context->gl_info;
1282 struct wined3d_color color;
1283
1285 GL_EXTCALL(glUniform3fv(prog->vs.light_ambient_location, 1, &color.r));
1286 checkGLcall("glUniform3fv");
1287}
1288
1289static void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1,
1290 const struct wined3d_matrix *src2)
1291{
1292 struct wined3d_vec4 temp;
1293
1294 temp.x = (src1->x * src2->_11) + (src1->y * src2->_21) + (src1->z * src2->_31) + (src1->w * src2->_41);
1295 temp.y = (src1->x * src2->_12) + (src1->y * src2->_22) + (src1->z * src2->_32) + (src1->w * src2->_42);
1296 temp.z = (src1->x * src2->_13) + (src1->y * src2->_23) + (src1->z * src2->_33) + (src1->w * src2->_43);
1297 temp.w = (src1->x * src2->_14) + (src1->y * src2->_24) + (src1->z * src2->_34) + (src1->w * src2->_44);
1298
1299 *dest = temp;
1300}
1301
1303 const struct wined3d_state *state, unsigned int light, const struct wined3d_light_info *light_info,
1305{
1306 const struct wined3d_matrix *view = &state->transforms[WINED3D_TS_VIEW];
1307 const struct wined3d_gl_info *gl_info = context->gl_info;
1308 struct wined3d_vec4 vec4;
1309
1310 GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].diffuse, 1, &light_info->OriginalParms.diffuse.r));
1311 GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].specular, 1, &light_info->OriginalParms.specular.r));
1312 GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].ambient, 1, &light_info->OriginalParms.ambient.r));
1313
1314 switch (light_info->OriginalParms.type)
1315 {
1317 multiply_vector_matrix(&vec4, &light_info->position, view);
1318 GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x));
1319 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].range, light_info->OriginalParms.range));
1320 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].c_att, light_info->OriginalParms.attenuation0));
1321 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].l_att, light_info->OriginalParms.attenuation1));
1322 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].q_att, light_info->OriginalParms.attenuation2));
1323 break;
1324
1325 case WINED3D_LIGHT_SPOT:
1326 multiply_vector_matrix(&vec4, &light_info->position, view);
1327 GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x));
1328
1329 multiply_vector_matrix(&vec4, &light_info->direction, view);
1330 GL_EXTCALL(glUniform3fv(prog->vs.light_location[light].direction, 1, &vec4.x));
1331
1332 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].range, light_info->OriginalParms.range));
1333 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].falloff, light_info->OriginalParms.falloff));
1334 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].c_att, light_info->OriginalParms.attenuation0));
1335 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].l_att, light_info->OriginalParms.attenuation1));
1336 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].q_att, light_info->OriginalParms.attenuation2));
1337 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].cos_htheta, cosf(light_info->OriginalParms.theta / 2.0f)));
1338 GL_EXTCALL(glUniform1f(prog->vs.light_location[light].cos_hphi, cosf(light_info->OriginalParms.phi / 2.0f)));
1339 break;
1340
1342 multiply_vector_matrix(&vec4, &light_info->direction, view);
1343 GL_EXTCALL(glUniform3fv(prog->vs.light_location[light].direction, 1, &vec4.x));
1344 break;
1345
1347 multiply_vector_matrix(&vec4, &light_info->position, view);
1348 GL_EXTCALL(glUniform4fv(prog->vs.light_location[light].position, 1, &vec4.x));
1349 break;
1350
1351 default:
1352 FIXME("Unrecognized light type %#x.\n", light_info->OriginalParms.type);
1353 }
1354 checkGLcall("setting FFP lights uniforms");
1355}
1356
1358 const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
1359{
1360 const struct wined3d_gl_info *gl_info = context->gl_info;
1361 float min, max;
1362 float size, att[3];
1363
1365
1366 GL_EXTCALL(glUniform1f(prog->vs.pointsize_min_location, min));
1367 checkGLcall("glUniform1f");
1368 GL_EXTCALL(glUniform1f(prog->vs.pointsize_max_location, max));
1369 checkGLcall("glUniform1f");
1370
1372
1373 GL_EXTCALL(glUniform1f(prog->vs.pointsize_location, size));
1374 checkGLcall("glUniform1f");
1375 GL_EXTCALL(glUniform1f(prog->vs.pointsize_c_att_location, att[0]));
1376 checkGLcall("glUniform1f");
1377 GL_EXTCALL(glUniform1f(prog->vs.pointsize_l_att_location, att[1]));
1378 checkGLcall("glUniform1f");
1379 GL_EXTCALL(glUniform1f(prog->vs.pointsize_q_att_location, att[2]));
1380 checkGLcall("glUniform1f");
1381}
1382
1384 const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
1385{
1386 const struct wined3d_gl_info *gl_info = context->gl_info;
1387 struct wined3d_color color;
1388 float start, end, scale;
1389 union
1390 {
1391 DWORD d;
1392 float f;
1393 } tmpvalue;
1394
1396 GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, &color.r));
1397 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1398 GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, tmpvalue.f));
1400 scale = 1.0f / (end - start);
1401 GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, end));
1402 GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, scale));
1403 checkGLcall("fog emulation uniforms");
1404}
1405
1407 const struct wined3d_state *state, unsigned int index, struct glsl_shader_prog_link *prog)
1408{
1409 const struct wined3d_gl_info *gl_info = context->gl_info;
1410 struct wined3d_matrix matrix;
1411 struct wined3d_vec4 plane;
1412
1413 plane = state->clip_planes[index];
1414
1415 /* Clip planes are affected by the view transform in d3d for FFP draws. */
1416 if (!use_vs(state))
1417 {
1418 invert_matrix(&matrix, &state->transforms[WINED3D_TS_VIEW]);
1421 }
1422
1423 GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &plane.x));
1424}
1425
1426/* Context activation is done by the caller (state handler). */
1428 const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
1429{
1430 struct wined3d_color float_key[2];
1431 const struct wined3d_texture *texture = state->textures[0];
1432
1433 wined3d_format_get_float_color_key(texture->resource.format, &texture->async.src_blt_color_key, float_key);
1434 GL_EXTCALL(glUniform4fv(ps->color_key_location, 2, &float_key[0].r));
1435}
1436
1437/* Context activation is done by the caller. */
1439{
1440 int i, j;
1441
1442 if (context->d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING)
1444 else
1446 /* Tests show that singular modelview matrices are used unchanged as normal
1447 * matrices on D3D3 and older. There seems to be no clearly consistent
1448 * behavior on newer D3D versions so always follow older ddraw behavior. */
1449 for (i = 0; i < 3; ++i)
1450 for (j = 0; j < 3; ++j)
1451 normal[i * 3 + j] = (&mat->_11)[j * 4 + i];
1452}
1453
1454/* Context activation is done by the caller (state handler). */
1455static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context,
1456 const struct wined3d_state *state)
1457{
1458 const struct glsl_context_data *ctx_data = context->shader_backend_data;
1459 const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
1460 const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
1461 const struct wined3d_gl_info *gl_info = context->gl_info;
1462 struct shader_glsl_priv *priv = shader_priv;
1463 float position_fixup[4];
1464 float normal[3 * 3];
1465 DWORD update_mask;
1466
1467 struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
1469 int i;
1470
1471 if (!prog) {
1472 /* No GLSL program set - nothing to do. */
1473 return;
1474 }
1475 constant_version = prog->constant_version;
1476 update_mask = context->constant_update_mask & prog->constant_update_mask;
1477
1478 if (update_mask & WINED3D_SHADER_CONST_VS_F)
1479 shader_glsl_load_constants_f(vshader, gl_info, state->vs_consts_f,
1480 prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
1481
1482 if (update_mask & WINED3D_SHADER_CONST_VS_I)
1483 shader_glsl_load_constants_i(vshader, gl_info, state->vs_consts_i,
1484 prog->vs.uniform_i_locations, vshader->reg_maps.integer_constants);
1485
1486 if (update_mask & WINED3D_SHADER_CONST_VS_B)
1487 shader_glsl_load_constantsB(vshader, gl_info, prog->vs.uniform_b_locations, state->vs_consts_b,
1488 vshader->reg_maps.boolean_constants);
1489
1490 if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES)
1491 {
1492 for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
1494 }
1495
1496 if (update_mask & WINED3D_SHADER_CONST_VS_POINTSIZE)
1498
1499 if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP)
1500 {
1501 shader_get_position_fixup(context, state, position_fixup);
1503 GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup));
1504 else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
1505 GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup));
1506 else
1507 GL_EXTCALL(glUniform4fv(prog->vs.pos_fixup_location, 1, position_fixup));
1508 checkGLcall("glUniform4fv");
1509 }
1510
1511 if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW)
1512 {
1513 struct wined3d_matrix mat;
1514
1516 GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11));
1517 checkGLcall("glUniformMatrix4fv");
1518
1520 GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[0], 1, FALSE, normal));
1521 checkGLcall("glUniformMatrix3fv");
1522 }
1523
1524 if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND)
1525 {
1526 struct wined3d_matrix mat;
1527
1528 for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
1529 {
1530 if (prog->vs.modelview_matrix_location[i] == -1)
1531 break;
1532 if (!(update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i)))
1533 continue;
1534
1536 GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
1537 checkGLcall("glUniformMatrix4fv");
1538
1540 GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[i], 1, FALSE, normal));
1541 checkGLcall("glUniformMatrix3fv");
1542 }
1543 }
1544
1545 if (update_mask & WINED3D_SHADER_CONST_FFP_PROJ)
1546 {
1547 struct wined3d_matrix projection;
1548
1549 get_projection_matrix(context, state, &projection);
1550 GL_EXTCALL(glUniformMatrix4fv(prog->vs.projection_matrix_location, 1, FALSE, &projection._11));
1551 checkGLcall("glUniformMatrix4fv");
1552 }
1553
1554 if (update_mask & WINED3D_SHADER_CONST_FFP_TEXMATRIX)
1555 {
1556 for (i = 0; i < MAX_TEXTURES; ++i)
1558 }
1559
1560 if (update_mask & WINED3D_SHADER_CONST_FFP_MATERIAL)
1562
1563 if (update_mask & WINED3D_SHADER_CONST_FFP_LIGHTS)
1564 {
1565 unsigned int point_idx, spot_idx, directional_idx, parallel_point_idx;
1566 DWORD point_count = 0;
1567 DWORD spot_count = 0;
1568 DWORD directional_count = 0;
1569 DWORD parallel_point_count = 0;
1570
1571 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
1572 {
1573 if (!state->lights[i])
1574 continue;
1575
1576 switch (state->lights[i]->OriginalParms.type)
1577 {
1579 ++point_count;
1580 break;
1581 case WINED3D_LIGHT_SPOT:
1582 ++spot_count;
1583 break;
1585 ++directional_count;
1586 break;
1588 ++parallel_point_count;
1589 break;
1590 default:
1591 FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type);
1592 break;
1593 }
1594 }
1595 point_idx = 0;
1596 spot_idx = point_idx + point_count;
1597 directional_idx = spot_idx + spot_count;
1598 parallel_point_idx = directional_idx + directional_count;
1599
1601 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
1602 {
1603 const struct wined3d_light_info *light_info = state->lights[i];
1604 unsigned int idx;
1605
1606 if (!light_info)
1607 continue;
1608
1609 switch (light_info->OriginalParms.type)
1610 {
1612 idx = point_idx++;
1613 break;
1614 case WINED3D_LIGHT_SPOT:
1615 idx = spot_idx++;
1616 break;
1618 idx = directional_idx++;
1619 break;
1621 idx = parallel_point_idx++;
1622 break;
1623 default:
1624 FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type);
1625 continue;
1626 }
1628 }
1629 }
1630
1631 if (update_mask & WINED3D_SHADER_CONST_PS_F)
1632 shader_glsl_load_constants_f(pshader, gl_info, state->ps_consts_f,
1633 prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
1634
1635 if (update_mask & WINED3D_SHADER_CONST_PS_I)
1636 shader_glsl_load_constants_i(pshader, gl_info, state->ps_consts_i,
1637 prog->ps.uniform_i_locations, pshader->reg_maps.integer_constants);
1638
1639 if (update_mask & WINED3D_SHADER_CONST_PS_B)
1640 shader_glsl_load_constantsB(pshader, gl_info, prog->ps.uniform_b_locations, state->ps_consts_b,
1641 pshader->reg_maps.boolean_constants);
1642
1643 if (update_mask & WINED3D_SHADER_CONST_PS_BUMP_ENV)
1644 {
1645 for (i = 0; i < MAX_TEXTURES; ++i)
1646 {
1647 if (prog->ps.bumpenv_mat_location[i] == -1)
1648 continue;
1649
1650 GL_EXTCALL(glUniformMatrix2fv(prog->ps.bumpenv_mat_location[i], 1, 0,
1651 (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00]));
1652
1653 if (prog->ps.bumpenv_lum_scale_location[i] != -1)
1654 {
1655 GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_scale_location[i], 1,
1656 (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE]));
1657 GL_EXTCALL(glUniform1fv(prog->ps.bumpenv_lum_offset_location[i], 1,
1658 (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET]));
1659 }
1660 }
1661
1662 checkGLcall("bump env uniforms");
1663 }
1664
1665 if (update_mask & WINED3D_SHADER_CONST_PS_Y_CORR)
1666 {
1667 const struct wined3d_vec4 correction_params =
1668 {
1669 /* Position is relative to the framebuffer, not the viewport. */
1670 context->render_offscreen ? 0.0f : (float)state->fb->render_targets[0]->height,
1671 context->render_offscreen ? 1.0f : -1.0f,
1672 0.0f,
1673 0.0f,
1674 };
1675
1676 GL_EXTCALL(glUniform4fv(prog->ps.ycorrection_location, 1, &correction_params.x));
1677 }
1678
1679 if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP)
1681 if (update_mask & WINED3D_SHADER_CONST_FFP_COLOR_KEY)
1683
1684 if (update_mask & WINED3D_SHADER_CONST_FFP_PS)
1685 {
1686 struct wined3d_color color;
1687
1688 if (prog->ps.tex_factor_location != -1)
1689 {
1691 GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, &color.r));
1692 }
1693
1694 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1695 GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f));
1696 else
1697 GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f));
1698
1699 for (i = 0; i < MAX_TEXTURES; ++i)
1700 {
1701 if (prog->ps.tss_constant_location[i] == -1)
1702 continue;
1703
1705 GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, &color.r));
1706 }
1707
1708 checkGLcall("fixed function uniforms");
1709 }
1710
1711 if (update_mask & WINED3D_SHADER_CONST_PS_FOG)
1713
1714 if (update_mask & WINED3D_SHADER_CONST_PS_ALPHA_TEST)
1715 {
1716 float ref = state->render_states[WINED3D_RS_ALPHAREF] / 255.0f;
1717
1718 GL_EXTCALL(glUniform1f(prog->ps.alpha_test_ref_location, ref));
1719 checkGLcall("alpha test emulation uniform");
1720 }
1721
1722 if (priv->next_constant_version == UINT_MAX)
1723 {
1724 TRACE("Max constant version reached, resetting to 0.\n");
1726 priv->next_constant_version = 1;
1727 }
1728 else
1729 {
1730 prog->constant_version = priv->next_constant_version++;
1731 }
1732}
1733
1734static void update_heap_entry(struct constant_heap *heap, unsigned int idx, DWORD new_version)
1735{
1736 struct constant_entry *entries = heap->entries;
1737 unsigned int *positions = heap->positions;
1738 unsigned int heap_idx, parent_idx;
1739
1740 if (!heap->contained[idx])
1741 {
1742 heap_idx = heap->size++;
1743 heap->contained[idx] = TRUE;
1744 }
1745 else
1746 {
1747 heap_idx = positions[idx];
1748 }
1749
1750 while (heap_idx > 1)
1751 {
1752 parent_idx = heap_idx >> 1;
1753
1754 if (new_version <= entries[parent_idx].version) break;
1755
1756 entries[heap_idx] = entries[parent_idx];
1757 positions[entries[parent_idx].idx] = heap_idx;
1758 heap_idx = parent_idx;
1759 }
1760
1761 entries[heap_idx].version = new_version;
1762 entries[heap_idx].idx = idx;
1763 positions[idx] = heap_idx;
1764}
1765
1767{
1768 struct shader_glsl_priv *priv = device->shader_priv;
1769 struct constant_heap *heap = &priv->vconst_heap;
1770 UINT i;
1771
1772 for (i = start; i < count + start; ++i)
1773 {
1775 }
1776}
1777
1779{
1780 struct shader_glsl_priv *priv = device->shader_priv;
1781 struct constant_heap *heap = &priv->pconst_heap;
1782 UINT i;
1783
1784 for (i = start; i < count + start; ++i)
1785 {
1787 }
1788}
1789
1790static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_info *gl_info)
1791{
1792 unsigned int ret = gl_info->limits.glsl_varyings / 4;
1793 /* 4.0 shaders do not write clip coords because d3d10 does not support user clipplanes */
1794 if(shader_major > 3) return ret;
1795
1796 /* 3.0 shaders may need an extra varying for the clip coord on some cards(mostly dx10 ones) */
1797 if (gl_info->quirks & WINED3D_QUIRK_GLSL_CLIP_VARYING) ret -= 1;
1798 return ret;
1799}
1800
1801static BOOL needs_legacy_glsl_syntax(const struct wined3d_gl_info *gl_info)
1802{
1803 return gl_info->glsl_version < MAKEDWORD_VERSION(1, 30);
1804}
1805
1807{
1810}
1811
1813{
1814 return shader_glsl_get_version(gl_info) >= 150;
1815}
1816
1817static const char *get_attribute_keyword(const struct wined3d_gl_info *gl_info)
1818{
1819 return needs_legacy_glsl_syntax(gl_info) ? "attribute" : "in";
1820}
1821
1822static void PRINTF_ATTR(4, 5) declare_in_varying(const struct wined3d_gl_info *gl_info,
1824{
1825 va_list args;
1826 int ret;
1827
1828 shader_addline(buffer, "%s%s ", flat ? "flat " : "",
1829 needs_legacy_glsl_syntax(gl_info) ? "varying" : "in");
1830 for (;;)
1831 {
1834 va_end(args);
1835 if (!ret)
1836 return;
1838 return;
1839 }
1840}
1841
1842static void PRINTF_ATTR(4, 5) declare_out_varying(const struct wined3d_gl_info *gl_info,
1844{
1845 va_list args;
1846 int ret;
1847
1848 shader_addline(buffer, "%s%s ", flat ? "flat " : "",
1849 needs_legacy_glsl_syntax(gl_info) ? "varying" : "out");
1850 for (;;)
1851 {
1854 va_end(args);
1855 if (!ret)
1856 return;
1858 return;
1859 }
1860}
1861
1862static const char *shader_glsl_shader_input_name(const struct wined3d_gl_info *gl_info)
1863{
1864 return shader_glsl_use_interface_blocks(gl_info) ? "shader_in.reg" : "ps_link";
1865}
1866
1867static const char *shader_glsl_shader_output_name(const struct wined3d_gl_info *gl_info)
1868{
1869 return shader_glsl_use_interface_blocks(gl_info) ? "shader_out.reg" : "ps_link";
1870}
1871
1873{
1874 switch (mode)
1875 {
1877 return "flat";
1879 return "noperspective";
1880 default:
1881 FIXME("Unhandled interpolation mode %#x.\n", mode);
1882 case WINED3DSIM_NONE:
1883 case WINED3DSIM_LINEAR:
1884 return "";
1885 }
1886}
1887
1889 const DWORD *packed_interpolation_mode, unsigned int register_idx)
1890{
1891 return wined3d_extract_bits(packed_interpolation_mode,
1893}
1894
1895static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_info,
1896 struct wined3d_string_buffer *buffer, unsigned int element_count,
1897 const DWORD *interpolation_mode, BOOL unroll)
1898{
1900 unsigned int i;
1901
1903 {
1904 if (unroll)
1905 {
1906 shader_addline(buffer, "in shader_in_out {\n");
1907 for (i = 0; i < element_count; ++i)
1908 {
1909 mode = wined3d_extract_interpolation_mode(interpolation_mode, i);
1911 }
1912 shader_addline(buffer, "} shader_in;\n");
1913 }
1914 else
1915 {
1916 shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in;\n", element_count);
1917 }
1918 }
1919 else
1920 {
1921 declare_in_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", element_count);
1922 }
1923}
1924
1925static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info,
1926 struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL rasterizer_setup,
1927 const DWORD *interpolation_mode)
1928{
1930 unsigned int i;
1931
1933 {
1934 if (rasterizer_setup)
1935 {
1936 shader_addline(buffer, "out shader_in_out {\n");
1937 for (i = 0; i < element_count; ++i)
1938 {
1939 const char *interpolation_qualifiers = "";
1941 {
1942 mode = wined3d_extract_interpolation_mode(interpolation_mode, i);
1943 interpolation_qualifiers = shader_glsl_interpolation_qualifiers(mode);
1944 }
1945 shader_addline(buffer, "%s vec4 reg%u;\n", interpolation_qualifiers, i);
1946 }
1947 shader_addline(buffer, "} shader_out;\n");
1948 }
1949 else
1950 {
1951 shader_addline(buffer, "out shader_in_out { vec4 reg[%u]; } shader_out;\n", element_count);
1952 }
1953 }
1954 else
1955 {
1956 declare_out_varying(gl_info, buffer, FALSE, "vec4 ps_link[%u];\n", element_count);
1957 }
1958}
1959
1960static const char *glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
1961{
1962 switch (primitive_type)
1963 {
1965 return "points";
1966
1968 return "lines";
1969
1971 return "line_strip";
1972
1974 return "triangles";
1975
1977 return "triangle_strip";
1978
1980 return "lines_adjacency";
1981
1983 return "triangles_adjacency";
1984
1985 default:
1986 FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(primitive_type));
1987 return "";
1988 }
1989}
1990
1991static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned int idx)
1992{
1993 const struct wined3d_shader_signature *input_signature = &shader->input_signature;
1994 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
1995 DWORD input_reg_used = shader->u.ps.input_reg_used;
1996 unsigned int i;
1997
1998 if (reg_maps->shader_version.major < 3)
1999 return input_reg_used & (1u << idx);
2000
2001 for (i = 0; i < input_signature->element_count; ++i)
2002 {
2003 const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
2004
2005 if (!(reg_maps->input_registers & (1u << input->register_idx)))
2006 continue;
2007
2009 && input->semantic_idx == idx)
2010 return input_reg_used & (1u << input->register_idx);
2011 }
2012 return FALSE;
2013}
2014
2016 const struct ps_compile_args *ps_args, unsigned int resource_idx, unsigned int sampler_idx)
2017{
2018 const struct wined3d_shader_version *version = &shader->reg_maps.shader_version;
2019
2020 if (version->major >= 4)
2021 return shader->reg_maps.sampler_comparison_mode & (1u << sampler_idx);
2022 else
2023 return version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << resource_idx));
2024}
2025
2027 const struct wined3d_gl_info *gl_info, const char *vector_type, const char *scalar_type,
2028 unsigned int index)
2029{
2030 shader_addline(buffer, "%s %s4 vs_in_%s%u;\n",
2031 get_attribute_keyword(gl_info), vector_type, scalar_type, index);
2032 shader_addline(buffer, "vec4 vs_in%u = %sBitsToFloat(vs_in_%s%u);\n",
2033 index, scalar_type, scalar_type, index);
2034}
2035
2037 const struct wined3d_gl_info *gl_info, const struct wined3d_shader_signature_element *e)
2038{
2039 unsigned int index = e->register_idx;
2040
2041 if (e->sysval_semantic == WINED3D_SV_VERTEX_ID)
2042 {
2043 shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_VertexID), 0.0, 0.0, 0.0);\n",
2044 index);
2045 return;
2046 }
2047 if (e->sysval_semantic == WINED3D_SV_INSTANCE_ID)
2048 {
2049 shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_InstanceID), 0.0, 0.0, 0.0);\n",
2050 index);
2051 return;
2052 }
2053 if (e->sysval_semantic && e->sysval_semantic != WINED3D_SV_POSITION)
2054 FIXME("Unhandled sysval semantic %#x.\n", e->sysval_semantic);
2055
2057 shader_addline(buffer, "layout(location = %u) ", index);
2058
2059 switch (e->component_type)
2060 {
2061 case WINED3D_TYPE_UINT:
2062 shader_glsl_declare_typed_vertex_attribute(buffer, gl_info, "uvec", "uint", index);
2063 break;
2064 case WINED3D_TYPE_INT:
2066 break;
2067
2068 default:
2069 FIXME("Unhandled type %#x.\n", e->component_type);
2070 /* Fall through. */
2072 case WINED3D_TYPE_FLOAT:
2073 shader_addline(buffer, "%s vec4 vs_in%u;\n", get_attribute_keyword(gl_info), index);
2074 break;
2075 }
2076}
2077
2080 struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
2081 const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv)
2082{
2083 const struct wined3d_shader_version *version = &reg_maps->shader_version;
2084 const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args;
2085 const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
2086 const struct wined3d_gl_info *gl_info = context->gl_info;
2087 const struct wined3d_shader_indexable_temp *idx_temp_reg;
2088 unsigned int uniform_block_base, uniform_block_count;
2089 const struct wined3d_shader_lconst *lconst;
2090 const char *prefix;
2091 unsigned int i;
2092 DWORD map;
2093
2094 prefix = shader_glsl_get_prefix(version->type);
2095
2096 /* Prototype the subroutines */
2097 for (i = 0, map = reg_maps->labels; map; map >>= 1, ++i)
2098 {
2099 if (map & 1) shader_addline(buffer, "void subroutine%u();\n", i);
2100 }
2101
2102 /* Declare the constants (aka uniforms) */
2103 if (shader->limits->constant_float > 0)
2104 {
2105 unsigned max_constantsF;
2106
2107 /* Unless the shader uses indirect addressing, always declare the
2108 * maximum array size and ignore that we need some uniforms privately.
2109 * E.g. if GL supports 256 uniforms, and we need 2 for the pos fixup
2110 * and immediate values, still declare VC[256]. If the shader needs
2111 * more uniforms than we have it won't work in any case. If it uses
2112 * less, the compiler will figure out which uniforms are really used
2113 * and strip them out. This allows a shader to use c255 on a dx9 card,
2114 * as long as it doesn't also use all the other constants.
2115 *
2116 * If the shader uses indirect addressing the compiler must assume
2117 * that all declared uniforms are used. In this case, declare only the
2118 * amount that we're assured to have.
2119 *
2120 * Thus we run into problems in these two cases:
2121 * 1) The shader really uses more uniforms than supported.
2122 * 2) The shader uses indirect addressing, less constants than
2123 * supported, but uses a constant index > #supported consts. */
2125 {
2126 /* No indirect addressing here. */
2127 max_constantsF = gl_info->limits.glsl_ps_float_constants;
2128 }
2129 else
2130 {
2131 if (reg_maps->usesrelconstF)
2132 {
2133 /* Subtract the other potential uniforms from the max
2134 * available (bools, ints, and 1 row of projection matrix).
2135 * Subtract another uniform for immediate values, which have
2136 * to be loaded via uniform by the driver as well. The shader
2137 * code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex
2138 * shader code, so one vec4 should be enough. (Unfortunately
2139 * the Nvidia driver doesn't store 128 and -128 in one float).
2140 *
2141 * Writing gl_ClipVertex requires one uniform for each
2142 * clipplane as well. */
2143 max_constantsF = gl_info->limits.glsl_vs_float_constants - 3;
2144 if (vs_args->clip_enabled)
2145 max_constantsF -= gl_info->limits.user_clip_distances;
2146 max_constantsF -= wined3d_popcount(reg_maps->integer_constants);
2147 /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
2148 * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
2149 * for now take this into account when calculating the number of available constants
2150 */
2151 max_constantsF -= wined3d_popcount(reg_maps->boolean_constants);
2152 /* Set by driver quirks in directx.c */
2153 max_constantsF -= gl_info->reserved_glsl_constants;
2154
2155 if (max_constantsF < shader->limits->constant_float)
2156 {
2157 static unsigned int once;
2158
2159 if (!once++)
2160 ERR_(winediag)("The hardware does not support enough uniform components to run this shader,"
2161 " it may not render correctly.\n");
2162 else
2163 WARN("The hardware does not support enough uniform components to run this shader.\n");
2164 }
2165 }
2166 else
2167 {
2168 max_constantsF = gl_info->limits.glsl_vs_float_constants;
2169 }
2170 }
2171 max_constantsF = min(shader->limits->constant_float, max_constantsF);
2172 shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF);
2173 }
2174
2175 /* Always declare the full set of constants, the compiler can remove the
2176 * unused ones because d3d doesn't (yet) support indirect int and bool
2177 * constant addressing. This avoids problems if the app uses e.g. i0 and i9. */
2178 if (shader->limits->constant_int > 0 && reg_maps->integer_constants)
2179 shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits->constant_int);
2180
2181 if (shader->limits->constant_bool > 0 && reg_maps->boolean_constants)
2182 shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits->constant_bool);
2183
2184 /* Declare immediate constant buffer */
2185 if (reg_maps->icb)
2186 shader_addline(buffer, "uniform vec4 %s_icb[%u];\n", prefix, reg_maps->icb->vec4_count);
2187
2188 /* Declare constant buffers */
2190 &uniform_block_base, &uniform_block_count);
2191 for (i = 0; i < min(uniform_block_count, WINED3D_MAX_CBS); ++i)
2192 {
2193 if (reg_maps->cb_sizes[i])
2194 {
2195 shader_addline(buffer, "layout(std140");
2197 shader_addline(buffer, ", binding = %u", uniform_block_base + i);
2198 shader_addline(buffer, ") uniform block_%s_cb%u { vec4 %s_cb%u[%u]; };\n",
2199 prefix, i, prefix, i, reg_maps->cb_sizes[i]);
2200 }
2201 }
2202
2203 /* Declare texture samplers */
2204 for (i = 0; i < reg_maps->sampler_map.count; ++i)
2205 {
2207 const char *sampler_type_prefix, *sampler_type;
2208 BOOL shadow_sampler, tex_rect;
2209
2210 entry = &reg_maps->sampler_map.entries[i];
2211
2212 if (entry->resource_idx >= ARRAY_SIZE(reg_maps->resource_info))
2213 {
2214 ERR("Invalid resource index %u.\n", entry->resource_idx);
2215 continue;
2216 }
2217
2218 switch (reg_maps->resource_info[entry->resource_idx].data_type)
2219 {
2220 case WINED3D_DATA_FLOAT:
2221 case WINED3D_DATA_UNORM:
2222 case WINED3D_DATA_SNORM:
2223 sampler_type_prefix = "";
2224 break;
2225
2226 case WINED3D_DATA_INT:
2227 sampler_type_prefix = "i";
2228 break;
2229
2230 case WINED3D_DATA_UINT:
2231 sampler_type_prefix = "u";
2232 break;
2233
2234 default:
2235 sampler_type_prefix = "";
2236 ERR("Unhandled resource data type %#x.\n", reg_maps->resource_info[i].data_type);
2237 break;
2238 }
2239
2240 shadow_sampler = glsl_is_shadow_sampler(shader, ps_args, entry->resource_idx, entry->sampler_idx);
2241 switch (reg_maps->resource_info[entry->resource_idx].type)
2242 {
2244 sampler_type = "samplerBuffer";
2245 break;
2246
2248 if (shadow_sampler)
2249 sampler_type = "sampler1DShadow";
2250 else
2251 sampler_type = "sampler1D";
2252 break;
2253
2255 tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL
2256 && (ps_args->np2_fixup & (1u << entry->resource_idx))
2257 && gl_info->supported[ARB_TEXTURE_RECTANGLE];
2258 if (shadow_sampler)
2259 {
2260 if (tex_rect)
2261 sampler_type = "sampler2DRectShadow";
2262 else
2263 sampler_type = "sampler2DShadow";
2264 }
2265 else
2266 {
2267 if (tex_rect)
2268 sampler_type = "sampler2DRect";
2269 else
2270 sampler_type = "sampler2D";
2271 }
2272 break;
2273
2275 if (shadow_sampler)
2276 FIXME("Unsupported 3D shadow sampler.\n");
2277 sampler_type = "sampler3D";
2278 break;
2279
2281 if (shadow_sampler)
2282 sampler_type = "samplerCubeShadow";
2283 else
2284 sampler_type = "samplerCube";
2285 break;
2286
2288 if (shadow_sampler)
2289 sampler_type = "sampler1DArrayShadow";
2290 else
2291 sampler_type = "sampler1DArray";
2292 break;
2293
2295 if (shadow_sampler)
2296 sampler_type = "sampler2DArrayShadow";
2297 else
2298 sampler_type = "sampler2DArray";
2299 break;
2300
2302 if (shadow_sampler)
2303 sampler_type = "samplerCubeArrayShadow";
2304 else
2305 sampler_type = "samplerCubeArray";
2306 break;
2307
2309 sampler_type = "sampler2DMS";
2310 break;
2311
2313 sampler_type = "sampler2DMSArray";
2314 break;
2315
2316 default:
2317 sampler_type = "unsupported_sampler";
2318 FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[entry->resource_idx].type);
2319 break;
2320 }
2321
2324 shader_addline(buffer, "uniform %s%s %s_sampler%u;\n",
2325 sampler_type_prefix, sampler_type, prefix, entry->bind_idx);
2326 }
2327
2328 /* Declare images */
2329 for (i = 0; i < ARRAY_SIZE(reg_maps->uav_resource_info); ++i)
2330 {
2331 const char *image_type_prefix, *image_type, *read_format;
2332
2333 if (!reg_maps->uav_resource_info[i].type)
2334 continue;
2335
2336 switch (reg_maps->uav_resource_info[i].data_type)
2337 {
2338 case WINED3D_DATA_FLOAT:
2339 case WINED3D_DATA_UNORM:
2340 case WINED3D_DATA_SNORM:
2341 image_type_prefix = "";
2342 read_format = "r32f";
2343 break;
2344
2345 case WINED3D_DATA_INT:
2346 image_type_prefix = "i";
2347 read_format = "r32i";
2348 break;
2349
2350 case WINED3D_DATA_UINT:
2351 image_type_prefix = "u";
2352 read_format = "r32ui";
2353 break;
2354
2355 default:
2356 image_type_prefix = "";
2357 read_format = "";
2358 ERR("Unhandled resource data type %#x.\n", reg_maps->uav_resource_info[i].data_type);
2359 break;
2360 }
2361
2362 switch (reg_maps->uav_resource_info[i].type)
2363 {
2365 image_type = "imageBuffer";
2366 break;
2367
2369 image_type = "image2D";
2370 break;
2371
2373 image_type = "image3D";
2374 break;
2375
2377 image_type = "image2DArray";
2378 break;
2379
2380 default:
2381 image_type = "unsupported_image";
2382 FIXME("Unhandled resource type %#x.\n", reg_maps->uav_resource_info[i].type);
2383 break;
2384 }
2385
2387 shader_addline(buffer, "layout(binding = %u)\n", i);
2388 if (reg_maps->uav_read_mask & (1u << i))
2389 shader_addline(buffer, "layout(%s) uniform %s%s %s_image%u;\n",
2390 read_format, image_type_prefix, image_type, prefix, i);
2391 else
2392 shader_addline(buffer, "writeonly uniform %s%s %s_image%u;\n",
2393 image_type_prefix, image_type, prefix, i);
2394
2395 if (reg_maps->uav_counter_mask & (1u << i))
2396 shader_addline(buffer, "layout(binding = %u) uniform atomic_uint %s_counter%u;\n",
2397 i, prefix, i);
2398 }
2399
2400 /* Declare address variables */
2401 for (i = 0, map = reg_maps->address; map; map >>= 1, ++i)
2402 {
2403 if (map & 1) shader_addline(buffer, "ivec4 A%u;\n", i);
2404 }
2405
2406 /* Declare output register temporaries */
2407 if (shader->limits->packed_output)
2408 shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits->packed_output);
2409
2410 /* Declare temporary variables */
2411 if (reg_maps->temporary_count)
2412 {
2413 for (i = 0; i < reg_maps->temporary_count; ++i)
2414 shader_addline(buffer, "vec4 R%u;\n", i);
2415 }
2416 else if (version->major < 4)
2417 {
2418 for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
2419 {
2420 if (map & 1)
2421 shader_addline(buffer, "vec4 R%u;\n", i);
2422 }
2423 }
2424
2425 /* Declare indexable temporary variables */
2427 {
2428 if (idx_temp_reg->component_count != 4)
2429 FIXME("Ignoring component count %u.\n", idx_temp_reg->component_count);
2430 shader_addline(buffer, "vec4 X%u[%u];\n", idx_temp_reg->register_idx, idx_temp_reg->register_size);
2431 }
2432
2433 /* Declare loop registers aLx */
2434 if (version->major < 4)
2435 {
2436 for (i = 0; i < reg_maps->loop_depth; ++i)
2437 {
2438 shader_addline(buffer, "int aL%u;\n", i);
2439 shader_addline(buffer, "int tmpInt%u;\n", i);
2440 }
2441 }
2442
2443 /* Temporary variables for matrix operations */
2444 shader_addline(buffer, "vec4 tmp0;\n");
2445 shader_addline(buffer, "vec4 tmp1;\n");
2446
2447 if (!shader->load_local_constsF)
2448 {
2449 LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
2450 {
2451 shader_addline(buffer, "const vec4 %s_lc%u = ", prefix, lconst->idx);
2452 shader_glsl_append_imm_vec4(buffer, (const float *)lconst->value);
2453 shader_addline(buffer, ";\n");
2454 }
2455 }
2456}
2457
2458/* Prototypes */
2459static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
2460 const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src);
2461
2463static const char * const shift_glsl_tab[] = {
2464 "", /* 0 (none) */
2465 "2.0 * ", /* 1 (x2) */
2466 "4.0 * ", /* 2 (x4) */
2467 "8.0 * ", /* 3 (x8) */
2468 "16.0 * ", /* 4 (x16) */
2469 "32.0 * ", /* 5 (x32) */
2470 "", /* 6 (x64) */
2471 "", /* 7 (x128) */
2472 "", /* 8 (d256) */
2473 "", /* 9 (d128) */
2474 "", /* 10 (d64) */
2475 "", /* 11 (d32) */
2476 "0.0625 * ", /* 12 (d16) */
2477 "0.125 * ", /* 13 (d8) */
2478 "0.25 * ", /* 14 (d4) */
2479 "0.5 * " /* 15 (d2) */
2480};
2481
2482/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
2484 const char *in_reg, const char *in_regswizzle, char *out_str)
2485{
2486 switch (src_modifier)
2487 {
2488 case WINED3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
2489 case WINED3DSPSM_DW:
2490 case WINED3DSPSM_NONE:
2491 sprintf(out_str, "%s%s", in_reg, in_regswizzle);
2492 break;
2493 case WINED3DSPSM_NEG:
2494 sprintf(out_str, "-%s%s", in_reg, in_regswizzle);
2495 break;
2496 case WINED3DSPSM_NOT:
2497 sprintf(out_str, "!%s%s", in_reg, in_regswizzle);
2498 break;
2499 case WINED3DSPSM_BIAS:
2500 sprintf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle);
2501 break;
2503 sprintf(out_str, "-(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle);
2504 break;
2505 case WINED3DSPSM_SIGN:
2506 sprintf(out_str, "(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle);
2507 break;
2509 sprintf(out_str, "-(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle);
2510 break;
2511 case WINED3DSPSM_COMP:
2512 sprintf(out_str, "(1.0 - %s%s)", in_reg, in_regswizzle);
2513 break;
2514 case WINED3DSPSM_X2:
2515 sprintf(out_str, "(2.0 * %s%s)", in_reg, in_regswizzle);
2516 break;
2517 case WINED3DSPSM_X2NEG:
2518 sprintf(out_str, "-(2.0 * %s%s)", in_reg, in_regswizzle);
2519 break;
2520 case WINED3DSPSM_ABS:
2521 sprintf(out_str, "abs(%s%s)", in_reg, in_regswizzle);
2522 break;
2523 case WINED3DSPSM_ABSNEG:
2524 sprintf(out_str, "-abs(%s%s)", in_reg, in_regswizzle);
2525 break;
2526 default:
2527 FIXME("Unhandled modifier %u\n", src_modifier);
2528 sprintf(out_str, "%s%s", in_reg, in_regswizzle);
2529 }
2530}
2531
2532static void shader_glsl_fixup_scalar_register_variable(char *register_name,
2533 const char *glsl_variable, const struct wined3d_gl_info *gl_info)
2534{
2535 /* The ARB_shading_language_420pack extension allows swizzle operations on
2536 * scalars. */
2538 sprintf(register_name, "%s", glsl_variable);
2539 else
2540 sprintf(register_name, "ivec2(%s, 0)", glsl_variable);
2541}
2542
2546 enum wined3d_data_type data_type, char *register_name, BOOL *is_color,
2547 const struct wined3d_shader_instruction *ins)
2548{
2549 /* oPos, oFog and oPts in D3D */
2550 static const char * const hwrastout_reg_names[] = {"vs_out[10]", "vs_out[11].x", "vs_out[11].y"};
2551
2552 const struct wined3d_shader *shader = ins->ctx->shader;
2553 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
2554 const struct wined3d_shader_version *version = &reg_maps->shader_version;
2555 const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
2556 const char *prefix = shader_glsl_get_prefix(version->type);
2557 struct glsl_src_param rel_param0, rel_param1;
2558 char imm_str[4][17];
2559
2560 if (reg->idx[0].offset != ~0U && reg->idx[0].rel_addr)
2561 shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param0);
2562 if (reg->idx[1].offset != ~0U && reg->idx[1].rel_addr)
2563 shader_glsl_add_src_param(ins, reg->idx[1].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param1);
2564 *is_color = FALSE;
2565
2566 switch (reg->type)
2567 {
2568 case WINED3DSPR_TEMP:
2569 sprintf(register_name, "R%u", reg->idx[0].offset);
2570 break;
2571
2572 case WINED3DSPR_INPUT:
2575 {
2576 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
2577
2578 if (reg->idx[0].rel_addr)
2579 FIXME("VS3 input registers relative addressing.\n");
2580 if (priv->cur_vs_args->swizzle_map & (1u << reg->idx[0].offset))
2581 *is_color = TRUE;
2582 if (reg->idx[0].rel_addr)
2583 {
2584 sprintf(register_name, "%s_in[%s + %u]",
2585 prefix, rel_param0.param_str, reg->idx[0].offset);
2586 }
2587 else
2588 {
2589 sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset);
2590 }
2591 break;
2592 }
2593
2597 {
2598 if (reg->idx[0].rel_addr)
2599 {
2600 if (reg->idx[1].rel_addr)
2601 sprintf(register_name, "shader_in[%s + %u].reg[%s + %u]",
2602 rel_param0.param_str, reg->idx[0].offset,
2603 rel_param1.param_str, reg->idx[1].offset);
2604 else
2605 sprintf(register_name, "shader_in[%s + %u].reg[%u]",
2606 rel_param0.param_str, reg->idx[0].offset,
2607 reg->idx[1].offset);
2608 }
2609 else if (reg->idx[1].rel_addr)
2610 sprintf(register_name, "shader_in[%u].reg[%s + %u]", reg->idx[0].offset,
2611 rel_param1.param_str, reg->idx[1].offset);
2612 else
2613 sprintf(register_name, "shader_in[%u].reg[%u]",
2614 reg->idx[0].offset, reg->idx[1].offset);
2615 break;
2616 }
2617
2618 /* pixel shaders >= 3.0 */
2619 if (version->major >= 3)
2620 {
2621 DWORD idx = shader->u.ps.input_reg_map[reg->idx[0].offset];
2622 unsigned int in_count = vec4_varyings(version->major, gl_info);
2623
2624 if (reg->idx[0].rel_addr)
2625 {
2626 /* Removing a + 0 would be an obvious optimization, but
2627 * OS X doesn't see the NOP operation there. */
2628 if (idx)
2629 {
2630 if (needs_legacy_glsl_syntax(gl_info)
2631 && shader->u.ps.declared_in_count > in_count)
2632 {
2633 sprintf(register_name,
2634 "((%s + %u) > %u ? (%s + %u) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s + %u])",
2635 rel_param0.param_str, idx, in_count - 1, rel_param0.param_str, idx, in_count,
2636 prefix, rel_param0.param_str, idx);
2637 }
2638 else
2639 {
2640 sprintf(register_name, "%s_in[%s + %u]", prefix, rel_param0.param_str, idx);
2641 }
2642 }
2643 else
2644 {
2645 if (needs_legacy_glsl_syntax(gl_info)
2646 && shader->u.ps.declared_in_count > in_count)
2647 {
2648 sprintf(register_name, "((%s) > %u ? (%s) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s])",
2649 rel_param0.param_str, in_count - 1, rel_param0.param_str, in_count,
2650 prefix, rel_param0.param_str);
2651 }
2652 else
2653 {
2654 sprintf(register_name, "%s_in[%s]", prefix, rel_param0.param_str);
2655 }
2656 }
2657 }
2658 else
2659 {
2660 if (idx == in_count) sprintf(register_name, "gl_Color");
2661 else if (idx == in_count + 1) sprintf(register_name, "gl_SecondaryColor");
2662 else sprintf(register_name, "%s_in[%u]", prefix, idx);
2663 }
2664 }
2665 else
2666 {
2667 if (!reg->idx[0].offset)
2668 strcpy(register_name, "ffp_varying_diffuse");
2669 else
2670 strcpy(register_name, "ffp_varying_specular");
2671 break;
2672 }
2673 break;
2674
2675 case WINED3DSPR_CONST:
2676 {
2677 /* Relative addressing */
2678 if (reg->idx[0].rel_addr)
2679 {
2681 sprintf(register_name, "(%s + %u >= 0 && %s + %u < %u ? %s_c[%s + %u] : vec4(0.0))",
2682 rel_param0.param_str, reg->idx[0].offset,
2683 rel_param0.param_str, reg->idx[0].offset, shader->limits->constant_float,
2684 prefix, rel_param0.param_str, reg->idx[0].offset);
2685 else if (reg->idx[0].offset)
2686 sprintf(register_name, "%s_c[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset);
2687 else
2688 sprintf(register_name, "%s_c[%s]", prefix, rel_param0.param_str);
2689 }
2690 else
2691 {
2692 if (shader_constant_is_local(shader, reg->idx[0].offset))
2693 sprintf(register_name, "%s_lc%u", prefix, reg->idx[0].offset);
2694 else
2695 sprintf(register_name, "%s_c[%u]", prefix, reg->idx[0].offset);
2696 }
2697 }
2698 break;
2699
2701 sprintf(register_name, "%s_i[%u]", prefix, reg->idx[0].offset);
2702 break;
2703
2705 sprintf(register_name, "%s_b[%u]", prefix, reg->idx[0].offset);
2706 break;
2707
2708 case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
2710 sprintf(register_name, "T%u", reg->idx[0].offset);
2711 else
2712 sprintf(register_name, "A%u", reg->idx[0].offset);
2713 break;
2714
2715 case WINED3DSPR_LOOP:
2716 sprintf(register_name, "aL%u", ins->ctx->state->current_loop_reg - 1);
2717 break;
2718
2719 case WINED3DSPR_SAMPLER:
2720 sprintf(register_name, "%s_sampler%u", prefix, reg->idx[0].offset);
2721 break;
2722
2724 /* FIXME: should check dual_buffers when dual blending is enabled */
2725 if (reg->idx[0].offset >= gl_info->limits.buffers)
2726 WARN("Write to render target %u, only %d supported.\n",
2727 reg->idx[0].offset, gl_info->limits.buffers);
2728
2729 sprintf(register_name, needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[%u]" : "ps_out%u",
2730 reg->idx[0].offset);
2731 break;
2732
2733 case WINED3DSPR_RASTOUT:
2734 sprintf(register_name, "%s", hwrastout_reg_names[reg->idx[0].offset]);
2735 break;
2736
2740 sprintf(register_name, "gl_FragDepth");
2741 break;
2742
2743 case WINED3DSPR_ATTROUT:
2744 if (!reg->idx[0].offset)
2745 sprintf(register_name, "%s_out[8]", prefix);
2746 else
2747 sprintf(register_name, "%s_out[9]", prefix);
2748 break;
2749
2751 /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
2752 if (reg->idx[0].rel_addr)
2753 sprintf(register_name, "%s_out[%s + %u]",
2754 prefix, rel_param0.param_str, reg->idx[0].offset);
2755 else
2756 sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset);
2757 break;
2758
2760 if (!reg->idx[0].offset)
2761 {
2762 /* vPos */
2763 sprintf(register_name, "vpos");
2764 }
2765 else if (reg->idx[0].offset == 1)
2766 {
2767 /* Note that gl_FrontFacing is a bool, while vFace is
2768 * a float for which the sign determines front/back */
2769 sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
2770 }
2771 else
2772 {
2773 FIXME("Unhandled misctype register %u.\n", reg->idx[0].offset);
2774 sprintf(register_name, "unrecognized_register");
2775 }
2776 break;
2777
2779 switch (reg->immconst_type)
2780 {
2782 switch (data_type)
2783 {
2784 case WINED3D_DATA_FLOAT:
2785 if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
2786 sprintf(register_name, "uintBitsToFloat(%#xu)", reg->u.immconst_data[0]);
2787 else
2788 wined3d_ftoa(*(const float *)reg->u.immconst_data, register_name);
2789 break;
2790 case WINED3D_DATA_INT:
2791 sprintf(register_name, "%#x", reg->u.immconst_data[0]);
2792 break;
2795 case WINED3D_DATA_UINT:
2796 sprintf(register_name, "%#xu", reg->u.immconst_data[0]);
2797 break;
2798 default:
2799 sprintf(register_name, "<unhandled data type %#x>", data_type);
2800 break;
2801 }
2802 break;
2803
2805 switch (data_type)
2806 {
2807 case WINED3D_DATA_FLOAT:
2808 if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
2809 {
2810 sprintf(register_name, "uintBitsToFloat(uvec4(%#xu, %#xu, %#xu, %#xu))",
2811 reg->u.immconst_data[0], reg->u.immconst_data[1],
2812 reg->u.immconst_data[2], reg->u.immconst_data[3]);
2813 }
2814 else
2815 {
2816 wined3d_ftoa(*(const float *)&reg->u.immconst_data[0], imm_str[0]);
2817 wined3d_ftoa(*(const float *)&reg->u.immconst_data[1], imm_str[1]);
2818 wined3d_ftoa(*(const float *)&reg->u.immconst_data[2], imm_str[2]);
2819 wined3d_ftoa(*(const float *)&reg->u.immconst_data[3], imm_str[3]);
2820 sprintf(register_name, "vec4(%s, %s, %s, %s)",
2821 imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
2822 }
2823 break;
2824 case WINED3D_DATA_INT:
2825 sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
2826 reg->u.immconst_data[0], reg->u.immconst_data[1],
2827 reg->u.immconst_data[2], reg->u.immconst_data[3]);
2828 break;
2831 case WINED3D_DATA_UINT:
2832 sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
2833 reg->u.immconst_data[0], reg->u.immconst_data[1],
2834 reg->u.immconst_data[2], reg->u.immconst_data[3]);
2835 break;
2836 default:
2837 sprintf(register_name, "<unhandled data type %#x>", data_type);
2838 break;
2839 }
2840 break;
2841
2842 default:
2843 FIXME("Unhandled immconst type %#x\n", reg->immconst_type);
2844 sprintf(register_name, "<unhandled_immconst_type %#x>", reg->immconst_type);
2845 }
2846 break;
2847
2849 if (reg->idx[1].rel_addr)
2850 sprintf(register_name, "%s_cb%u[%s + %u]",
2851 prefix, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset);
2852 else
2853 sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx[0].offset, reg->idx[1].offset);
2854 break;
2855
2857 if (reg->idx[0].rel_addr)
2858 sprintf(register_name, "%s_icb[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset);
2859 else
2860 sprintf(register_name, "%s_icb[%u]", prefix, reg->idx[0].offset);
2861 break;
2862
2863 case WINED3DSPR_PRIMID:
2865 sprintf(register_name, "gl_PrimitiveIDIn");
2866 else
2867 sprintf(register_name, "gl_PrimitiveID");
2868 break;
2869
2870 case WINED3DSPR_IDXTEMP:
2871 if (reg->idx[1].rel_addr)
2872 sprintf(register_name, "X%u[%s + %u]", reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset);
2873 else
2874 sprintf(register_name, "X%u[%u]", reg->idx[0].offset, reg->idx[1].offset);
2875 break;
2876
2879 "int(gl_LocalInvocationIndex)", gl_info);
2880 break;
2881
2885 "gl_InvocationID", gl_info);
2886 break;
2887
2889 sprintf(register_name, "ivec3(gl_GlobalInvocationID)");
2890 break;
2891
2893 sprintf(register_name, "ivec3(gl_WorkGroupID)");
2894 break;
2895
2897 sprintf(register_name, "ivec3(gl_LocalInvocationID)");
2898 break;
2899
2903 "phase_instance_id", gl_info);
2904 break;
2905
2907 sprintf(register_name, "gl_TessCoord");
2908 break;
2909
2911 if (reg->idx[0].rel_addr)
2912 {
2913 if (reg->idx[1].rel_addr)
2914 sprintf(register_name, "shader_out[%s + %u].reg[%s + %u]",
2915 rel_param0.param_str, reg->idx[0].offset,
2916 rel_param1.param_str, reg->idx[1].offset);
2917 else
2918 sprintf(register_name, "shader_out[%s + %u].reg[%u]",
2919 rel_param0.param_str, reg->idx[0].offset,
2920 reg->idx[1].offset);
2921 }
2922 else if (reg->idx[1].rel_addr)
2923 {
2924 sprintf(register_name, "shader_out[%u].reg[%s + %u]",
2925 reg->idx[0].offset, rel_param1.param_str,
2926 reg->idx[1].offset);
2927 }
2928 else
2929 {
2930 sprintf(register_name, "shader_out[%u].reg[%u]",
2931 reg->idx[0].offset, reg->idx[1].offset);
2932 }
2933 break;
2934
2936 if (version->type == WINED3D_SHADER_TYPE_HULL)
2937 sprintf(register_name, "hs_out[%u]", reg->idx[0].offset);
2938 else
2939 sprintf(register_name, "vpc[%u]", reg->idx[0].offset);
2940 break;
2941
2942 default:
2943 FIXME("Unhandled register type %#x.\n", reg->type);
2944 sprintf(register_name, "unrecognized_register");
2945 break;
2946 }
2947}
2948
2949static void shader_glsl_write_mask_to_str(DWORD write_mask, char *str)
2950{
2951 *str++ = '.';
2952 if (write_mask & WINED3DSP_WRITEMASK_0) *str++ = 'x';
2953 if (write_mask & WINED3DSP_WRITEMASK_1) *str++ = 'y';
2954 if (write_mask & WINED3DSP_WRITEMASK_2) *str++ = 'z';
2955 if (write_mask & WINED3DSP_WRITEMASK_3) *str++ = 'w';
2956 *str = '\0';
2957}
2958
2959/* Get the GLSL write mask for the destination register */
2961{
2962 DWORD mask = param->write_mask;
2963
2964 if (shader_is_scalar(&param->reg))
2965 {
2967 *write_mask = '\0';
2968 }
2969 else
2970 {
2972 }
2973
2974 return mask;
2975}
2976
2977static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask)
2978{
2979 unsigned int size = 0;
2980
2981 if (write_mask & WINED3DSP_WRITEMASK_0) ++size;
2982 if (write_mask & WINED3DSP_WRITEMASK_1) ++size;
2983 if (write_mask & WINED3DSP_WRITEMASK_2) ++size;
2984 if (write_mask & WINED3DSP_WRITEMASK_3) ++size;
2985
2986 return size;
2987}
2988
2990 unsigned int component_idx)
2991{
2992 /* swizzle bits fields: wwzzyyxx */
2993 return (swizzle >> (2 * component_idx)) & 0x3;
2994}
2995
2997{
2998 /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
2999 * but addressed as "rgba". To fix this we need to swap the register's x
3000 * and z components. */
3001 const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
3002 unsigned int i;
3003
3004 *str++ = '.';
3005 for (i = 0; i < 4; ++i)
3006 {
3007 if (mask & (WINED3DSP_WRITEMASK_0 << i))
3008 *str++ = swizzle_chars[shader_glsl_swizzle_get_component(swizzle, i)];
3009 }
3010 *str = '\0';
3011}
3012
3014 BOOL fixup, DWORD mask, char *swizzle_str)
3015{
3016 if (shader_is_scalar(&param->reg))
3017 *swizzle_str = '\0';
3018 else
3019 shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
3020}
3021
3022static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param,
3023 enum wined3d_data_type dst_data_type, enum wined3d_data_type src_data_type)
3024{
3025 if (dst_data_type == src_data_type)
3026 {
3027 string_buffer_sprintf(dst_param, "%s", src_param);
3028 return;
3029 }
3030
3031 if (src_data_type == WINED3D_DATA_FLOAT)
3032 {
3033 switch (dst_data_type)
3034 {
3035 case WINED3D_DATA_INT:
3036 string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
3037 return;
3040 case WINED3D_DATA_UINT:
3041 string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
3042 return;
3043 default:
3044 break;
3045 }
3046 }
3047
3048 if (src_data_type == WINED3D_DATA_UINT && dst_data_type == WINED3D_DATA_FLOAT)
3049 {
3050 string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param);
3051 return;
3052 }
3053
3054 if (src_data_type == WINED3D_DATA_INT && dst_data_type == WINED3D_DATA_FLOAT)
3055 {
3056 string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param);
3057 return;
3058 }
3059
3060 FIXME("Unhandled cast from %#x to %#x.\n", src_data_type, dst_data_type);
3061 string_buffer_sprintf(dst_param, "%s", src_param);
3062}
3063
3064/* From a given parameter token, generate the corresponding GLSL string.
3065 * Also, return the actual register name and swizzle in case the
3066 * caller needs this information as well. */
3068 const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src,
3069 enum wined3d_data_type data_type)
3070{
3071 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
3073 enum wined3d_data_type param_data_type;
3074 BOOL is_color = FALSE;
3075 char swizzle_str[6];
3076
3077 glsl_src->reg_name[0] = '\0';
3078 glsl_src->param_str[0] = '\0';
3079 swizzle_str[0] = '\0';
3080
3081 shader_glsl_get_register_name(&wined3d_src->reg, data_type, glsl_src->reg_name, &is_color, ins);
3082 shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str);
3083
3084 switch (wined3d_src->reg.type)
3085 {
3087 param_data_type = data_type;
3088 break;
3095 case WINED3DSPR_PRIMID:
3098 param_data_type = WINED3D_DATA_INT;
3099 break;
3100 default:
3101 param_data_type = WINED3D_DATA_FLOAT;
3102 break;
3103 }
3104
3105 shader_glsl_sprintf_cast(reg_name, glsl_src->reg_name, data_type, param_data_type);
3106 shader_glsl_gen_modifier(wined3d_src->modifiers, reg_name->buffer, swizzle_str, glsl_src->param_str);
3107
3109}
3110
3112 const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src)
3113{
3114 shader_glsl_add_src_param_ext(ins, wined3d_src, mask, glsl_src, wined3d_src->reg.data_type);
3115}
3116
3117/* From a given parameter token, generate the corresponding GLSL string.
3118 * Also, return the actual register name and swizzle in case the
3119 * caller needs this information as well. */
3121 const struct wined3d_shader_dst_param *wined3d_dst, struct glsl_dst_param *glsl_dst)
3122{
3123 BOOL is_color = FALSE;
3124
3125 glsl_dst->mask_str[0] = '\0';
3126 glsl_dst->reg_name[0] = '\0';
3127
3128 shader_glsl_get_register_name(&wined3d_dst->reg, wined3d_dst->reg.data_type,
3129 glsl_dst->reg_name, &is_color, ins);
3130 return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
3131}
3132
3133/* Append the destination part of the instruction to the buffer, return the effective write mask */
3135 const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst,
3136 enum wined3d_data_type data_type)
3137{
3138 struct glsl_dst_param glsl_dst;
3139 DWORD mask;
3140
3141 if ((mask = shader_glsl_add_dst_param(ins, dst, &glsl_dst)))
3142 {
3143 switch (data_type)
3144 {
3145 case WINED3D_DATA_FLOAT:
3146 shader_addline(buffer, "%s%s = %s(",
3147 glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
3148 break;
3149 case WINED3D_DATA_INT:
3150 shader_addline(buffer, "%s%s = %sintBitsToFloat(",
3151 glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
3152 break;
3155 case WINED3D_DATA_UINT:
3156 shader_addline(buffer, "%s%s = %suintBitsToFloat(",
3157 glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
3158 break;
3159 default:
3160 FIXME("Unhandled data type %#x.\n", data_type);
3161 shader_addline(buffer, "%s%s = %s(",
3162 glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
3163 break;
3164 }
3165 }
3166
3167 return mask;
3168}
3169
3170/* Append the destination part of the instruction to the buffer, return the effective write mask */
3172{
3173 return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
3174}
3175
3178{
3179 struct glsl_dst_param dst_param;
3180 DWORD modifiers;
3181
3182 if (!ins->dst_count) return;
3183
3184 modifiers = ins->dst[0].modifiers;
3185 if (!modifiers) return;
3186
3187 shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
3188
3189 if (modifiers & WINED3DSPDM_SATURATE)
3190 {
3191 /* _SAT means to clamp the value of the register to between 0 and 1 */
3192 shader_addline(ins->ctx->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
3193 dst_param.mask_str, dst_param.reg_name, dst_param.mask_str);
3194 }
3195
3196 if (modifiers & WINED3DSPDM_MSAMPCENTROID)
3197 {
3198 FIXME("_centroid modifier not handled\n");
3199 }
3200
3201 if (modifiers & WINED3DSPDM_PARTIALPRECISION)
3202 {
3203 /* MSDN says this modifier can be safely ignored, so that's what we'll do. */
3204 }
3205}
3206
3208{
3209 switch (op)
3210 {
3211 case WINED3D_SHADER_REL_OP_GT: return ">";
3212 case WINED3D_SHADER_REL_OP_EQ: return "==";
3213 case WINED3D_SHADER_REL_OP_GE: return ">=";
3214 case WINED3D_SHADER_REL_OP_LT: return "<";
3215 case WINED3D_SHADER_REL_OP_NE: return "!=";
3216 case WINED3D_SHADER_REL_OP_LE: return "<=";
3217 default:
3218 FIXME("Unrecognized operator %#x.\n", op);
3219 return "(\?\?)";
3220 }
3221}
3222
3224{
3225 return shader_glsl_get_version(gl_info) >= 130 || gl_info->supported[EXT_GPU_SHADER4];
3226}
3227
3229 unsigned int *coord_size, unsigned int *deriv_size)
3230{
3232 || resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY;
3233
3234 *coord_size = resource_type_info[resource_type].coord_size;
3235 *deriv_size = *coord_size;
3236 if (is_array)
3237 --(*deriv_size);
3238}
3239
3241 DWORD resource_idx, DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function)
3242{
3243 enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
3244 struct shader_glsl_ctx_priv *priv = ctx->backend_data;
3245 const struct wined3d_gl_info *gl_info = ctx->gl_info;
3246 BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
3247 BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx);
3249 BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
3250 && priv->cur_ps_args->np2_fixup & (1u << resource_idx)
3251 && gl_info->supported[ARB_TEXTURE_RECTANGLE];
3255 const char *base = "texture", *type_part = "", *suffix = "";
3256 unsigned int coord_size, deriv_size;
3257
3258 sample_function->data_type = ctx->reg_maps->resource_info[resource_idx].data_type;
3259 sample_function->emulate_lod = WINED3D_SHADER_RESOURCE_NONE;
3260
3261 if (resource_type >= ARRAY_SIZE(resource_type_info))
3262 {
3263 ERR("Unexpected resource type %#x.\n", resource_type);
3264 resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
3265 }
3266
3267 /* Note that there's no such thing as a projected cube texture. */
3268 if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
3269 projected = FALSE;
3270
3271 if (shadow && lod)
3272 {
3273 switch (resource_type)
3274 {
3275 /* emulate textureLod(sampler2DArrayShadow, ...) using textureGradOffset */
3277 sample_function->emulate_lod = resource_type;
3278 grad = offset = TRUE;
3279 lod = FALSE;
3280 break;
3281
3282 /* emulate textureLod(samplerCubeShadow, ...) using shadowCubeGrad */
3284 sample_function->emulate_lod = resource_type;
3285 grad = legacy_syntax = TRUE;
3286 lod = FALSE;
3287 break;
3288
3289 default:
3290 break;
3291 }
3292 }
3293
3294 if (legacy_syntax)
3295 {
3296 if (shadow)
3297 base = "shadow";
3298
3299 type_part = resource_type_info[resource_type].type_part;
3300 if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2D && texrect)
3301 type_part = "2DRect";
3302 if (!type_part[0] && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY)
3303 FIXME("Unhandled resource type %#x.\n", resource_type);
3304
3305 if (!lod && grad && !shader_glsl_has_core_grad(gl_info))
3306 {
3307 if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
3308 suffix = "ARB";
3309 else
3310 FIXME("Unsupported grad function.\n");
3311 }
3312 }
3313
3315 {
3316 static const DWORD texel_fetch_flags = WINED3D_GLSL_SAMPLE_LOAD | WINED3D_GLSL_SAMPLE_OFFSET;
3317 if (flags & ~texel_fetch_flags)
3318 ERR("Unexpected flags %#x for texelFetch.\n", flags & ~texel_fetch_flags);
3319
3320 base = "texelFetch";
3321 type_part = "";
3322 }
3323
3324 sample_function->name = string_buffer_get(priv->string_buffers);
3325 string_buffer_sprintf(sample_function->name, "%s%s%s%s%s%s", base, type_part, projected ? "Proj" : "",
3326 lod ? "Lod" : grad ? "Grad" : "", offset ? "Offset" : "", suffix);
3327
3328 shader_glsl_get_coord_size(resource_type, &coord_size, &deriv_size);
3329 if (shadow)
3330 ++coord_size;
3331 sample_function->offset_size = offset ? deriv_size : 0;
3332 sample_function->coord_mask = (1u << coord_size) - 1;
3333 sample_function->deriv_mask = (1u << deriv_size) - 1;
3334 sample_function->output_single_component = shadow && !legacy_syntax;
3335}
3336
3338 struct glsl_sample_function *sample_function)
3339{
3340 const struct shader_glsl_ctx_priv *priv = ctx->backend_data;
3341
3342 string_buffer_release(priv->string_buffers, sample_function->name);
3343}
3344
3345static void shader_glsl_append_fixup_arg(char *arguments, const char *reg_name,
3346 BOOL sign_fixup, enum fixup_channel_source channel_source)
3347{
3348 switch(channel_source)
3349 {
3351 strcat(arguments, "0.0");
3352 break;
3353
3354 case CHANNEL_SOURCE_ONE:
3355 strcat(arguments, "1.0");
3356 break;
3357
3358 case CHANNEL_SOURCE_X:
3359 strcat(arguments, reg_name);
3360 strcat(arguments, ".x");
3361 break;
3362
3363 case CHANNEL_SOURCE_Y:
3364 strcat(arguments, reg_name);
3365 strcat(arguments, ".y");
3366 break;
3367
3368 case CHANNEL_SOURCE_Z:
3369 strcat(arguments, reg_name);
3370 strcat(arguments, ".z");
3371 break;
3372
3373 case CHANNEL_SOURCE_W:
3374 strcat(arguments, reg_name);
3375 strcat(arguments, ".w");
3376 break;
3377
3378 default:
3379 FIXME("Unhandled channel source %#x\n", channel_source);
3380 strcat(arguments, "undefined");
3381 break;
3382 }
3383
3384 if (sign_fixup) strcat(arguments, " * 2.0 - 1.0");
3385}
3386
3388 const char *reg_name, DWORD mask, struct color_fixup_desc fixup)
3389{
3390 unsigned int mask_size, remaining;
3391 DWORD fixup_mask = 0;
3392 char arguments[256];
3393 char mask_str[6];
3394
3395 if (fixup.x_sign_fixup || fixup.x_source != CHANNEL_SOURCE_X) fixup_mask |= WINED3DSP_WRITEMASK_0;
3396 if (fixup.y_sign_fixup || fixup.y_source != CHANNEL_SOURCE_Y) fixup_mask |= WINED3DSP_WRITEMASK_1;
3397 if (fixup.z_sign_fixup || fixup.z_source != CHANNEL_SOURCE_Z) fixup_mask |= WINED3DSP_WRITEMASK_2;
3398 if (fixup.w_sign_fixup || fixup.w_source != CHANNEL_SOURCE_W) fixup_mask |= WINED3DSP_WRITEMASK_3;
3399 if (!(mask &= fixup_mask))
3400 return;
3401
3402 if (is_complex_fixup(fixup))
3403 {
3405 FIXME("Complex fixup (%#x) not supported\n",complex_fixup);
3406 return;
3407 }
3408
3411
3412 arguments[0] = '\0';
3413 remaining = mask_size;
3415 {
3417 if (--remaining) strcat(arguments, ", ");
3418 }
3420 {
3422 if (--remaining) strcat(arguments, ", ");
3423 }
3425 {
3427 if (--remaining) strcat(arguments, ", ");
3428 }
3430 {
3432 if (--remaining) strcat(arguments, ", ");
3433 }
3434
3435 if (mask_size > 1)
3436 shader_addline(buffer, "%s%s = vec%u(%s);\n", reg_name, mask_str, mask_size, arguments);
3437 else
3438 shader_addline(buffer, "%s%s = %s;\n", reg_name, mask_str, arguments);
3439}
3440
3442{
3443 char reg_name[256];
3444 BOOL is_color;
3445
3446 shader_glsl_get_register_name(&ins->dst[0].reg, ins->dst[0].reg.data_type, reg_name, &is_color, ins);
3447 shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name, ins->dst[0].write_mask, fixup);
3448}
3449
3450static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
3451 unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, DWORD swizzle,
3453 const char *coord_reg_fmt, ...)
3454{
3455 static const struct wined3d_shader_texel_offset dummy_offset = {0, 0, 0};
3456 const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
3457 char dst_swizzle[6];
3458 struct color_fixup_desc fixup;
3459 BOOL np2_fixup = FALSE;
3460 va_list args;
3461 int ret;
3462
3463 shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
3464
3465 /* If ARB_texture_swizzle is supported we don't need to do anything here.
3466 * We actually rely on it for vertex shaders and SM4+. */
3467 if (version->type == WINED3D_SHADER_TYPE_PIXEL && version->major < 4)
3468 {
3469 const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
3470 fixup = priv->cur_ps_args->color_fixup[sampler_bind_idx];
3471
3472 if (priv->cur_ps_args->np2_fixup & (1u << sampler_bind_idx))
3473 np2_fixup = TRUE;
3474 }
3475 else
3476 {
3477 fixup = COLOR_FIXUP_IDENTITY;
3478 }
3479
3480 shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], sample_function->data_type);
3481
3482 if (sample_function->output_single_component)
3483 shader_addline(ins->ctx->buffer, "vec4(");
3484
3485 shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ",
3486 sample_function->name->buffer, shader_glsl_get_prefix(version->type), sampler_bind_idx);
3487
3488 for (;;)
3489 {
3490 va_start(args, coord_reg_fmt);
3491 ret = shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args);
3492 va_end(args);
3493 if (!ret)
3494 break;
3495 if (!string_buffer_resize(ins->ctx->buffer, ret))
3496 break;
3497 }
3498
3499 if (np2_fixup)
3500 {
3501 const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
3502 const unsigned char idx = priv->cur_np2fixup_info->idx[sampler_bind_idx];
3503
3504 switch (shader_glsl_get_write_mask_size(sample_function->coord_mask))
3505 {
3506 case 1:
3507 shader_addline(ins->ctx->buffer, " * ps_samplerNP2Fixup[%u].%s",
3508 idx >> 1, (idx % 2) ? "z" : "x");
3509 break;
3510 case 2:
3511 shader_addline(ins->ctx->buffer, " * ps_samplerNP2Fixup[%u].%s",
3512 idx >> 1, (idx % 2) ? "zw" : "xy");
3513 break;
3514 case 3:
3515 shader_addline(ins->ctx->buffer, " * vec3(ps_samplerNP2Fixup[%u].%s, 1.0)",
3516 idx >> 1, (idx % 2) ? "zw" : "xy");
3517 break;
3518 case 4:
3519 shader_addline(ins->ctx->buffer, " * vec4(ps_samplerNP2Fixup[%u].%s, 1.0, 1.0)",
3520 idx >> 1, (idx % 2) ? "zw" : "xy");
3521 break;
3522 }
3523 }
3524 if (sample_function->emulate_lod)
3525 {
3526 if (strcmp(bias, "0")) FIXME("Don't know how to emulate lod level %s\n", bias);
3527 switch (sample_function->emulate_lod)
3528 {
3530 if (!dx) dx = "vec2(0.0, 0.0)";
3531 if (!dy) dy = "vec2(0.0, 0.0)";
3532 break;
3533
3535 if (!dx) dx = "vec3(0.0, 0.0, 0.0)";
3536 if (!dy) dy = "vec3(0.0, 0.0, 0.0)";
3537 break;
3538
3539 default:
3540 break;
3541 }
3542 if (!offset) offset = &dummy_offset;
3543 }
3544 if (dx && dy)
3545 shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
3546 else if (bias)
3547 shader_addline(ins->ctx->buffer, ", %s", bias);
3548 if (sample_function->offset_size)
3549 {
3550 int offset_immdata[4] = {offset->u, offset->v, offset->w};
3551 shader_addline(ins->ctx->buffer, ", ");
3552 shader_glsl_append_imm_ivec(ins->ctx->buffer, offset_immdata, sample_function->offset_size);
3553 }
3554 shader_addline(ins->ctx->buffer, ")");
3555
3556 if (sample_function->output_single_component)
3557 shader_addline(ins->ctx->buffer, ")");
3558
3559 shader_addline(ins->ctx->buffer, "%s);\n", dst_swizzle);
3560
3561 if (!is_identity_fixup(fixup))
3562 shader_glsl_color_correction(ins, fixup);
3563}
3564
3566{
3567 /* Write the final position.
3568 *
3569 * OpenGL coordinates specify the center of the pixel while D3D coords
3570 * specify the corner. The offsets are stored in z and w in
3571 * pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering
3572 * upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow
3573 * a MAD. */
3574 shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
3575 shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
3576
3577 /* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix()
3578 * in utils.c
3579 *
3580 * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However,
3581 * shaders are run before the homogeneous divide, so we have to take the w
3582 * into account: z = ((z / w) * 2 - 1) * w, which is the same as
3583 * z = z * 2 - w. */
3584 shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n");
3585}
3586
3587/*****************************************************************************
3588 * Begin processing individual instruction opcodes
3589 ****************************************************************************/
3590
3591static void shader_glsl_binop(const struct wined3d_shader_instruction *ins)
3592{
3593 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3594 struct glsl_src_param src0_param;
3595 struct glsl_src_param src1_param;
3596 DWORD write_mask;
3597 const char *op;
3598
3599 /* Determine the GLSL operator to use based on the opcode */
3600 switch (ins->handler_idx)
3601 {
3602 case WINED3DSIH_ADD: op = "+"; break;
3603 case WINED3DSIH_AND: op = "&"; break;
3604 case WINED3DSIH_DIV: op = "/"; break;
3605 case WINED3DSIH_IADD: op = "+"; break;
3606 case WINED3DSIH_ISHL: op = "<<"; break;
3607 case WINED3DSIH_ISHR: op = ">>"; break;
3608 case WINED3DSIH_MUL: op = "*"; break;
3609 case WINED3DSIH_OR: op = "|"; break;
3610 case WINED3DSIH_SUB: op = "-"; break;
3611 case WINED3DSIH_USHR: op = ">>"; break;
3612 case WINED3DSIH_XOR: op = "^"; break;
3613 default:
3614 op = "<unhandled operator>";
3615 FIXME("Opcode %s not yet handled in GLSL.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
3616 break;
3617 }
3618
3619 write_mask = shader_glsl_append_dst(buffer, ins);
3620 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3621 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3622 shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str);
3623}
3624
3625static void shader_glsl_relop(const struct wined3d_shader_instruction *ins)
3626{
3627 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3628 struct glsl_src_param src0_param;
3629 struct glsl_src_param src1_param;
3630 unsigned int mask_size;
3631 DWORD write_mask;
3632 const char *op;
3633
3634 write_mask = shader_glsl_append_dst(buffer, ins);
3635 mask_size = shader_glsl_get_write_mask_size(write_mask);
3636 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3637 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3638
3639 if (mask_size > 1)
3640 {
3641 switch (ins->handler_idx)
3642 {
3643 case WINED3DSIH_EQ: op = "equal"; break;
3644 case WINED3DSIH_IEQ: op = "equal"; break;
3645 case WINED3DSIH_GE: op = "greaterThanEqual"; break;
3646 case WINED3DSIH_IGE: op = "greaterThanEqual"; break;
3647 case WINED3DSIH_UGE: op = "greaterThanEqual"; break;
3648 case WINED3DSIH_LT: op = "lessThan"; break;
3649 case WINED3DSIH_ILT: op = "lessThan"; break;
3650 case WINED3DSIH_ULT: op = "lessThan"; break;
3651 case WINED3DSIH_NE: op = "notEqual"; break;
3652 case WINED3DSIH_INE: op = "notEqual"; break;
3653 default:
3654 op = "<unhandled operator>";
3655 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
3656 break;
3657 }
3658
3659 shader_addline(buffer, "uvec%u(%s(%s, %s)) * 0xffffffffu);\n",
3660 mask_size, op, src0_param.param_str, src1_param.param_str);
3661 }
3662 else
3663 {
3664 switch (ins->handler_idx)
3665 {
3666 case WINED3DSIH_EQ: op = "=="; break;
3667 case WINED3DSIH_IEQ: op = "=="; break;
3668 case WINED3DSIH_GE: op = ">="; break;
3669 case WINED3DSIH_IGE: op = ">="; break;
3670 case WINED3DSIH_UGE: op = ">="; break;
3671 case WINED3DSIH_LT: op = "<"; break;
3672 case WINED3DSIH_ILT: op = "<"; break;
3673 case WINED3DSIH_ULT: op = "<"; break;
3674 case WINED3DSIH_NE: op = "!="; break;
3675 case WINED3DSIH_INE: op = "!="; break;
3676 default:
3677 op = "<unhandled operator>";
3678 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
3679 break;
3680 }
3681
3682 shader_addline(buffer, "%s %s %s ? 0xffffffffu : 0u);\n",
3683 src0_param.param_str, op, src1_param.param_str);
3684 }
3685}
3686
3688{
3689 struct glsl_src_param src_param;
3690 DWORD write_mask;
3691 const char *op;
3692
3693 switch (ins->handler_idx)
3694 {
3695 case WINED3DSIH_INEG: op = "-"; break;
3696 case WINED3DSIH_NOT: op = "~"; break;
3697 default:
3698 op = "<unhandled operator>";
3699 ERR("Unhandled opcode %s.\n",
3701 break;
3702 }
3703
3704 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
3705 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
3706 shader_addline(ins->ctx->buffer, "%s%s);\n", op, src_param.param_str);
3707}
3708
3710{
3711 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3712 struct glsl_src_param src0_param;
3713 struct glsl_src_param src1_param;
3714 DWORD write_mask;
3715
3716 /* If we have ARB_gpu_shader5, we can use imulExtended() / umulExtended().
3717 * If not, we can emulate it. */
3718 if (ins->dst[0].reg.type != WINED3DSPR_NULL)
3719 FIXME("64-bit integer multiplies not implemented.\n");
3720
3721 if (ins->dst[1].reg.type != WINED3DSPR_NULL)
3722 {
3723 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
3724 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3725 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3726
3727 shader_addline(ins->ctx->buffer, "%s * %s);\n",
3728 src0_param.param_str, src1_param.param_str);
3729 }
3730}
3731
3732static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
3733{
3734 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3735 struct glsl_src_param src0_param, src1_param;
3736 DWORD write_mask;
3737
3738 if (ins->dst[0].reg.type != WINED3DSPR_NULL)
3739 {
3740 if (ins->dst[1].reg.type != WINED3DSPR_NULL)
3741 {
3742 char dst_mask[6];
3743
3744 write_mask = shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
3745 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3746 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3747 shader_addline(buffer, "tmp0%s = uintBitsToFloat(%s / %s);\n",
3748 dst_mask, src0_param.param_str, src1_param.param_str);
3749
3750 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
3751 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3752 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3753 shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str);
3754
3756 shader_addline(buffer, "tmp0%s);\n", dst_mask);
3757 }
3758 else
3759 {
3760 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
3761 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3762 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3763 shader_addline(buffer, "%s / %s);\n", src0_param.param_str, src1_param.param_str);
3764 }
3765 }
3766 else if (ins->dst[1].reg.type != WINED3DSPR_NULL)
3767 {
3768 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
3769 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3770 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
3771 shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str);
3772 }
3773}
3774
3775/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
3776static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
3777{
3778 const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
3779 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3780 struct glsl_src_param src0_param;
3781 DWORD write_mask;
3782
3783 write_mask = shader_glsl_append_dst(buffer, ins);
3784 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
3785
3786 /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
3787 * shader versions WINED3DSIO_MOVA is used for this. */
3788 if (ins->ctx->reg_maps->shader_version.major == 1
3789 && ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_VERTEX
3790 && ins->dst[0].reg.type == WINED3DSPR_ADDR)
3791 {
3792 /* This is a simple floor() */
3793 unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
3794 if (mask_size > 1) {
3795 shader_addline(buffer, "ivec%d(floor(%s)));\n", mask_size, src0_param.param_str);
3796 } else {
3797 shader_addline(buffer, "int(floor(%s)));\n", src0_param.param_str);
3798 }
3799 }
3800 else if (ins->handler_idx == WINED3DSIH_MOVA)
3801 {
3802 unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
3803
3804 if (shader_glsl_get_version(gl_info) >= 130 || gl_info->supported[EXT_GPU_SHADER4])
3805 {
3806 if (mask_size > 1)
3807 shader_addline(buffer, "ivec%d(round(%s)));\n", mask_size, src0_param.param_str);
3808 else
3809 shader_addline(buffer, "int(round(%s)));\n", src0_param.param_str);
3810 }
3811 else
3812 {
3813 if (mask_size > 1)
3814 shader_addline(buffer, "ivec%d(floor(abs(%s) + vec%d(0.5)) * sign(%s)));\n",
3815 mask_size, src0_param.param_str, mask_size, src0_param.param_str);
3816 else
3817 shader_addline(buffer, "int(floor(abs(%s) + 0.5) * sign(%s)));\n",
3818 src0_param.param_str, src0_param.param_str);
3819 }
3820 }
3821 else
3822 {
3823 shader_addline(buffer, "%s);\n", src0_param.param_str);
3824 }
3825}
3826
3827/* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
3828static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
3829{
3830 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3831 struct glsl_src_param src0_param;
3832 struct glsl_src_param src1_param;
3833 DWORD dst_write_mask, src_write_mask;
3834 unsigned int dst_size;
3835
3836 dst_write_mask = shader_glsl_append_dst(buffer, ins);
3837 dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
3838
3839 /* dp4 works on vec4, dp3 on vec3, etc. */
3840 if (ins->handler_idx == WINED3DSIH_DP4)
3841 src_write_mask = WINED3DSP_WRITEMASK_ALL;
3842 else if (ins->handler_idx == WINED3DSIH_DP3)
3844 else
3846
3847 shader_glsl_add_src_param(ins, &ins->src[0], src_write_mask, &src0_param);
3848 shader_glsl_add_src_param(ins, &ins->src[1], src_write_mask, &src1_param);
3849
3850 if (dst_size > 1) {
3851 shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
3852 } else {
3853 shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str);
3854 }
3855}
3856
3857/* Note that this instruction has some restrictions. The destination write mask
3858 * can't contain the w component, and the source swizzles have to be .xyzw */
3859static void shader_glsl_cross(const struct wined3d_shader_instruction *ins)
3860{
3862 struct glsl_src_param src0_param;
3863 struct glsl_src_param src1_param;
3864 char dst_mask[6];
3865
3866 shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
3867 shader_glsl_append_dst(ins->ctx->buffer, ins);
3868 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
3869 shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
3870 shader_addline(ins->ctx->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
3871}
3872
3873static void shader_glsl_cut(const struct wined3d_shader_instruction *ins)
3874{
3875 unsigned int stream = ins->handler_idx == WINED3DSIH_CUT ? 0 : ins->src[0].reg.idx[0].offset;
3876
3877 if (!stream)
3878 shader_addline(ins->ctx->buffer, "EndPrimitive();\n");
3879 else
3880 FIXME("Unhandled primitive stream %u.\n", stream);
3881}
3882
3883/* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
3884 * Src0 and src1 are scalars. Note that D3D uses the absolute of src0, while
3885 * GLSL uses the value as-is. */
3886static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
3887{
3888 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3889 struct glsl_src_param src0_param;
3890 struct glsl_src_param src1_param;
3891 DWORD dst_write_mask;
3892 unsigned int dst_size;
3893
3894 dst_write_mask = shader_glsl_append_dst(buffer, ins);
3895 dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
3896
3897 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
3898 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
3899
3900 if (dst_size > 1)
3901 {
3902 shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n",
3903 dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str);
3904 }
3905 else
3906 {
3907 shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n",
3908 src1_param.param_str, src0_param.param_str, src1_param.param_str);
3909 }
3910}
3911
3912/* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
3914{
3915 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
3916 struct glsl_src_param src_param;
3917 const char *instruction;
3918 DWORD write_mask;
3919 unsigned i;
3920
3921 /* Determine the GLSL function to use based on the opcode */
3922 /* TODO: Possibly make this a table for faster lookups */
3923 switch (ins->handler_idx)
3924 {
3925 case WINED3DSIH_ABS: instruction = "abs"; break;
3926 case WINED3DSIH_BFREV: instruction = "bitfieldReverse"; break;
3927 case WINED3DSIH_COUNTBITS: instruction = "bitCount"; break;
3928 case WINED3DSIH_DSX: instruction = "dFdx"; break;
3929 case WINED3DSIH_DSX_COARSE: instruction = "dFdxCoarse"; break;
3930 case WINED3DSIH_DSX_FINE: instruction = "dFdxFine"; break;
3931 case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break;
3932 case WINED3DSIH_DSY_COARSE: instruction = "ycorrection.y * dFdyCoarse"; break;
3933 case WINED3DSIH_DSY_FINE: instruction = "ycorrection.y * dFdyFine"; break;
3934 case WINED3DSIH_FIRSTBIT_HI: instruction = "findMSB"; break;
3935 case WINED3DSIH_FIRSTBIT_LO: instruction = "findLSB"; break;
3936 case WINED3DSIH_FIRSTBIT_SHI: instruction = "findMSB"; break;
3937 case WINED3DSIH_FRC: instruction = "fract"; break;
3938 case WINED3DSIH_IMAX: instruction = "max"; break;
3939 case WINED3DSIH_IMIN: instruction = "min"; break;
3940 case WINED3DSIH_MAX: instruction = "max"; break;
3941 case WINED3DSIH_MIN: instruction = "min"; break;
3942 case WINED3DSIH_ROUND_NE: instruction = "roundEven"; break;
3943 case WINED3DSIH_ROUND_NI: instruction = "floor"; break;
3944 case WINED3DSIH_ROUND_PI: instruction = "ceil"; break;
3945 case WINED3DSIH_ROUND_Z: instruction = "trunc"; break;
3946 case WINED3DSIH_SQRT: instruction = "sqrt"; break;
3947 case WINED3DSIH_UMAX: instruction = "max"; break;
3948 case WINED3DSIH_UMIN: instruction = "min"; break;
3949 default: instruction = "";
3950 ERR("Opcode %s not yet handled in GLSL.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
3951 break;
3952 }
3953
3954 write_mask = shader_glsl_append_dst(buffer, ins);
3955
3956 /* In D3D bits are numbered from the most significant bit. */
3958 shader_addline(buffer, "31 - ");
3960
3961 if (ins->src_count)
3962 {
3963 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
3964 shader_addline(buffer, "%s", src_param.param_str);
3965 for (i = 1; i < ins->src_count; ++i)
3966 {
3967 shader_glsl_add_src_param(ins, &ins->src[i], write_mask, &src_param);
3968 shader_addline(buffer, ", %s", src_param.param_str);
3969 }
3970 }
3971
3972 shader_addline(buffer, "));\n");
3973}
3974
3976{
3978 struct glsl_src_param src;
3979 DWORD write_mask;
3980 const char *fmt;
3981 unsigned int i;
3982
3984 ? "unpackHalf2x16(%s).x);\n" : "packHalf2x16(vec2(%s, 0.0)));\n";
3985
3986 dst = ins->dst[0];
3987 for (i = 0; i < 4; ++i)
3988 {
3989 dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i);
3990 if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins,
3991 &dst, dst.reg.data_type)))
3992 continue;
3993
3994 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src);
3995 shader_addline(ins->ctx->buffer, fmt, src.param_str);
3996 }
3997}
3998
4000{
4001 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4003 struct glsl_src_param src[4];
4004 const char *instruction;
4005 BOOL tmp_dst = FALSE;
4006 char mask_char[6];
4007 unsigned int i, j;
4008 DWORD write_mask;
4009
4010 switch (ins->handler_idx)
4011 {
4012 case WINED3DSIH_BFI: instruction = "bitfieldInsert"; break;
4013 case WINED3DSIH_IBFE: instruction = "bitfieldExtract"; break;
4014 case WINED3DSIH_UBFE: instruction = "bitfieldExtract"; break;
4015 default:
4016 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
4017 return;
4018 }
4019
4020 for (i = 0; i < ins->src_count; ++i)
4021 {
4022 if (ins->dst[0].reg.idx[0].offset == ins->src[i].reg.idx[0].offset
4023 && ins->dst[0].reg.type == ins->src[i].reg.type)
4024 tmp_dst = TRUE;
4025 }
4026
4027 dst = ins->dst[0];
4028 for (i = 0; i < 4; ++i)
4029 {
4030 dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i);
4031 if (tmp_dst && (write_mask = shader_glsl_get_write_mask(&dst, mask_char)))
4032 shader_addline(buffer, "tmp0%s = %sBitsToFloat(", mask_char,
4033 dst.reg.data_type == WINED3D_DATA_INT ? "int" : "uint");
4034 else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst, dst.reg.data_type)))
4035 continue;
4036
4037 for (j = 0; j < ins->src_count; ++j)
4038 shader_glsl_add_src_param(ins, &ins->src[j], write_mask, &src[j]);
4040 for (j = 0; j < ins->src_count - 2; ++j)
4041 shader_addline(buffer, "%s, ", src[ins->src_count - j - 1].param_str);
4042 shader_addline(buffer, "%s & 0x1f, %s & 0x1f));\n", src[1].param_str, src[0].param_str);
4043 }
4044
4045 if (tmp_dst)
4046 {
4048 shader_glsl_get_write_mask(&ins->dst[0], mask_char);
4049 shader_addline(buffer, "tmp0%s);\n", mask_char);
4050 }
4051}
4052
4053static void shader_glsl_nop(const struct wined3d_shader_instruction *ins) {}
4054
4055static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins)
4056{
4057 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4058 struct glsl_src_param src_param;
4059 unsigned int mask_size;
4060 DWORD write_mask;
4061 char dst_mask[6];
4062
4063 write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask);
4064 mask_size = shader_glsl_get_write_mask_size(write_mask);
4065 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
4066
4067 shader_addline(buffer, "tmp0.x = dot(%s, %s);\n",
4068 src_param.param_str, src_param.param_str);
4070
4071 if (mask_size > 1)
4072 {
4073 shader_addline(buffer, "tmp0.x == 0.0 ? vec%u(0.0) : (%s * inversesqrt(tmp0.x)));\n",
4074 mask_size, src_param.param_str);
4075 }
4076 else
4077 {
4078 shader_addline(buffer, "tmp0.x == 0.0 ? 0.0 : (%s * inversesqrt(tmp0.x)));\n",
4079 src_param.param_str);
4080 }
4081}
4082
4084{
4085 DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
4086 ins->ctx->reg_maps->shader_version.minor);
4087 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4088 struct glsl_src_param src0_param;
4089 const char *prefix, *suffix;
4090 unsigned int dst_size;
4091 DWORD dst_write_mask;
4092
4093 dst_write_mask = shader_glsl_append_dst(buffer, ins);
4094 dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
4095
4096 if (shader_version < WINED3D_SHADER_VERSION(4, 0))
4097 dst_write_mask = WINED3DSP_WRITEMASK_3;
4098
4099 shader_glsl_add_src_param(ins, &ins->src[0], dst_write_mask, &src0_param);
4100
4101 switch (ins->handler_idx)
4102 {
4103 case WINED3DSIH_EXP:
4104 case WINED3DSIH_EXPP:
4105 prefix = "exp2(";
4106 suffix = ")";
4107 break;
4108
4109 case WINED3DSIH_LOG:
4110 case WINED3DSIH_LOGP:
4111 prefix = "log2(abs(";
4112 suffix = "))";
4113 break;
4114
4115 case WINED3DSIH_RCP:
4116 prefix = "1.0 / ";
4117 suffix = "";
4118 break;
4119
4120 case WINED3DSIH_RSQ:
4121 prefix = "inversesqrt(abs(";
4122 suffix = "))";
4123 break;
4124
4125 default:
4126 prefix = "";
4127 suffix = "";
4128 FIXME("Unhandled instruction %#x.\n", ins->handler_idx);
4129 break;
4130 }
4131
4132 if (dst_size > 1 && shader_version < WINED3D_SHADER_VERSION(4, 0))
4133 shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix);
4134 else
4135 shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix);
4136}
4137
4147static void shader_glsl_expp(const struct wined3d_shader_instruction *ins)
4148{
4149 if (ins->ctx->reg_maps->shader_version.major < 2)
4150 {
4151 struct glsl_src_param src_param;
4152 char dst_mask[6];
4153
4154 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
4155
4156 shader_addline(ins->ctx->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
4157 shader_addline(ins->ctx->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
4158 shader_addline(ins->ctx->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str);
4159 shader_addline(ins->ctx->buffer, "tmp0.w = 1.0;\n");
4160
4161 shader_glsl_append_dst(ins->ctx->buffer, ins);
4162 shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
4163 shader_addline(ins->ctx->buffer, "tmp0%s);\n", dst_mask);
4164 return;
4165 }
4166
4168}
4169
4170static void shader_glsl_cast(const struct wined3d_shader_instruction *ins,
4171 const char *vector_constructor, const char *scalar_constructor)
4172{
4173 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4174 struct glsl_src_param src_param;
4175 unsigned int mask_size;
4176 DWORD write_mask;
4177
4178 write_mask = shader_glsl_append_dst(buffer, ins);
4179 mask_size = shader_glsl_get_write_mask_size(write_mask);
4180 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
4181
4182 if (mask_size > 1)
4183 shader_addline(buffer, "%s%u(%s));\n", vector_constructor, mask_size, src_param.param_str);
4184 else
4185 shader_addline(buffer, "%s(%s));\n", scalar_constructor, src_param.param_str);
4186}
4187
4189{
4190 shader_glsl_cast(ins, "ivec", "int");
4191}
4192
4194{
4195 shader_glsl_cast(ins, "uvec", "uint");
4196}
4197
4199{
4200 shader_glsl_cast(ins, "vec", "float");
4201}
4202
4205{
4206 struct glsl_src_param src0_param;
4207 struct glsl_src_param src1_param;
4208 DWORD write_mask;
4209 unsigned int mask_size;
4210
4211 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
4212 mask_size = shader_glsl_get_write_mask_size(write_mask);
4213 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4214 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
4215
4216 if (mask_size > 1) {
4217 const char *compare;
4218
4219 switch(ins->handler_idx)
4220 {
4221 case WINED3DSIH_SLT: compare = "lessThan"; break;
4222 case WINED3DSIH_SGE: compare = "greaterThanEqual"; break;
4223 default: compare = "";
4224 FIXME("Can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
4225 }
4226
4227 shader_addline(ins->ctx->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare,
4228 src0_param.param_str, src1_param.param_str);
4229 } else {
4230 switch(ins->handler_idx)
4231 {
4232 case WINED3DSIH_SLT:
4233 /* Step(src0, src1) is not suitable here because if src0 == src1 SLT is supposed,
4234 * to return 0.0 but step returns 1.0 because step is not < x
4235 * An alternative is a bvec compare padded with an unused second component.
4236 * step(src1 * -1.0, src0 * -1.0) is not an option because it suffers from the same
4237 * issue. Playing with not() is not possible either because not() does not accept
4238 * a scalar.
4239 */
4240 shader_addline(ins->ctx->buffer, "(%s < %s) ? 1.0 : 0.0);\n",
4241 src0_param.param_str, src1_param.param_str);
4242 break;
4243 case WINED3DSIH_SGE:
4244 /* Here we can use the step() function and safe a conditional */
4245 shader_addline(ins->ctx->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
4246 break;
4247 default:
4248 FIXME("Can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
4249 }
4250
4251 }
4252}
4253
4254static void shader_glsl_swapc(const struct wined3d_shader_instruction *ins)
4255{
4256 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4257 struct wined3d_shader_dst_param dst[2];
4258 struct glsl_src_param src[3];
4259 unsigned int i, j, k;
4260 char mask_char[6];
4261 DWORD write_mask;
4262 BOOL tmp_dst[2];
4263
4264 for (i = 0; i < ins->dst_count; ++i)
4265 {
4266 tmp_dst[i] = FALSE;
4267 for (j = 0; j < ins->src_count; ++j)
4268 {
4269 if (ins->dst[i].reg.idx[0].offset == ins->src[j].reg.idx[0].offset
4270 && ins->dst[i].reg.type == ins->src[j].reg.type)
4271 tmp_dst[i] = TRUE;
4272 }
4273 }
4274
4275 dst[0] = ins->dst[0];
4276 dst[1] = ins->dst[1];
4277 for (i = 0; i < 4; ++i)
4278 {
4279 for (j = 0; j < ARRAY_SIZE(dst); ++j)
4280 {
4281 dst[j].write_mask = ins->dst[j].write_mask & (WINED3DSP_WRITEMASK_0 << i);
4282 if (tmp_dst[j] && (write_mask = shader_glsl_get_write_mask(&dst[j], mask_char)))
4283 shader_addline(buffer, "tmp%u%s = (", j, mask_char);
4284 else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst[j], dst[j].reg.data_type)))
4285 continue;
4286
4287 for (k = 0; k < ARRAY_SIZE(src); ++k)
4288 shader_glsl_add_src_param(ins, &ins->src[k], write_mask, &src[k]);
4289
4290 shader_addline(buffer, "%sbool(%s) ? %s : %s);\n", !j ? "!" : "",
4291 src[0].param_str, src[1].param_str, src[2].param_str);
4292 }
4293 }
4294
4295 for (i = 0; i < ARRAY_SIZE(tmp_dst); ++i)
4296 {
4297 if (tmp_dst[i])
4298 {
4299 shader_glsl_get_write_mask(&ins->dst[i], mask_char);
4300 shader_glsl_append_dst_ext(buffer, ins, &ins->dst[i], ins->dst[i].reg.data_type);
4301 shader_addline(buffer, "tmp%u%s);\n", i, mask_char);
4302 }
4303 }
4304}
4305
4307{
4308 const char *condition_prefix, *condition_suffix;
4310 struct glsl_src_param src0_param;
4311 struct glsl_src_param src1_param;
4312 struct glsl_src_param src2_param;
4313 BOOL temp_destination = FALSE;
4314 DWORD cmp_channel = 0;
4315 unsigned int i, j;
4316 char mask_char[6];
4317 DWORD write_mask;
4318
4319 switch (ins->handler_idx)
4320 {
4321 case WINED3DSIH_CMP:
4322 condition_prefix = "";
4323 condition_suffix = " >= 0.0";
4324 break;
4325
4326 case WINED3DSIH_CND:
4327 condition_prefix = "";
4328 condition_suffix = " > 0.5";
4329 break;
4330
4331 case WINED3DSIH_MOVC:
4332 condition_prefix = "bool(";
4333 condition_suffix = ")";
4334 break;
4335
4336 default:
4337 FIXME("Unhandled instruction %#x.\n", ins->handler_idx);
4338 condition_prefix = "<unhandled prefix>";
4339 condition_suffix = "<unhandled suffix>";
4340 break;
4341 }
4342
4343 if (shader_is_scalar(&ins->dst[0].reg) || shader_is_scalar(&ins->src[0].reg))
4344 {
4345 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
4346 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4347 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
4348 shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
4349
4350 shader_addline(ins->ctx->buffer, "%s%s%s ? %s : %s);\n",
4351 condition_prefix, src0_param.param_str, condition_suffix,
4352 src1_param.param_str, src2_param.param_str);
4353 return;
4354 }
4355
4356 dst = ins->dst[0];
4357
4358 /* Splitting the instruction up in multiple lines imposes a problem:
4359 * The first lines may overwrite source parameters of the following lines.
4360 * Deal with that by using a temporary destination register if needed. */
4361 if ((ins->src[0].reg.idx[0].offset == dst.reg.idx[0].offset
4362 && ins->src[0].reg.type == dst.reg.type)
4363 || (ins->src[1].reg.idx[0].offset == dst.reg.idx[0].offset
4364 && ins->src[1].reg.type == dst.reg.type)
4365 || (ins->src[2].reg.idx[0].offset == dst.reg.idx[0].offset
4366 && ins->src[2].reg.type == dst.reg.type))
4367 temp_destination = TRUE;
4368
4369 /* Cycle through all source0 channels. */
4370 for (i = 0; i < 4; ++i)
4371 {
4372 write_mask = 0;
4373 /* Find the destination channels which use the current source0 channel. */
4374 for (j = 0; j < 4; ++j)
4375 {
4376 if (shader_glsl_swizzle_get_component(ins->src[0].swizzle, j) == i)
4377 {
4378 write_mask |= WINED3DSP_WRITEMASK_0 << j;
4379 cmp_channel = WINED3DSP_WRITEMASK_0 << j;
4380 }
4381 }
4382 dst.write_mask = ins->dst[0].write_mask & write_mask;
4383
4384 if (temp_destination)
4385 {
4386 if (!(write_mask = shader_glsl_get_write_mask(&dst, mask_char)))
4387 continue;
4388 shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
4389 }
4390 else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst, dst.reg.data_type)))
4391 continue;
4392
4393 shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
4394 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
4395 shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
4396
4397 shader_addline(ins->ctx->buffer, "%s%s%s ? %s : %s);\n",
4398 condition_prefix, src0_param.param_str, condition_suffix,
4399 src1_param.param_str, src2_param.param_str);
4400 }
4401
4402 if (temp_destination)
4403 {
4404 shader_glsl_get_write_mask(&ins->dst[0], mask_char);
4405 shader_glsl_append_dst(ins->ctx->buffer, ins);
4406 shader_addline(ins->ctx->buffer, "tmp0%s);\n", mask_char);
4407 }
4408}
4409
4411/* For ps 1.1-1.3, only a single component of src0 is used. For ps 1.4
4412 * the compare is done per component of src0. */
4413static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
4414{
4415 struct glsl_src_param src0_param;
4416 struct glsl_src_param src1_param;
4417 struct glsl_src_param src2_param;
4418 DWORD write_mask;
4419 DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
4420 ins->ctx->reg_maps->shader_version.minor);
4421
4422 if (shader_version < WINED3D_SHADER_VERSION(1, 4))
4423 {
4424 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
4425 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4426 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
4427 shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
4428
4429 if (ins->coissue && ins->dst->write_mask != WINED3DSP_WRITEMASK_3)
4430 shader_addline(ins->ctx->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
4431 else
4432 shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
4433 src0_param.param_str, src1_param.param_str, src2_param.param_str);
4434 return;
4435 }
4436
4438}
4439
4441static void shader_glsl_mad(const struct wined3d_shader_instruction *ins)
4442{
4443 struct glsl_src_param src0_param;
4444 struct glsl_src_param src1_param;
4445 struct glsl_src_param src2_param;
4446 DWORD write_mask;
4447
4448 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
4449 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4450 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
4451 shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
4452 shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n",
4453 src0_param.param_str, src1_param.param_str, src2_param.param_str);
4454}
4455
4456/* Handles transforming all WINED3DSIO_M?x? opcodes for
4457 Vertex shaders to GLSL codes */
4458static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
4459{
4460 int i;
4461 int nComponents = 0;
4462 struct wined3d_shader_dst_param tmp_dst = {{0}};
4463 struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
4464 struct wined3d_shader_instruction tmp_ins;
4465
4466 memset(&tmp_ins, 0, sizeof(tmp_ins));
4467
4468 /* Set constants for the temporary argument */
4469 tmp_ins.ctx = ins->ctx;
4470 tmp_ins.dst_count = 1;
4471 tmp_ins.dst = &tmp_dst;
4472 tmp_ins.src_count = 2;
4473 tmp_ins.src = tmp_src;
4474
4475 switch(ins->handler_idx)
4476 {
4477 case WINED3DSIH_M4x4:
4478 nComponents = 4;
4479 tmp_ins.handler_idx = WINED3DSIH_DP4;
4480 break;
4481 case WINED3DSIH_M4x3:
4482 nComponents = 3;
4483 tmp_ins.handler_idx = WINED3DSIH_DP4;
4484 break;
4485 case WINED3DSIH_M3x4:
4486 nComponents = 4;
4487 tmp_ins.handler_idx = WINED3DSIH_DP3;
4488 break;
4489 case WINED3DSIH_M3x3:
4490 nComponents = 3;
4491 tmp_ins.handler_idx = WINED3DSIH_DP3;
4492 break;
4493 case WINED3DSIH_M3x2:
4494 nComponents = 2;
4495 tmp_ins.handler_idx = WINED3DSIH_DP3;
4496 break;
4497 default:
4498 break;
4499 }
4500
4501 tmp_dst = ins->dst[0];
4502 tmp_src[0] = ins->src[0];
4503 tmp_src[1] = ins->src[1];
4504 for (i = 0; i < nComponents; ++i)
4505 {
4506 tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
4507 shader_glsl_dot(&tmp_ins);
4508 ++tmp_src[1].reg.idx[0].offset;
4509 }
4510}
4511
4518static void shader_glsl_lrp(const struct wined3d_shader_instruction *ins)
4519{
4520 struct glsl_src_param src0_param;
4521 struct glsl_src_param src1_param;
4522 struct glsl_src_param src2_param;
4523 DWORD write_mask;
4524
4525 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
4526
4527 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4528 shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
4529 shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
4530
4531 shader_addline(ins->ctx->buffer, "mix(%s, %s, %s));\n",
4532 src2_param.param_str, src1_param.param_str, src0_param.param_str);
4533}
4534
4541static void shader_glsl_lit(const struct wined3d_shader_instruction *ins)
4542{
4543 struct glsl_src_param src0_param;
4544 struct glsl_src_param src1_param;
4545 struct glsl_src_param src3_param;
4546 char dst_mask[6];
4547
4548 shader_glsl_append_dst(ins->ctx->buffer, ins);
4549 shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
4550
4551 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4552 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src1_param);
4553 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src3_param);
4554
4555 /* The sdk specifies the instruction like this
4556 * dst.x = 1.0;
4557 * if(src.x > 0.0) dst.y = src.x
4558 * else dst.y = 0.0.
4559 * if(src.x > 0.0 && src.y > 0.0) dst.z = pow(src.y, power);
4560 * else dst.z = 0.0;
4561 * dst.w = 1.0;
4562 * (where power = src.w clamped between -128 and 128)
4563 *
4564 * Obviously that has quite a few conditionals in it which we don't like. So the first step is this:
4565 * dst.x = 1.0 ... No further explanation needed
4566 * dst.y = max(src.y, 0.0); ... If x < 0.0, use 0.0, otherwise x. Same as the conditional
4567 * dst.z = x > 0.0 ? pow(max(y, 0.0), p) : 0; ... 0 ^ power is 0, and otherwise we use y anyway
4568 * dst.w = 1.0. ... Nothing fancy.
4569 *
4570 * So we still have one conditional in there. So do this:
4571 * dst.z = pow(max(0.0, src.y) * step(0.0, src.x), power);
4572 *
4573 * step(0.0, x) will return 1 if src.x > 0.0, and 0 otherwise. So if y is 0 we get pow(0.0 * 1.0, power),
4574 * which sets dst.z to 0. If y > 0, but x = 0.0, we get pow(y * 0.0, power), which results in 0 too.
4575 * if both x and y are > 0, we get pow(y * 1.0, power), as it is supposed to.
4576 *
4577 * Unfortunately pow(0.0 ^ 0.0) returns NaN on most GPUs, but lit with src.y = 0 and src.w = 0 returns
4578 * a non-NaN value in dst.z. What we return doesn't matter, as long as it is not NaN. Return 0, which is
4579 * what all Windows HW drivers and GL_ARB_vertex_program's LIT do.
4580 */
4581 shader_addline(ins->ctx->buffer,
4582 "vec4(1.0, max(%s, 0.0), %s == 0.0 ? 0.0 : "
4583 "pow(max(0.0, %s) * step(0.0, %s), clamp(%s, -128.0, 128.0)), 1.0)%s);\n",
4584 src0_param.param_str, src3_param.param_str, src1_param.param_str,
4585 src0_param.param_str, src3_param.param_str, dst_mask);
4586}
4587
4594static void shader_glsl_dst(const struct wined3d_shader_instruction *ins)
4595{
4596 struct glsl_src_param src0y_param;
4597 struct glsl_src_param src0z_param;
4598 struct glsl_src_param src1y_param;
4599 struct glsl_src_param src1w_param;
4600 char dst_mask[6];
4601
4602 shader_glsl_append_dst(ins->ctx->buffer, ins);
4603 shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
4604
4605 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src0y_param);
4606 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &src0z_param);
4607 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_1, &src1y_param);
4608 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_3, &src1w_param);
4609
4610 shader_addline(ins->ctx->buffer, "vec4(1.0, %s * %s, %s, %s))%s;\n",
4611 src0y_param.param_str, src1y_param.param_str, src0z_param.param_str, src1w_param.param_str, dst_mask);
4612}
4613
4624{
4625 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4626 struct glsl_src_param src0_param;
4627 DWORD write_mask;
4628
4629 if (ins->ctx->reg_maps->shader_version.major < 4)
4630 {
4631 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4632
4633 write_mask = shader_glsl_append_dst(buffer, ins);
4634 switch (write_mask)
4635 {
4637 shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
4638 break;
4639
4641 shader_addline(buffer, "sin(%s));\n", src0_param.param_str);
4642 break;
4643
4645 shader_addline(buffer, "vec2(cos(%s), sin(%s)));\n",
4646 src0_param.param_str, src0_param.param_str);
4647 break;
4648
4649 default:
4650 ERR("Write mask should be .x, .y or .xy\n");
4651 break;
4652 }
4653
4654 return;
4655 }
4656
4657 if (ins->dst[0].reg.type != WINED3DSPR_NULL)
4658 {
4659
4660 if (ins->dst[1].reg.type != WINED3DSPR_NULL)
4661 {
4662 char dst_mask[6];
4663
4664 write_mask = shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
4665 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4666 shader_addline(buffer, "tmp0%s = sin(%s);\n", dst_mask, src0_param.param_str);
4667
4668 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
4669 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4670 shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
4671
4672 shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
4673 shader_addline(buffer, "tmp0%s);\n", dst_mask);
4674 }
4675 else
4676 {
4677 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type);
4678 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4679 shader_addline(buffer, "sin(%s));\n", src0_param.param_str);
4680 }
4681 }
4682 else if (ins->dst[1].reg.type != WINED3DSPR_NULL)
4683 {
4684 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type);
4685 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4686 shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
4687 }
4688}
4689
4690/* sgn in vs_2_0 has 2 extra parameters(registers for temporary storage) which we don't use
4691 * here. But those extra parameters require a dedicated function for sgn, since map2gl would
4692 * generate invalid code
4693 */
4694static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins)
4695{
4696 struct glsl_src_param src0_param;
4697 DWORD write_mask;
4698
4699 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
4700 shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
4701
4702 shader_addline(ins->ctx->buffer, "sign(%s));\n", src0_param.param_str);
4703}
4704
4710/* FIXME: I don't think nested loops will work correctly this way. */
4711static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
4712{
4713 struct wined3d_shader_parser_state *state = ins->ctx->state;
4714 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
4715 const struct wined3d_shader *shader = ins->ctx->shader;
4716 const struct wined3d_shader_lconst *constant;
4717 struct glsl_src_param src1_param;
4718 const DWORD *control_values = NULL;
4719
4720 if (ins->ctx->reg_maps->shader_version.major < 4)
4721 {
4722 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
4723
4724 /* Try to hardcode the loop control parameters if possible. Direct3D 9
4725 * class hardware doesn't support real varying indexing, but Microsoft
4726 * designed this feature for Shader model 2.x+. If the loop control is
4727 * known at compile time, the GLSL compiler can unroll the loop, and
4728 * replace indirect addressing with direct addressing. */
4729 if (ins->src[1].reg.type == WINED3DSPR_CONSTINT)
4730 {
4732 {
4733 if (constant->idx == ins->src[1].reg.idx[0].offset)
4734 {
4735 control_values = constant->value;
4736 break;
4737 }
4738 }
4739 }
4740
4741 if (control_values)
4742 {
4743 struct wined3d_shader_loop_control loop_control;
4744 loop_control.count = control_values[0];
4745 loop_control.start = control_values[1];
4746 loop_control.step = (int)control_values[2];
4747
4748 if (loop_control.step > 0)
4749 {
4750 shader_addline(buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d)\n{\n",
4751 state->current_loop_depth, loop_control.start,
4752 state->current_loop_depth, loop_control.count, loop_control.step, loop_control.start,
4753 state->current_loop_depth, loop_control.step);
4754 }
4755 else if (loop_control.step < 0)
4756 {
4757 shader_addline(buffer, "for (aL%u = %u; aL%u > (%u * %d + %u); aL%u += %d)\n{\n",
4758 state->current_loop_depth, loop_control.start,
4759 state->current_loop_depth, loop_control.count, loop_control.step, loop_control.start,
4760 state->current_loop_depth, loop_control.step);
4761 }
4762 else
4763 {
4764 shader_addline(buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++)\n{\n",
4765 state->current_loop_depth, loop_control.start, state->current_loop_depth,
4766 state->current_loop_depth, loop_control.count,
4767 state->current_loop_depth);
4768 }
4769 }
4770 else
4771 {
4772 shader_addline(buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z)\n{\n",
4773 state->current_loop_depth, state->current_loop_reg,
4774 src1_param.reg_name, state->current_loop_depth, src1_param.reg_name,
4775 state->current_loop_depth, state->current_loop_reg, src1_param.reg_name);
4776 }
4777
4778 ++state->current_loop_reg;
4779 }
4780 else
4781 {
4782 shader_addline(buffer, "for (;;)\n{\n");
4783 }
4784
4785 ++state->current_loop_depth;
4786}
4787
4788static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
4789{
4790 struct wined3d_shader_parser_state *state = ins->ctx->state;
4791
4792 shader_addline(ins->ctx->buffer, "}\n");
4793
4794 if (ins->handler_idx == WINED3DSIH_ENDLOOP)
4795 {
4796 --state->current_loop_depth;
4797 --state->current_loop_reg;
4798 }
4799
4800 if (ins->handler_idx == WINED3DSIH_ENDREP)
4801 {
4802 --state->current_loop_depth;
4803 }
4804}
4805
4806static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
4807{
4808 struct wined3d_shader_parser_state *state = ins->ctx->state;
4809 const struct wined3d_shader *shader = ins->ctx->shader;
4810 const struct wined3d_shader_lconst *constant;
4811 struct glsl_src_param src0_param;
4812 const DWORD *control_values = NULL;
4813
4814 /* Try to hardcode local values to help the GLSL compiler to unroll and optimize the loop */
4815 if (ins->src[0].reg.type == WINED3DSPR_CONSTINT)
4816 {
4818 {
4819 if (constant->idx == ins->src[0].reg.idx[0].offset)
4820 {
4821 control_values = constant->value;
4822 break;
4823 }
4824 }
4825 }
4826
4827 if (control_values)
4828 {
4829 shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %d; tmpInt%d++) {\n",
4830 state->current_loop_depth, state->current_loop_depth,
4831 control_values[0], state->current_loop_depth);
4832 }
4833 else
4834 {
4835 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4836 shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
4837 state->current_loop_depth, state->current_loop_depth,
4838 src0_param.param_str, state->current_loop_depth);
4839 }
4840
4841 ++state->current_loop_depth;
4842}
4843
4845{
4846 struct glsl_src_param src0_param;
4847
4848 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4849 shader_addline(ins->ctx->buffer, "switch (%s)\n{\n", src0_param.param_str);
4850}
4851
4852static void shader_glsl_case(const struct wined3d_shader_instruction *ins)
4853{
4854 struct glsl_src_param src0_param;
4855
4856 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4857 shader_addline(ins->ctx->buffer, "case %s:\n", src0_param.param_str);
4858}
4859
4861{
4862 shader_addline(ins->ctx->buffer, "default:\n");
4863}
4864
4866 const char *op)
4867{
4868 struct glsl_src_param src_param;
4869 const char *condition;
4870
4871 condition = ins->flags == WINED3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool";
4872 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param);
4873 shader_addline(ins->ctx->buffer, "if (%s(%s)) %s\n", condition, src_param.param_str, op);
4874}
4875
4876static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
4877{
4879}
4880
4881static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
4882{
4883 struct glsl_src_param src0_param;
4884 struct glsl_src_param src1_param;
4885
4886 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4887 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
4888
4889 shader_addline(ins->ctx->buffer, "if (%s %s %s) {\n",
4890 src0_param.param_str, shader_glsl_get_rel_op(ins->flags), src1_param.param_str);
4891}
4892
4893static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
4894{
4895 shader_addline(ins->ctx->buffer, "} else {\n");
4896}
4897
4898static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
4899{
4900 unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset;
4901
4902 shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n");
4903 if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL])
4904 shader_glsl_fixup_position(ins->ctx->buffer);
4905
4906 if (!stream)
4907 shader_addline(ins->ctx->buffer, "EmitVertex();\n");
4908 else
4909 FIXME("Unhandled primitive stream %u.\n", stream);
4910}
4911
4912static void shader_glsl_break(const struct wined3d_shader_instruction *ins)
4913{
4914 shader_addline(ins->ctx->buffer, "break;\n");
4915}
4916
4917/* FIXME: According to MSDN the compare is done per component. */
4919{
4920 struct glsl_src_param src0_param;
4921 struct glsl_src_param src1_param;
4922
4923 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
4924 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
4925
4926 shader_addline(ins->ctx->buffer, "if (%s %s %s) break;\n",
4927 src0_param.param_str, shader_glsl_get_rel_op(ins->flags), src1_param.param_str);
4928}
4929
4931{
4932 const char *op;
4933
4934 switch (ins->handler_idx)
4935 {
4936 case WINED3DSIH_BREAKP: op = "break;"; break;
4937 case WINED3DSIH_CONTINUEP: op = "continue;"; break;
4938 case WINED3DSIH_RETP: op = "return;"; break;
4939 default:
4940 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
4941 return;
4942 }
4943
4945}
4946
4948{
4949 shader_addline(ins->ctx->buffer, "continue;\n");
4950}
4951
4952static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
4953{
4954 shader_addline(ins->ctx->buffer, "}\n");
4955 shader_addline(ins->ctx->buffer, "void subroutine%u()\n{\n", ins->src[0].reg.idx[0].offset);
4956
4957 /* Subroutines appear at the end of the shader. */
4958 ins->ctx->state->in_subroutine = TRUE;
4959}
4960
4961static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
4962{
4963 shader_addline(ins->ctx->buffer, "subroutine%u();\n", ins->src[0].reg.idx[0].offset);
4964}
4965
4967{
4968 struct glsl_src_param src1_param;
4969
4970 shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
4971 shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n",
4972 src1_param.param_str, ins->src[0].reg.idx[0].offset);
4973}
4974
4975static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
4976{
4977 const struct wined3d_shader_version *version = &ins->ctx->shader->reg_maps.shader_version;
4978
4979 if (version->major >= 4 && !ins->ctx->state->in_subroutine)
4980 {
4982 shader_addline(ins->ctx->buffer, "return;\n");
4983 }
4984}
4985
4986static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
4987{
4988 DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
4989 ins->ctx->reg_maps->shader_version.minor);
4990 struct glsl_sample_function sample_function;
4991 DWORD sample_flags = 0;
4992 DWORD resource_idx;
4993 DWORD mask = 0, swizzle;
4994 const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
4995
4996 /* 1.0-1.4: Use destination register as sampler source.
4997 * 2.0+: Use provided sampler source. */
4998 if (shader_version < WINED3D_SHADER_VERSION(2,0))
4999 resource_idx = ins->dst[0].reg.idx[0].offset;
5000 else
5001 resource_idx = ins->src[1].reg.idx[0].offset;
5002
5003 if (shader_version < WINED3D_SHADER_VERSION(1,4))
5004 {
5005 DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
5007 enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type;
5008
5009 /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
5011 {
5012 sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
5014 {
5016 FIXME("WINED3D_TTFF_PROJECTED with WINED3D_TTFF_COUNT1?\n");
5017 break;
5020 break;
5023 break;
5027 break;
5028 }
5029 }
5030 }
5031 else if (shader_version < WINED3D_SHADER_VERSION(2,0))
5032 {
5033 enum wined3d_shader_src_modifier src_mod = ins->src[0].modifiers;
5034
5035 if (src_mod == WINED3DSPSM_DZ) {
5036 sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
5038 } else if (src_mod == WINED3DSPSM_DW) {
5039 sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
5041 }
5042 }
5043 else
5044 {
5045 if ((ins->flags & WINED3DSI_TEXLD_PROJECT)
5046 && ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
5047 {
5048 /* ps 2.0 texldp instruction always divides by the fourth component. */
5049 sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
5051 }
5052 }
5053
5054 shader_glsl_get_sample_function(ins->ctx, resource_idx, resource_idx, sample_flags, &sample_function);
5055 mask |= sample_function.coord_mask;
5056 sample_function.coord_mask = mask;
5057
5058 if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
5059 else swizzle = ins->src[1].swizzle;
5060
5061 /* 1.0-1.3: Use destination register as coordinate source.
5062 1.4+: Use provided coordinate source register. */
5063 if (shader_version < WINED3D_SHADER_VERSION(1,4))
5064 {
5065 char coord_mask[6];
5067 shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL,
5068 "T%u%s", resource_idx, coord_mask);
5069 }
5070 else
5071 {
5072 struct glsl_src_param coord_param;
5073 shader_glsl_add_src_param(ins, &ins->src[0], mask, &coord_param);
5074 if (ins->flags & WINED3DSI_TEXLD_BIAS)
5075 {
5076 struct glsl_src_param bias;
5078 shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
5079 NULL, "%s", coord_param.param_str);
5080 } else {
5081 shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL,
5082 "%s", coord_param.param_str);
5083 }
5084 }
5085 shader_glsl_release_sample_function(ins->ctx, &sample_function);
5086}
5087
5089{
5090 const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
5091 struct glsl_src_param coord_param, dx_param, dy_param;
5092 struct glsl_sample_function sample_function;
5093 DWORD sampler_idx;
5094 DWORD swizzle = ins->src[1].swizzle;
5095
5097 {
5098 FIXME("texldd used, but not supported by hardware. Falling back to regular tex.\n");
5099 shader_glsl_tex(ins);
5100 return;
5101 }
5102
5103 sampler_idx = ins->src[1].reg.idx[0].offset;
5104
5105 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_GRAD, &sample_function);
5106 shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
5107 shader_glsl_add_src_param(ins, &ins->src[2], sample_function.deriv_mask, &dx_param);
5108 shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dy_param);
5109
5110 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str,
5111 NULL, NULL, "%s", coord_param.param_str);
5112 shader_glsl_release_sample_function(ins->ctx, &sample_function);
5113}
5114
5116{
5117 const struct wined3d_shader_version *shader_version = &ins->ctx->reg_maps->shader_version;
5118 const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
5119 struct glsl_src_param coord_param, lod_param;
5120 struct glsl_sample_function sample_function;
5121 DWORD swizzle = ins->src[1].swizzle;
5122 DWORD sampler_idx;
5123
5124 sampler_idx = ins->src[1].reg.idx[0].offset;
5125
5126 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_LOD, &sample_function);
5127 shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
5128
5129 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
5130
5131 if (shader_version->type == WINED3D_SHADER_TYPE_PIXEL && !shader_glsl_has_core_grad(gl_info)
5132 && !gl_info->supported[ARB_SHADER_TEXTURE_LOD])
5133 {
5134 /* Plain GLSL only supports Lod sampling functions in vertex shaders.
5135 * However, the NVIDIA drivers allow them in fragment shaders as well,
5136 * even without the appropriate extension. */
5137 WARN("Using %s in fragment shader.\n", sample_function.name->buffer);
5138 }
5139 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str, NULL,
5140 "%s", coord_param.param_str);
5141 shader_glsl_release_sample_function(ins->ctx, &sample_function);
5142}
5143
5144static unsigned int shader_glsl_find_sampler(const struct wined3d_shader_sampler_map *sampler_map,
5145 unsigned int resource_idx, unsigned int sampler_idx)
5146{
5147 struct wined3d_shader_sampler_map_entry *entries = sampler_map->entries;
5148 unsigned int i;
5149
5150 for (i = 0; i < sampler_map->count; ++i)
5151 {
5152 if (entries[i].resource_idx == resource_idx && entries[i].sampler_idx == sampler_idx)
5153 return entries[i].bind_idx;
5154 }
5155
5156 ERR("No GLSL sampler found for resource %u / sampler %u.\n", resource_idx, sampler_idx);
5157
5158 return ~0u;
5159}
5160
5162{
5163 const BOOL is_imm_instruction = WINED3DSIH_IMM_ATOMIC_AND <= ins->handler_idx
5165 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5166 const struct wined3d_shader_version *version = &reg_maps->shader_version;
5167 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
5168 struct glsl_src_param structure_idx, offset, data, data2;
5169 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5170 enum wined3d_shader_resource_type resource_type;
5172 enum wined3d_data_type data_type;
5173 unsigned int resource_idx, stride;
5174 const char *op, *resource;
5175 DWORD coord_mask;
5176 BOOL is_tgsm;
5177
5178 resource_idx = ins->dst[is_imm_instruction].reg.idx[0].offset;
5179 is_tgsm = ins->dst[is_imm_instruction].reg.type == WINED3DSPR_GROUPSHAREDMEM;
5180 if (is_tgsm)
5181 {
5182 if (resource_idx >= reg_maps->tgsm_count)
5183 {
5184 ERR("Invalid TGSM index %u.\n", resource_idx);
5185 return;
5186 }
5187 resource = "g";
5188 data_type = WINED3D_DATA_UINT;
5189 coord_mask = 1;
5190 stride = reg_maps->tgsm[resource_idx].stride;
5191 }
5192 else
5193 {
5194 if (resource_idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
5195 {
5196 ERR("Invalid UAV index %u.\n", resource_idx);
5197 return;
5198 }
5199 resource_type = reg_maps->uav_resource_info[resource_idx].type;
5200 if (resource_type >= ARRAY_SIZE(resource_type_info))
5201 {
5202 ERR("Unexpected resource type %#x.\n", resource_type);
5203 return;
5204 }
5205 resource = "image";
5206 data_type = reg_maps->uav_resource_info[resource_idx].data_type;
5207 coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1;
5208 stride = reg_maps->uav_resource_info[resource_idx].stride;
5209 }
5210
5211 switch (ins->handler_idx)
5212 {
5215 if (is_tgsm)
5216 op = "atomicAnd";
5217 else
5218 op = "imageAtomicAnd";
5219 break;
5222 if (is_tgsm)
5223 op = "atomicCompSwap";
5224 else
5225 op = "imageAtomicCompSwap";
5226 break;
5229 if (is_tgsm)
5230 op = "atomicAdd";
5231 else
5232 op = "imageAtomicAdd";
5233 break;
5236 if (is_tgsm)
5237 op = "atomicMax";
5238 else
5239 op = "imageAtomicMax";
5240 if (data_type != WINED3D_DATA_INT)
5241 {
5242 FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx);
5243 return;
5244 }
5245 break;
5248 if (is_tgsm)
5249 op = "atomicMin";
5250 else
5251 op = "imageAtomicMin";
5252 if (data_type != WINED3D_DATA_INT)
5253 {
5254 FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx);
5255 return;
5256 }
5257 break;
5260 if (is_tgsm)
5261 op = "atomicOr";
5262 else
5263 op = "imageAtomicOr";
5264 break;
5267 if (is_tgsm)
5268 op = "atomicMax";
5269 else
5270 op = "imageAtomicMax";
5271 if (data_type != WINED3D_DATA_UINT)
5272 {
5273 FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx);
5274 return;
5275 }
5276 break;
5279 if (is_tgsm)
5280 op = "atomicMin";
5281 else
5282 op = "imageAtomicMin";
5283 if (data_type != WINED3D_DATA_UINT)
5284 {
5285 FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx);
5286 return;
5287 }
5288 break;
5291 if (is_tgsm)
5292 op = "atomicXor";
5293 else
5294 op = "imageAtomicXor";
5295 break;
5297 if (is_tgsm)
5298 op = "atomicExchange";
5299 else
5300 op = "imageAtomicExchange";
5301 break;
5302 default:
5303 ERR("Unhandled opcode %#x.\n", ins->handler_idx);
5304 return;
5305 }
5306
5308 if (stride)
5309 {
5310 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &structure_idx);
5312 string_buffer_sprintf(address, "%s * %u + %s / 4", structure_idx.param_str, stride, offset.param_str);
5313 }
5314 else
5315 {
5316 shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &offset);
5317 string_buffer_sprintf(address, "%s", offset.param_str);
5318 if (is_tgsm || (reg_maps->uav_resource_info[resource_idx].flags & WINED3D_VIEW_BUFFER_RAW))
5319 shader_addline(address, "/ 4");
5320 }
5321
5322 if (is_imm_instruction)
5323 shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], data_type);
5324
5325 if (is_tgsm)
5326 shader_addline(buffer, "%s(%s_%s%u[%s], ",
5327 op, shader_glsl_get_prefix(version->type), resource, resource_idx, address->buffer);
5328 else
5329 shader_addline(buffer, "%s(%s_%s%u, %s, ",
5330 op, shader_glsl_get_prefix(version->type), resource, resource_idx, address->buffer);
5331
5332 shader_glsl_add_src_param_ext(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &data, data_type);
5333 shader_addline(buffer, "%s", data.param_str);
5334 if (ins->src_count >= 3)
5335 {
5336 shader_glsl_add_src_param_ext(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &data2, data_type);
5337 shader_addline(buffer, ", %s", data2.param_str);
5338 }
5339
5340 if (is_imm_instruction)
5341 shader_addline(buffer, ")");
5342 shader_addline(buffer, ");\n");
5343
5345}
5346
5348{
5349 const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type);
5350 const char *op;
5351
5353 op = "atomicCounterIncrement";
5354 else
5355 op = "atomicCounterDecrement";
5356
5357 shader_glsl_append_dst(ins->ctx->buffer, ins);
5358 shader_addline(ins->ctx->buffer, "%s(%s_counter%u));\n", op, prefix, ins->src[0].reg.idx[0].offset);
5359}
5360
5362{
5363 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5364 const struct wined3d_shader_version *version = &reg_maps->shader_version;
5365 enum wined3d_shader_resource_type resource_type;
5366 struct glsl_src_param image_coord_param;
5367 enum wined3d_data_type data_type;
5368 DWORD coord_mask, write_mask;
5369 unsigned int uav_idx;
5370 char dst_swizzle[6];
5371
5372 uav_idx = ins->src[1].reg.idx[0].offset;
5373 if (uav_idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
5374 {
5375 ERR("Invalid UAV index %u.\n", uav_idx);
5376 return;
5377 }
5378 resource_type = reg_maps->uav_resource_info[uav_idx].type;
5379 if (resource_type >= ARRAY_SIZE(resource_type_info))
5380 {
5381 ERR("Unexpected resource type %#x.\n", resource_type);
5382 resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
5383 }
5384 data_type = reg_maps->uav_resource_info[uav_idx].data_type;
5385 coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1;
5386
5387 write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], data_type);
5388 shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle);
5389
5390 shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &image_coord_param);
5391 shader_addline(ins->ctx->buffer, "imageLoad(%s_image%u, %s)%s);\n",
5392 shader_glsl_get_prefix(version->type), uav_idx, image_coord_param.param_str, dst_swizzle);
5393}
5394
5396{
5397 const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type);
5398 const struct wined3d_shader_src_param *src = &ins->src[ins->src_count - 1];
5399 unsigned int i, swizzle, resource_idx, bind_idx, stride, src_idx = 0;
5400 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5401 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
5402 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5403 struct glsl_src_param structure_idx, offset;
5406 const char *function, *resource;
5407
5408 resource_idx = src->reg.idx[0].offset;
5409 if (src->reg.type == WINED3DSPR_RESOURCE)
5410 {
5411 if (resource_idx >= ARRAY_SIZE(reg_maps->resource_info))
5412 {
5413 ERR("Invalid resource index %u.\n", resource_idx);
5414 return;
5415 }
5416 stride = reg_maps->resource_info[resource_idx].stride;
5417 bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, WINED3D_SAMPLER_DEFAULT);
5418 function = "texelFetch";
5419 resource = "sampler";
5420 }
5421 else if (src->reg.type == WINED3DSPR_UAV)
5422 {
5423 if (resource_idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
5424 {
5425 ERR("Invalid UAV index %u.\n", resource_idx);
5426 return;
5427 }
5428 stride = reg_maps->uav_resource_info[resource_idx].stride;
5429 bind_idx = resource_idx;
5430 function = "imageLoad";
5431 resource = "image";
5432 }
5433 else
5434 {
5435 if (resource_idx >= reg_maps->tgsm_count)
5436 {
5437 ERR("Invalid TGSM index %u.\n", resource_idx);
5438 return;
5439 }
5440 stride = reg_maps->tgsm[resource_idx].stride;
5441 bind_idx = resource_idx;
5442 function = NULL;
5443 resource = "g";
5444 }
5445
5448 {
5449 shader_glsl_add_src_param(ins, &ins->src[src_idx++], WINED3DSP_WRITEMASK_0, &structure_idx);
5450 shader_addline(address, "%s * %u + ", structure_idx.param_str, stride);
5451 }
5453 shader_addline(address, "%s / 4", offset.param_str);
5454
5455 dst = ins->dst[0];
5456 if (shader_glsl_get_write_mask_size(dst.write_mask) > 1)
5457 {
5458 /* The instruction is split into multiple lines. The first lines may
5459 * overwrite source parameters of the following lines. */
5460 shader_addline(buffer, "tmp0.x = intBitsToFloat(%s);\n", address->buffer);
5461 string_buffer_sprintf(address, "floatBitsToInt(tmp0.x)");
5462 }
5463
5464 for (i = 0; i < 4; ++i)
5465 {
5466 dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i);
5467 if (!shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst, dst.reg.data_type))
5468 continue;
5469
5471 if (function)
5472 shader_addline(buffer, "%s(%s_%s%u, %s + %u).x);\n",
5473 function, prefix, resource, bind_idx, address->buffer, swizzle);
5474 else
5475 shader_addline(buffer, "%s_%s%u[%s + %u]);\n",
5476 prefix, resource, bind_idx, address->buffer, swizzle);
5477 }
5478
5480}
5481
5483{
5484 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5485 const struct wined3d_shader_version *version = &reg_maps->shader_version;
5486 struct glsl_src_param image_coord_param, image_data_param;
5487 enum wined3d_shader_resource_type resource_type;
5488 enum wined3d_data_type data_type;
5489 unsigned int uav_idx;
5490 DWORD coord_mask;
5491
5492 uav_idx = ins->dst[0].reg.idx[0].offset;
5493 if (uav_idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
5494 {
5495 ERR("Invalid UAV index %u.\n", uav_idx);
5496 return;
5497 }
5498 resource_type = reg_maps->uav_resource_info[uav_idx].type;
5499 if (resource_type >= ARRAY_SIZE(resource_type_info))
5500 {
5501 ERR("Unexpected resource type %#x.\n", resource_type);
5502 return;
5503 }
5504 data_type = reg_maps->uav_resource_info[uav_idx].data_type;
5505 coord_mask = (1u << resource_type_info[resource_type].coord_size) - 1;
5506
5507 shader_glsl_add_src_param(ins, &ins->src[0], coord_mask, &image_coord_param);
5508 shader_glsl_add_src_param_ext(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &image_data_param, data_type);
5509 shader_addline(ins->ctx->buffer, "imageStore(%s_image%u, %s, %s);\n",
5510 shader_glsl_get_prefix(version->type), uav_idx,
5511 image_coord_param.param_str, image_data_param.param_str);
5512}
5513
5515{
5516 const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type);
5517 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5518 struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
5519 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5520 struct glsl_src_param structure_idx, offset, data;
5521 unsigned int i, resource_idx, stride, src_idx = 0;
5523 DWORD write_mask;
5524 BOOL is_tgsm;
5525
5526 resource_idx = ins->dst[0].reg.idx[0].offset;
5527 is_tgsm = ins->dst[0].reg.type == WINED3DSPR_GROUPSHAREDMEM;
5528 if (is_tgsm)
5529 {
5530 if (resource_idx >= reg_maps->tgsm_count)
5531 {
5532 ERR("Invalid TGSM index %u.\n", resource_idx);
5533 return;
5534 }
5535 stride = reg_maps->tgsm[resource_idx].stride;
5536 }
5537 else
5538 {
5539 if (resource_idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
5540 {
5541 ERR("Invalid UAV index %u.\n", resource_idx);
5542 return;
5543 }
5544 stride = reg_maps->uav_resource_info[resource_idx].stride;
5545 }
5546
5549 {
5550 shader_glsl_add_src_param(ins, &ins->src[src_idx++], WINED3DSP_WRITEMASK_0, &structure_idx);
5551 shader_addline(address, "%s * %u + ", structure_idx.param_str, stride);
5552 }
5554 shader_addline(address, "%s / 4", offset.param_str);
5555
5556 for (i = 0; i < 4; ++i)
5557 {
5558 if (!(write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i)))
5559 continue;
5560
5561 shader_glsl_add_src_param(ins, &ins->src[src_idx], write_mask, &data);
5562
5563 if (is_tgsm)
5564 shader_addline(buffer, "%s_g%u[%s + %u] = %s;\n",
5565 prefix, resource_idx, address->buffer, i, data.param_str);
5566 else
5567 shader_addline(buffer, "imageStore(%s_image%u, %s + %u, uvec4(%s, 0, 0, 0));\n",
5568 prefix, resource_idx, address->buffer, i, data.param_str);
5569 }
5570
5572}
5573
5574static void shader_glsl_sync(const struct wined3d_shader_instruction *ins)
5575{
5576 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5577 unsigned int sync_flags = ins->flags;
5578
5579 if (sync_flags & WINED3DSSF_THREAD_GROUP)
5580 {
5581 shader_addline(buffer, "barrier();\n");
5583 }
5584
5585 if (sync_flags & WINED3DSSF_GROUP_SHARED_MEMORY)
5586 {
5587 shader_addline(buffer, "memoryBarrierShared();\n");
5588 sync_flags &= ~WINED3DSSF_GROUP_SHARED_MEMORY;
5589 }
5590
5591 if (sync_flags)
5592 FIXME("Unhandled sync flags %#x.\n", sync_flags);
5593}
5594
5596 const struct wined3d_shader_instruction *ins, const struct wined3d_shader_register *reg)
5597{
5598 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5599 unsigned int idx = reg->idx[0].offset;
5600
5601 if (reg->type == WINED3DSPR_RESOURCE)
5602 {
5603 if (idx >= ARRAY_SIZE(reg_maps->resource_info))
5604 {
5605 ERR("Invalid resource index %u.\n", idx);
5606 return NULL;
5607 }
5608 return &reg_maps->resource_info[idx];
5609 }
5610
5611 if (reg->type == WINED3DSPR_UAV)
5612 {
5613 if (idx >= ARRAY_SIZE(reg_maps->uav_resource_info))
5614 {
5615 ERR("Invalid UAV index %u.\n", idx);
5616 return NULL;
5617 }
5618 return &reg_maps->uav_resource_info[idx];
5619 }
5620
5621 FIXME("Unhandled register type %#x.\n", reg->type);
5622 return NULL;
5623}
5624
5626{
5627 const char *prefix = shader_glsl_get_prefix(ins->ctx->reg_maps->shader_version.type);
5628 const struct wined3d_shader_resource_info *resource_info;
5629 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5630 unsigned int resource_idx;
5631 char dst_swizzle[6];
5632 DWORD write_mask;
5633
5634 write_mask = shader_glsl_append_dst(buffer, ins);
5635 shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
5636
5637 if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[0].reg)))
5638 return;
5639 resource_idx = ins->src[0].reg.idx[0].offset;
5640
5641 shader_addline(buffer, "ivec2(");
5642 if (ins->src[0].reg.type == WINED3DSPR_RESOURCE)
5643 {
5644 unsigned int bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map,
5645 resource_idx, WINED3D_SAMPLER_DEFAULT);
5646 shader_addline(buffer, "textureSize(%s_sampler%u)", prefix, bind_idx);
5647 }
5648 else
5649 {
5650 shader_addline(buffer, "imageSize(%s_image%u)", prefix, resource_idx);
5651 }
5652 if (resource_info->stride)
5653 shader_addline(buffer, " / %u", resource_info->stride);
5654 else if (resource_info->flags & WINED3D_VIEW_BUFFER_RAW)
5655 shader_addline(buffer, " * 4");
5656 shader_addline(buffer, ", %u)%s);\n", resource_info->stride, dst_swizzle);
5657}
5658
5660{
5661 return resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_2DMS
5663}
5664
5666{
5667 return resource_type != WINED3D_SHADER_RESOURCE_BUFFER && !is_multisampled(resource_type);
5668}
5669
5671{
5672 const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
5673 const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
5674 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5675 enum wined3d_shader_resource_type resource_type;
5677 unsigned int resource_idx, bind_idx, i;
5678 enum wined3d_data_type dst_data_type;
5679 struct glsl_src_param lod_param;
5680 BOOL supports_mipmaps;
5681 char dst_swizzle[6];
5682 DWORD write_mask;
5683
5684 dst_data_type = ins->dst[0].reg.data_type;
5685 if (ins->flags == WINED3DSI_RESINFO_UINT)
5686 dst_data_type = WINED3D_DATA_UINT;
5687 else if (ins->flags)
5688 FIXME("Unhandled flags %#x.\n", ins->flags);
5689
5690 reg_type = ins->src[1].reg.type;
5691 resource_idx = ins->src[1].reg.idx[0].offset;
5692 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &lod_param);
5694 {
5695 resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type;
5696 bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map,
5697 resource_idx, WINED3D_SAMPLER_DEFAULT);
5698 }
5699 else
5700 {
5701 resource_type = ins->ctx->reg_maps->uav_resource_info[resource_idx].type;
5702 bind_idx = resource_idx;
5703 }
5704
5705 if (resource_type >= ARRAY_SIZE(resource_type_info))
5706 {
5707 ERR("Unexpected resource type %#x.\n", resource_type);
5708 return;
5709 }
5710
5711 write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], dst_data_type);
5712 shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle);
5713
5714 if (dst_data_type == WINED3D_DATA_UINT)
5715 shader_addline(buffer, "uvec4(");
5716 else
5717 shader_addline(buffer, "vec4(");
5718
5720 {
5721 shader_addline(buffer, "textureSize(%s_sampler%u",
5722 shader_glsl_get_prefix(version->type), bind_idx);
5723 }
5724 else
5725 {
5726 shader_addline(buffer, "imageSize(%s_image%u",
5727 shader_glsl_get_prefix(version->type), bind_idx);
5728 }
5729
5730 supports_mipmaps = is_mipmapped(resource_type) && reg_type != WINED3DSPR_UAV;
5731 if (supports_mipmaps)
5732 shader_addline(buffer, ", %s", lod_param.param_str);
5733 shader_addline(buffer, "), ");
5734
5735 for (i = 0; i < 3 - resource_type_info[resource_type].resinfo_size; ++i)
5736 shader_addline(buffer, "0, ");
5737
5738 if (supports_mipmaps)
5739 {
5740 if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS])
5741 {
5742 shader_addline(buffer, "textureQueryLevels(%s_sampler%u)",
5743 shader_glsl_get_prefix(version->type), bind_idx);
5744 }
5745 else
5746 {
5747 FIXME("textureQueryLevels is not supported, returning 1 level.\n");
5748 shader_addline(buffer, "1");
5749 }
5750 }
5751 else
5752 {
5753 shader_addline(buffer, "1");
5754 }
5755
5756 shader_addline(buffer, ")%s);\n", dst_swizzle);
5757}
5758
5759static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
5760{
5761 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5762 struct glsl_src_param coord_param, lod_param, sample_param;
5763 unsigned int resource_idx, sampler_idx, sampler_bind_idx;
5764 struct glsl_sample_function sample_function;
5766 BOOL has_lod_param;
5767
5770
5771 resource_idx = ins->src[1].reg.idx[0].offset;
5772 sampler_idx = WINED3D_SAMPLER_DEFAULT;
5773
5774 if (resource_idx >= ARRAY_SIZE(reg_maps->resource_info))
5775 {
5776 ERR("Invalid resource index %u.\n", resource_idx);
5777 return;
5778 }
5779 has_lod_param = is_mipmapped(reg_maps->resource_info[resource_idx].type);
5780
5781 shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
5782 shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
5783 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
5784 sampler_bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, sampler_idx);
5785 if (is_multisampled(reg_maps->resource_info[resource_idx].type))
5786 {
5787 shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &sample_param);
5788 shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
5789 NULL, NULL, NULL, &ins->texel_offset, "%s, %s", coord_param.param_str, sample_param.param_str);
5790 }
5791 else
5792 {
5793 shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
5794 NULL, NULL, has_lod_param ? lod_param.param_str : NULL, &ins->texel_offset,
5795 "%s", coord_param.param_str);
5796 }
5797 shader_glsl_release_sample_function(ins->ctx, &sample_function);
5798}
5799
5801{
5802 const char *lod_param_str = NULL, *dx_param_str = NULL, *dy_param_str = NULL;
5803 struct glsl_src_param coord_param, lod_param, dx_param, dy_param;
5804 unsigned int resource_idx, sampler_idx, sampler_bind_idx;
5805 struct glsl_sample_function sample_function;
5806 DWORD flags = 0;
5807
5814
5815 resource_idx = ins->src[1].reg.idx[0].offset;
5816 sampler_idx = ins->src[2].reg.idx[0].offset;
5817
5818 shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
5819 shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
5820
5821 switch (ins->handler_idx)
5822 {
5823 case WINED3DSIH_SAMPLE:
5824 break;
5826 shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param);
5827 lod_param_str = lod_param.param_str;
5828 break;
5830 shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dx_param);
5831 shader_glsl_add_src_param(ins, &ins->src[4], sample_function.deriv_mask, &dy_param);
5832 dx_param_str = dx_param.param_str;
5833 dy_param_str = dy_param.param_str;
5834 break;
5836 shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param);
5837 lod_param_str = lod_param.param_str;
5838 break;
5839 default:
5840 ERR("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
5841 break;
5842 }
5843
5844 sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx);
5845 shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
5846 dx_param_str, dy_param_str, lod_param_str, &ins->texel_offset, "%s", coord_param.param_str);
5847 shader_glsl_release_sample_function(ins->ctx, &sample_function);
5848}
5849
5850/* GLSL doesn't provide a function to sample from level zero with depth
5851 * comparison for array textures and cube textures. We use textureGrad*()
5852 * to implement sample_c_lz.
5853 */
5855 unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function,
5856 unsigned int coord_size, const char *coord_param, const char *ref_param)
5857{
5858 const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
5859 unsigned int deriv_size = wined3d_popcount(sample_function->deriv_mask);
5860 const struct wined3d_shader_texel_offset *offset = &ins->texel_offset;
5861 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5862 char dst_swizzle[6];
5863
5864 WARN("Emitting textureGrad() for sample_c_lz.\n");
5865
5866 shader_glsl_swizzle_to_str(WINED3DSP_NOSWIZZLE, FALSE, ins->dst[0].write_mask, dst_swizzle);
5867 shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], sample_function->data_type);
5868 shader_addline(buffer, "vec4(textureGrad%s(%s_sampler%u, vec%u(%s, %s), vec%u(0.0), vec%u(0.0)",
5869 sample_function->offset_size ? "Offset" : "",
5870 shader_glsl_get_prefix(version->type), sampler_bind_idx,
5871 coord_size, coord_param, ref_param, deriv_size, deriv_size);
5872 if (sample_function->offset_size)
5873 {
5874 int offset_immdata[4] = {offset->u, offset->v, offset->w};
5875 shader_addline(buffer, ", ");
5876 shader_glsl_append_imm_ivec(buffer, offset_immdata, sample_function->offset_size);
5877 }
5878 shader_addline(buffer, "))%s);\n", dst_swizzle);
5879}
5880
5882{
5883 unsigned int resource_idx, sampler_idx, sampler_bind_idx;
5884 const struct wined3d_shader_resource_info *resource_info;
5885 struct glsl_src_param coord_param, compare_param;
5886 struct glsl_sample_function sample_function;
5887 const char *lod_param = NULL;
5888 unsigned int coord_size;
5889 DWORD flags = 0;
5890
5892 {
5893 lod_param = "0";
5895 }
5896
5899
5900 if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[1].reg)))
5901 return;
5902 resource_idx = ins->src[1].reg.idx[0].offset;
5903 sampler_idx = ins->src[2].reg.idx[0].offset;
5904
5905 shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
5907 shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask >> 1, &coord_param);
5908 shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &compare_param);
5909 sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx);
5911 && (resource_info->type == WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY
5912 || resource_info->type == WINED3D_SHADER_RESOURCE_TEXTURE_CUBE))
5913 {
5914 shader_glsl_gen_sample_c_lz(ins, sampler_bind_idx, &sample_function,
5915 coord_size, coord_param.param_str, compare_param.param_str);
5916 }
5917 else
5918 {
5919 shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, WINED3DSP_NOSWIZZLE,
5920 NULL, NULL, lod_param, &ins->texel_offset, "vec%u(%s, %s)",
5921 coord_size, coord_param.param_str, compare_param.param_str);
5922 }
5923 shader_glsl_release_sample_function(ins->ctx, &sample_function);
5924}
5925
5927{
5928 unsigned int resource_param_idx, resource_idx, sampler_idx, sampler_bind_idx, component_idx;
5929 const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
5930 const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
5931 struct glsl_src_param coord_param, compare_param, offset_param;
5932 const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
5933 const struct wined3d_shader_resource_info *resource_info;
5934 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5935 unsigned int coord_size, offset_size;
5936 char dst_swizzle[6];
5937 BOOL has_offset;
5938
5939 if (!gl_info->supported[ARB_TEXTURE_GATHER])
5940 {
5941 FIXME("OpenGL implementation does not support textureGather.\n");
5942 return;
5943 }
5944
5945 has_offset = ins->handler_idx == WINED3DSIH_GATHER4_PO
5948
5949 resource_param_idx =
5951 resource_idx = ins->src[resource_param_idx].reg.idx[0].offset;
5952 sampler_idx = ins->src[resource_param_idx + 1].reg.idx[0].offset;
5953 component_idx = shader_glsl_swizzle_get_component(ins->src[resource_param_idx + 1].swizzle, 0);
5954 sampler_bind_idx = shader_glsl_find_sampler(&reg_maps->sampler_map, resource_idx, sampler_idx);
5955
5956 if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[resource_param_idx].reg)))
5957 return;
5958
5959 if (resource_info->type >= ARRAY_SIZE(resource_type_info))
5960 {
5961 ERR("Unexpected resource type %#x.\n", resource_info->type);
5962 return;
5963 }
5964 shader_glsl_get_coord_size(resource_info->type, &coord_size, &offset_size);
5965
5966 shader_glsl_swizzle_to_str(ins->src[resource_param_idx].swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
5967 shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], resource_info->data_type);
5968
5969 shader_glsl_add_src_param(ins, &ins->src[0], (1u << coord_size) - 1, &coord_param);
5970
5971 shader_addline(buffer, "textureGather%s(%s_sampler%u, %s",
5972 has_offset ? "Offset" : "", prefix, sampler_bind_idx, coord_param.param_str);
5974 {
5975 shader_glsl_add_src_param(ins, &ins->src[resource_param_idx + 2], WINED3DSP_WRITEMASK_0, &compare_param);
5976 shader_addline(buffer, ", %s", compare_param.param_str);
5977 }
5979 {
5980 shader_glsl_add_src_param(ins, &ins->src[1], (1u << offset_size) - 1, &offset_param);
5981 shader_addline(buffer, ", %s", offset_param.param_str);
5982 }
5983 else if (has_offset)
5984 {
5985 int offset_immdata[4] = {ins->texel_offset.u, ins->texel_offset.v, ins->texel_offset.w};
5986 shader_addline(buffer, ", ");
5987 shader_glsl_append_imm_ivec(buffer, offset_immdata, offset_size);
5988 }
5989 if (component_idx)
5990 shader_addline(buffer, ", %u", component_idx);
5991
5992 shader_addline(buffer, ")%s);\n", dst_swizzle);
5993}
5994
5996{
5997 /* FIXME: Make this work for more than just 2D textures */
5998 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
5999 DWORD write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
6000
6001 if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
6002 {
6003 char dst_mask[6];
6004
6005 shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
6006 shader_addline(buffer, "clamp(ffp_texcoord[%u], 0.0, 1.0)%s);\n",
6007 ins->dst[0].reg.idx[0].offset, dst_mask);
6008 }
6009 else
6010 {
6011 enum wined3d_shader_src_modifier src_mod = ins->src[0].modifiers;
6012 DWORD reg = ins->src[0].reg.idx[0].offset;
6013 char dst_swizzle[6];
6014
6015 shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
6016
6017 if (src_mod == WINED3DSPSM_DZ || src_mod == WINED3DSPSM_DW)
6018 {
6019 unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
6020 struct glsl_src_param div_param;
6021 DWORD src_writemask = src_mod == WINED3DSPSM_DZ ? WINED3DSP_WRITEMASK_2 : WINED3DSP_WRITEMASK_3;
6022
6023 shader_glsl_add_src_param(ins, &ins->src[0], src_writemask, &div_param);
6024
6025 if (mask_size > 1)
6026 shader_addline(buffer, "ffp_texcoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
6027 else
6028 shader_addline(buffer, "ffp_texcoord[%u]%s / %s);\n", reg, dst_swizzle, div_param.param_str);
6029 }
6030 else
6031 {
6032 shader_addline(buffer, "ffp_texcoord[%u]%s);\n", reg, dst_swizzle);
6033 }
6034 }
6035}
6036
6041{
6043 DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
6044 struct glsl_sample_function sample_function;
6045 struct glsl_src_param src0_param;
6046 UINT mask_size;
6047
6048 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6049
6050 /* Do I have to take care about the projected bit? I don't think so, since the dp3 returns only one
6051 * scalar, and projected sampling would require 4.
6052 *
6053 * It is a dependent read - not valid with conditional NP2 textures
6054 */
6055 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
6056 mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask);
6057
6058 switch(mask_size)
6059 {
6060 case 1:
6061 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
6062 NULL, "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
6063 break;
6064
6065 case 2:
6066 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
6067 NULL, "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
6068 break;
6069
6070 case 3:
6071 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
6072 NULL, "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
6073 break;
6074
6075 default:
6076 FIXME("Unexpected mask size %u\n", mask_size);
6077 break;
6078 }
6079 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6080}
6081
6085{
6087 DWORD dstreg = ins->dst[0].reg.idx[0].offset;
6088 struct glsl_src_param src0_param;
6089 DWORD dst_mask;
6090 unsigned int mask_size;
6091
6092 dst_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
6093 mask_size = shader_glsl_get_write_mask_size(dst_mask);
6094 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6095
6096 if (mask_size > 1) {
6097 shader_addline(ins->ctx->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
6098 } else {
6099 shader_addline(ins->ctx->buffer, "dot(T%u.xyz, %s));\n", dstreg, src0_param.param_str);
6100 }
6101}
6102
6106{
6107 struct glsl_dst_param dst_param;
6108
6109 shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
6110
6111 /* Tests show that texdepth never returns anything below 0.0, and that r5.y is clamped to 1.0.
6112 * Negative input is accepted, -0.25 / -0.5 returns 0.5. GL should clamp gl_FragDepth to [0;1], but
6113 * this doesn't always work, so clamp the results manually. Whether or not the x value is clamped at 1
6114 * too is irrelevant, since if x = 0, any y value < 1.0 (and > 1.0 is not allowed) results in a result
6115 * >= 1.0 or < 0.0
6116 */
6117 shader_addline(ins->ctx->buffer, "gl_FragDepth = clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n",
6118 dst_param.reg_name, dst_param.reg_name);
6119}
6120
6127{
6129 DWORD dstreg = ins->dst[0].reg.idx[0].offset;
6130 struct glsl_src_param src0_param;
6131
6132 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6133
6134 shader_addline(ins->ctx->buffer, "tmp0.y = dot(T%u.xyz, %s);\n", dstreg, src0_param.param_str);
6135 shader_addline(ins->ctx->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
6136}
6137
6141{
6143 DWORD reg = ins->dst[0].reg.idx[0].offset;
6144 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
6145 struct glsl_src_param src0_param;
6146
6147 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6148 shader_addline(buffer, "tmp0.x = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
6149}
6150
6154{
6156 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
6157 struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
6158 DWORD reg = ins->dst[0].reg.idx[0].offset;
6159 struct glsl_src_param src0_param;
6160
6161 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6162 shader_addline(buffer, "tmp0.%c = dot(T%u.xyz, %s);\n", 'x' + tex_mx->current_row, reg, src0_param.param_str);
6163 tex_mx->texcoord_w[tex_mx->current_row++] = reg;
6164}
6165
6167{
6169 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
6170 struct glsl_sample_function sample_function;
6171 DWORD reg = ins->dst[0].reg.idx[0].offset;
6172 struct glsl_src_param src0_param;
6173
6174 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6175 shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
6176
6177 shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function);
6178
6179 /* Sample the texture using the calculated coordinates */
6180 shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xy");
6181 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6182}
6183
6187{
6189 struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
6190 struct glsl_sample_function sample_function;
6191 DWORD reg = ins->dst[0].reg.idx[0].offset;
6192 struct glsl_src_param src0_param;
6193
6194 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6195 shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
6196
6197 /* Dependent read, not valid with conditional NP2 */
6198 shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function);
6199
6200 /* Sample the texture using the calculated coordinates */
6201 shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xyz");
6202 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6203
6204 tex_mx->current_row = 0;
6205}
6206
6210{
6212 struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
6213 DWORD reg = ins->dst[0].reg.idx[0].offset;
6214 struct glsl_src_param src0_param;
6215 char dst_mask[6];
6216
6217 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6218
6219 shader_glsl_append_dst(ins->ctx->buffer, ins);
6220 shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
6221 shader_addline(ins->ctx->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
6222
6223 tex_mx->current_row = 0;
6224}
6225
6226/* Process the WINED3DSIO_TEXM3X3SPEC instruction in GLSL
6227 * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
6229{
6230 struct glsl_src_param src0_param;
6231 struct glsl_src_param src1_param;
6232 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
6233 struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
6235 struct glsl_sample_function sample_function;
6236 DWORD reg = ins->dst[0].reg.idx[0].offset;
6237 char coord_mask[6];
6238
6239 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6240 shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
6241
6242 /* Perform the last matrix multiply operation */
6243 shader_addline(buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
6244 /* Reflection calculation */
6245 shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str);
6246
6247 /* Dependent read, not valid with conditional NP2 */
6248 shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function);
6250
6251 /* Sample the texture */
6252 shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE,
6253 NULL, NULL, NULL, NULL, "tmp0%s", coord_mask);
6254 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6255
6256 tex_mx->current_row = 0;
6257}
6258
6259/* Process the WINED3DSIO_TEXM3X3VSPEC instruction in GLSL
6260 * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
6262{
6263 struct wined3d_string_buffer *buffer = ins->ctx->buffer;
6264 struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
6266 struct glsl_sample_function sample_function;
6267 DWORD reg = ins->dst[0].reg.idx[0].offset;
6268 struct glsl_src_param src0_param;
6269 char coord_mask[6];
6270
6271 shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
6272
6273 /* Perform the last matrix multiply operation */
6274 shader_addline(buffer, "tmp0.z = dot(vec3(T%u), vec3(%s));\n", reg, src0_param.param_str);
6275
6276 /* Construct the eye-ray vector from w coordinates */
6277 shader_addline(buffer, "tmp1.xyz = normalize(vec3(ffp_texcoord[%u].w, ffp_texcoord[%u].w, ffp_texcoord[%u].w));\n",
6278 tex_mx->texcoord_w[0], tex_mx->texcoord_w[1], reg);
6279 shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n");
6280
6281 /* Dependent read, not valid with conditional NP2 */
6282 shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function);
6283 shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask);
6284
6285 /* Sample the texture using the calculated coordinates */
6286 shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE,
6287 NULL, NULL, NULL, NULL, "tmp0%s", coord_mask);
6288 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6289
6290 tex_mx->current_row = 0;
6291}
6292
6298{
6299 const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
6300 struct glsl_sample_function sample_function;
6301 struct glsl_src_param coord_param;
6302 DWORD sampler_idx;
6303 DWORD mask;
6304 DWORD flags;
6305 char coord_mask[6];
6306
6307 sampler_idx = ins->dst[0].reg.idx[0].offset;
6308 flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
6310
6311 /* Dependent read, not valid with conditional NP2 */
6312 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
6313 mask = sample_function.coord_mask;
6314
6316
6317 /* With projected textures, texbem only divides the static texture coord,
6318 * not the displacement, so we can't let GL handle this. */
6320 {
6321 DWORD div_mask=0;
6322 char coord_div_mask[3];
6324 {
6326 FIXME("WINED3D_TTFF_PROJECTED with WINED3D_TTFF_COUNT1?\n");
6327 break;
6329 div_mask = WINED3DSP_WRITEMASK_1;
6330 break;
6332 div_mask = WINED3DSP_WRITEMASK_2;
6333 break;
6336 div_mask = WINED3DSP_WRITEMASK_3;
6337 break;
6338 }
6339 shader_glsl_write_mask_to_str(div_mask, coord_div_mask);
6340 shader_addline(ins->ctx->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
6341 }
6342
6344
6345 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
6346 "T%u%s + vec4(bumpenv_mat%u * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
6347 coord_param.param_str, coord_mask);
6348
6349 if (ins->handler_idx == WINED3DSIH_TEXBEML)
6350 {
6351 struct glsl_src_param luminance_param;
6352 struct glsl_dst_param dst_param;
6353
6354 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &luminance_param);
6355 shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
6356
6357 shader_addline(ins->ctx->buffer, "%s%s *= (%s * bumpenv_lum_scale%u + bumpenv_lum_offset%u);\n",
6358 dst_param.reg_name, dst_param.mask_str,
6359 luminance_param.param_str, sampler_idx, sampler_idx);
6360 }
6361 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6362}
6363
6364static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
6365{
6366 DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
6367 struct glsl_src_param src0_param, src1_param;
6368
6371
6372 shader_glsl_append_dst(ins->ctx->buffer, ins);
6373 shader_addline(ins->ctx->buffer, "%s + bumpenv_mat%u * %s);\n",
6374 src0_param.param_str, sampler_idx, src1_param.param_str);
6375}
6376
6380{
6381 DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
6382 struct glsl_sample_function sample_function;
6383 struct glsl_src_param src0_param;
6384
6385 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
6386
6387 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
6388 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
6389 "%s.wx", src0_param.reg_name);
6390 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6391}
6392
6396{
6397 DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
6398 struct glsl_sample_function sample_function;
6399 struct glsl_src_param src0_param;
6400
6401 shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
6402
6403 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
6404 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
6405 "%s.yz", src0_param.reg_name);
6406 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6407}
6408
6412{
6413 DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
6414 struct glsl_sample_function sample_function;
6415 struct glsl_src_param src0_param;
6416
6417 /* Dependent read, not valid with conditional NP2 */
6418 shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
6419 shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
6420
6421 shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
6422 "%s", src0_param.param_str);
6423 shader_glsl_release_sample_function(ins->ctx, &sample_function);
6424}
6425
6429{
6430 if (ins->ctx->reg_maps->shader_version.major >= 4)
6431 {
6432 shader_glsl_generate_conditional_op(ins, "discard;");
6433 }
6434 else
6435 {
6436 struct glsl_dst_param dst_param;
6437
6438 /* The argument is a destination parameter, and no writemasks are allowed */
6439 shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
6440
6441 /* 2.0 shaders compare all 4 components in texkill. */
6442 if (ins->ctx->reg_maps->shader_version.major >= 2)
6443 shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
6444 /* 1.x shaders only compare the first 3 components, probably due to
6445 * the nature of the texkill instruction as a tex* instruction, and
6446 * phase, which kills all .w components. Even if all 4 components are
6447 * defined, only the first 3 are used. */
6448 else
6449 shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
6450 }
6451}
6452
6456{
6457 struct glsl_src_param src0_param;
6458 struct glsl_src_param src1_param;
6459 struct glsl_src_param src2_param;
6460 DWORD write_mask;
6461 unsigned int mask_size;
6462
6463 write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
6464 mask_size = shader_glsl_get_write_mask_size(write_mask);
6465
6468 shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &src2_param);
6469
6470 if (mask_size > 1) {
6471 shader_addline(ins->ctx->buffer, "vec%d(dot(%s, %s) + %s));\n",
6472 mask_size, src0_param.param_str, src1_param.param_str, src2_param.param_str);
6473 } else {
6474 shader_addline(ins->ctx->buffer, "dot(%s, %s) + %s);\n",
6475 src0_param.param_str, src1_param.param_str, src2_param.param_str);
6476 }
6477}
6478
6480 const struct wined3d_shader_signature *input_signature,
6481 const struct wined3d_shader_reg_maps *reg_maps,
6482 const struct ps_compile_args *args, const struct wined3d_gl_info *gl_info, BOOL unroll)
6483{
6484 unsigned int i;
6485
6486 for (i = 0; i < input_signature->element_count; ++i)
6487 {
6488 const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
6489 const char *semantic_name;
6491 char reg_mask[6];
6492
6493 /* Unused */
6494 if (!(reg_maps->input_registers & (1u << input->register_idx)))
6495 continue;
6496
6497 semantic_name = input->semantic_name;
6498 semantic_idx = input->semantic_idx;
6499 shader_glsl_write_mask_to_str(input->mask, reg_mask);
6500
6501 if (args->vp_mode == vertexshader)
6502 {
6503 if (input->sysval_semantic == WINED3D_SV_POSITION && !semantic_idx)
6504 {
6505 shader_addline(buffer, "ps_in[%u]%s = vpos%s;\n",
6506 shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
6507 }
6509 {
6510 shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", input->register_idx);
6511 }
6512 else if (input->sysval_semantic == WINED3D_SV_IS_FRONT_FACE)
6513 {
6514 shader_addline(buffer, "ps_in[%u]%s = uintBitsToFloat(gl_FrontFacing ? 0xffffffffu : 0u);\n",
6515 input->register_idx, reg_mask);
6516 }
6517 else if (input->sysval_semantic == WINED3D_SV_RENDER_TARGET_ARRAY_INDEX && !semantic_idx)
6518 {
6520 shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_Layer);\n",
6521 input->register_idx, reg_mask);
6522 else
6523 FIXME("ARB_fragment_layer_viewport is not supported.\n");
6524 }
6525 else
6526 {
6527 if (input->sysval_semantic)
6528 FIXME("Unhandled sysval semantic %#x.\n", input->sysval_semantic);
6529 shader_addline(buffer, unroll ? "ps_in[%u]%s = %s%u%s;\n" : "ps_in[%u]%s = %s[%u]%s;\n",
6530 shader->u.ps.input_reg_map[input->register_idx], reg_mask,
6532 shader->u.ps.input_reg_map[input->register_idx], reg_mask);
6533 }
6534 }
6536 {
6537 if (args->pointsprite)
6538 shader_addline(buffer, "ps_in[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n",
6539 shader->u.ps.input_reg_map[input->register_idx]);
6540 else if (args->vp_mode == pretransformed && args->texcoords_initialized & (1u << semantic_idx))
6541 shader_addline(buffer, "ps_in[%u]%s = %s[%u]%s;\n",
6542 shader->u.ps.input_reg_map[input->register_idx], reg_mask,
6544 ? "gl_TexCoord" : "ffp_varying_texcoord", semantic_idx, reg_mask);
6545 else
6546 shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
6547 shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
6548 }
6550 {
6551 if (!semantic_idx)
6552 shader_addline(buffer, "ps_in[%u]%s = vec4(ffp_varying_diffuse)%s;\n",
6553 shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
6554 else if (semantic_idx == 1)
6555 shader_addline(buffer, "ps_in[%u]%s = vec4(ffp_varying_specular)%s;\n",
6556 shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
6557 else
6558 shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
6559 shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
6560 }
6561 else
6562 {
6563 shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
6564 shader->u.ps.input_reg_map[input->register_idx], reg_mask, reg_mask);
6565 }
6566 }
6567}
6568
6570{
6571 struct glsl_program_key key;
6572
6573 key.vs_id = entry->vs.id;
6574 key.hs_id = entry->hs.id;
6575 key.ds_id = entry->ds.id;
6576 key.gs_id = entry->gs.id;
6577 key.ps_id = entry->ps.id;
6578 key.cs_id = entry->cs.id;
6579
6580 if (wine_rb_put(&priv->program_lookup, &key, &entry->program_lookup_entry) == -1)
6581 {
6582 ERR("Failed to insert program entry.\n");
6583 }
6584}
6585
6587 const struct glsl_program_key *key)
6588{
6589 struct wine_rb_entry *entry;
6590
6592 return entry ? WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry) : NULL;
6593}
6594
6595/* Context activation is done by the caller. */
6596static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info,
6598{
6599 wine_rb_remove(&priv->program_lookup, &entry->program_lookup_entry);
6600
6601 GL_EXTCALL(glDeleteProgram(entry->id));
6602 if (entry->vs.id)
6603 list_remove(&entry->vs.shader_entry);
6604 if (entry->hs.id)
6605 list_remove(&entry->hs.shader_entry);
6606 if (entry->ds.id)
6607 list_remove(&entry->ds.shader_entry);
6608 if (entry->gs.id)
6609 list_remove(&entry->gs.shader_entry);
6610 if (entry->ps.id)
6611 list_remove(&entry->ps.shader_entry);
6612 if (entry->cs.id)
6613 list_remove(&entry->cs.shader_entry);
6615}
6616
6618 const struct wined3d_gl_info *gl_info, const DWORD *map,
6619 const struct wined3d_shader_signature *input_signature,
6620 const struct wined3d_shader_reg_maps *reg_maps_in,
6621 const struct wined3d_shader_signature *output_signature,
6622 const struct wined3d_shader_reg_maps *reg_maps_out)
6623{
6624 struct wined3d_string_buffer *destination = string_buffer_get(&priv->string_buffers);
6625 const char *out_array_name = shader_glsl_shader_output_name(gl_info);
6627 unsigned int in_count = vec4_varyings(3, gl_info);
6628 unsigned int max_varyings = needs_legacy_glsl_syntax(gl_info) ? in_count + 2 : in_count;
6629 DWORD in_idx, *set = NULL;
6630 unsigned int i, j;
6631 char reg_mask[6];
6632
6633 set = heap_calloc(max_varyings, sizeof(*set));
6634
6635 for (i = 0; i < input_signature->element_count; ++i)
6636 {
6637 const struct wined3d_shader_signature_element *input = &input_signature->elements[i];
6638
6639 if (!(reg_maps_in->input_registers & (1u << input->register_idx)))
6640 continue;
6641
6642 in_idx = map[input->register_idx];
6643 /* Declared, but not read register */
6644 if (in_idx == ~0u)
6645 continue;
6646 if (in_idx >= max_varyings)
6647 {
6648 FIXME("More input varyings declared than supported, expect issues.\n");
6649 continue;
6650 }
6651
6652 if (in_idx == in_count)
6653 string_buffer_sprintf(destination, "gl_FrontColor");
6654 else if (in_idx == in_count + 1)
6655 string_buffer_sprintf(destination, "gl_FrontSecondaryColor");
6656 else
6657 string_buffer_sprintf(destination, "%s[%u]", out_array_name, in_idx);
6658
6659 if (!set[in_idx])
6660 set[in_idx] = ~0u;
6661
6662 for (j = 0; j < output_signature->element_count; ++j)
6663 {
6664 const struct wined3d_shader_signature_element *output = &output_signature->elements[j];
6665 DWORD mask;
6666
6667 if (!(reg_maps_out->output_registers & (1u << output->register_idx))
6668 || input->semantic_idx != output->semantic_idx
6669 || strcmp(input->semantic_name, output->semantic_name)
6670 || !(mask = input->mask & output->mask))
6671 continue;
6672
6673 if (set[in_idx] == ~0u)
6674 set[in_idx] = 0;
6675 set[in_idx] |= mask & reg_maps_out->u.output_registers_mask[output->register_idx];
6677
6678 shader_addline(buffer, "%s%s = outputs[%u]%s;\n",
6679 destination->buffer, reg_mask, output->register_idx, reg_mask);
6680 }
6681 }
6682
6683 for (i = 0; i < max_varyings; ++i)
6684 {
6685 unsigned int size;
6686
6687 if (!set[i] || set[i] == WINED3DSP_WRITEMASK_ALL)
6688 continue;
6689
6690 if (set[i] == ~0u)
6691 set[i] = 0;
6692
6693 size = 0;
6694 if (!(set[i] & WINED3DSP_WRITEMASK_0))
6695 reg_mask[size++] = 'x';
6696 if (!(set[i] & WINED3DSP_WRITEMASK_1))
6697 reg_mask[size++] = 'y';
6698 if (!(set[i] & WINED3DSP_WRITEMASK_2))
6699 reg_mask[size++] = 'z';
6700 if (!(set[i] & WINED3DSP_WRITEMASK_3))
6701 reg_mask[size++] = 'w';
6702 reg_mask[size] = '\0';
6703
6704 if (i == in_count)
6705 string_buffer_sprintf(destination, "gl_FrontColor");
6706 else if (i == in_count + 1)
6707 string_buffer_sprintf(destination, "gl_FrontSecondaryColor");
6708 else
6709 string_buffer_sprintf(destination, "%s[%u]", out_array_name, i);
6710
6711 if (size == 1)
6712 shader_addline(buffer, "%s.%s = 0.0;\n", destination->buffer, reg_mask);
6713 else
6714 shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination->buffer, reg_mask, size);
6715 }
6716
6717 heap_free(set);
6718 string_buffer_release(&priv->string_buffers, destination);
6719}
6720
6722 unsigned int input_count, const struct wined3d_shader_signature *output_signature,
6723 const struct wined3d_shader_reg_maps *reg_maps_out, const char *output_variable_name,
6724 BOOL rasterizer_setup)
6725{
6727 char reg_mask[6];
6728 unsigned int i;
6729
6730 for (i = 0; i < output_signature->element_count; ++i)
6731 {
6732 const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
6733
6734 if (!(reg_maps_out->output_registers & (1u << output->register_idx)))
6735 continue;
6736
6737 if (output->stream_idx)
6738 continue;
6739
6740 if (output->register_idx >= input_count)
6741 continue;
6742
6743 shader_glsl_write_mask_to_str(output->mask, reg_mask);
6744
6746 rasterizer_setup ? "%s.reg%u%s = outputs[%u]%s;\n" : "%s.reg[%u]%s = outputs[%u]%s;\n",
6747 output_variable_name, output->register_idx, reg_mask, output->register_idx, reg_mask);
6748 }
6749}
6750
6752 const struct wined3d_shader_signature_element *element, DWORD clip_or_cull_distance_mask)
6753{
6754 unsigned int i, clip_or_cull_index;
6755 const char *name;
6756 char reg_mask[6];
6757
6758 name = element->sysval_semantic == WINED3D_SV_CLIP_DISTANCE ? "Clip" : "Cull";
6759 /* Assign consecutive indices starting from 0. */
6760 clip_or_cull_index = element->semantic_idx ? wined3d_popcount(clip_or_cull_distance_mask & 0xf) : 0;
6761 for (i = 0; i < 4; ++i)
6762 {
6763 if (!(element->mask & (WINED3DSP_WRITEMASK_0 << i)))
6764 continue;
6765
6767 shader_addline(buffer, "gl_%sDistance[%u] = outputs[%u]%s;\n",
6768 name, clip_or_cull_index, element->register_idx, reg_mask);
6769 ++clip_or_cull_index;
6770 }
6771}
6772
6774 const struct wined3d_gl_info *gl_info, const DWORD *map,
6775 const struct wined3d_shader_signature *input_signature,
6776 const struct wined3d_shader_reg_maps *reg_maps_in, unsigned int input_count,
6777 const struct wined3d_shader_signature *output_signature,
6778 const struct wined3d_shader_reg_maps *reg_maps_out, BOOL per_vertex_point_size)
6779{
6781 const char *semantic_name;
6782 unsigned int semantic_idx;
6783 char reg_mask[6];
6784 unsigned int i;
6785
6786 /* First, sort out position and point size system values. */
6787 for (i = 0; i < output_signature->element_count; ++i)
6788 {
6789 const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
6790
6791 if (!(reg_maps_out->output_registers & (1u << output->register_idx)))
6792 continue;
6793
6794 if (output->stream_idx)
6795 continue;
6796
6797 semantic_name = output->semantic_name;
6798 semantic_idx = output->semantic_idx;
6799 shader_glsl_write_mask_to_str(output->mask, reg_mask);
6800
6802 {
6803 shader_addline(buffer, "gl_Position%s = outputs[%u]%s;\n",
6804 reg_mask, output->register_idx, reg_mask);
6805 }
6806 else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) && per_vertex_point_size)
6807 {
6808 shader_addline(buffer, "gl_PointSize = clamp(outputs[%u].%c, "
6809 "ffp_point.size_min, ffp_point.size_max);\n", output->register_idx, reg_mask[1]);
6810 }
6812 {
6813 shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n",
6814 output->register_idx, reg_mask);
6815 }
6816 else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
6817 {
6819 }
6820 else if (output->sysval_semantic == WINED3D_SV_CULL_DISTANCE)
6821 {
6823 }
6824 else if (output->sysval_semantic)
6825 {
6826 FIXME("Unhandled sysval semantic %#x.\n", output->sysval_semantic);
6827 }
6828 }
6829
6830 /* Then, setup the pixel shader input. */
6831 if (reg_maps_out->shader_version.major < 4)
6832 shader_glsl_setup_vs3_output(priv, gl_info, map, input_signature, reg_maps_in,
6833 output_signature, reg_maps_out);
6834 else
6835 shader_glsl_setup_sm4_shader_output(priv, input_count, output_signature, reg_maps_out, "shader_out", TRUE);
6836}
6837
6838/* Context activation is done by the caller. */
6840 const struct wined3d_shader *vs, const struct wined3d_shader *ps,
6841 BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info)
6842{
6843 const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
6844 DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0;
6846 const char *semantic_name;
6847 UINT semantic_idx;
6848 char reg_mask[6];
6849 unsigned int i;
6850 GLuint ret;
6851
6853
6855
6856 if (per_vertex_point_size)
6857 {
6858 shader_addline(buffer, "uniform struct\n{\n");
6859 shader_addline(buffer, " float size_min;\n");
6860 shader_addline(buffer, " float size_max;\n");
6861 shader_addline(buffer, "} ffp_point;\n");
6862 }
6863
6864 if (ps_major < 3)
6865 {
6866 DWORD colors_written_mask[2] = {0};
6867 DWORD texcoords_written_mask[MAX_TEXTURES] = {0};
6868
6869 if (!legacy_syntax)
6870 {
6871 declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_diffuse;\n");
6872 declare_out_varying(gl_info, buffer, flatshading, "vec4 ffp_varying_specular;\n");
6873 declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
6874 declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
6875 }
6876
6877 shader_addline(buffer, "void setup_vs_output(in vec4 outputs[%u])\n{\n", vs->limits->packed_output);
6878
6879 for (i = 0; i < vs->output_signature.element_count; ++i)
6880 {
6881 const struct wined3d_shader_signature_element *output = &vs->output_signature.elements[i];
6882 DWORD write_mask;
6883
6884 if (!(vs->reg_maps.output_registers & (1u << output->register_idx)))
6885 continue;
6886
6887 semantic_name = output->semantic_name;
6888 semantic_idx = output->semantic_idx;
6889 write_mask = output->mask;
6890 shader_glsl_write_mask_to_str(write_mask, reg_mask);
6891
6893 {
6894 if (legacy_syntax)
6895 shader_addline(buffer, "gl_Front%sColor%s = outputs[%u]%s;\n",
6896 semantic_idx ? "Secondary" : "", reg_mask, output->register_idx, reg_mask);
6897 else
6898 shader_addline(buffer, "ffp_varying_%s%s = clamp(outputs[%u]%s, 0.0, 1.0);\n",
6899 semantic_idx ? "specular" : "diffuse", reg_mask, output->register_idx, reg_mask);
6900
6901 colors_written_mask[semantic_idx] = write_mask;
6902 }
6904 {
6905 shader_addline(buffer, "gl_Position%s = outputs[%u]%s;\n",
6906 reg_mask, output->register_idx, reg_mask);
6907 }
6909 {
6911 {
6912 shader_addline(buffer, "%s[%u]%s = outputs[%u]%s;\n",
6913 legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord",
6914 semantic_idx, reg_mask, output->register_idx, reg_mask);
6915 texcoords_written_mask[semantic_idx] = write_mask;
6916 }
6917 }
6918 else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE) && per_vertex_point_size)
6919 {
6920 shader_addline(buffer, "gl_PointSize = clamp(outputs[%u].%c, "
6921 "ffp_point.size_min, ffp_point.size_max);\n", output->register_idx, reg_mask[1]);
6922 }
6924 {
6925 shader_addline(buffer, "%s = clamp(outputs[%u].%c, 0.0, 1.0);\n",
6926 legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord",
6927 output->register_idx, reg_mask[1]);
6928 }
6929 }
6930
6931 for (i = 0; i < 2; ++i)
6932 {
6933 if (colors_written_mask[i] != WINED3DSP_WRITEMASK_ALL)
6934 {
6935 shader_glsl_write_mask_to_str(~colors_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask);
6936 if (!i)
6937 shader_addline(buffer, "%s%s = vec4(1.0)%s;\n",
6938 legacy_syntax ? "gl_FrontColor" : "ffp_varying_diffuse",
6939 reg_mask, reg_mask);
6940 else
6941 shader_addline(buffer, "%s%s = vec4(0.0)%s;\n",
6942 legacy_syntax ? "gl_FrontSecondaryColor" : "ffp_varying_specular",
6943 reg_mask, reg_mask);
6944 }
6945 }
6946 for (i = 0; i < MAX_TEXTURES; ++i)
6947 {
6948 if (ps && !(ps->reg_maps.texcoord & (1u << i)))
6949 continue;
6950
6951 if (texcoords_written_mask[i] != WINED3DSP_WRITEMASK_ALL)
6952 {
6953 if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info)
6954 && !texcoords_written_mask[i])
6955 continue;
6956
6957 shader_glsl_write_mask_to_str(~texcoords_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask);
6958 shader_addline(buffer, "%s[%u]%s = vec4(0.0)%s;\n",
6959 legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", i, reg_mask, reg_mask);
6960 }
6961 }
6962 }
6963 else
6964 {
6965 unsigned int in_count = min(vec4_varyings(ps_major, gl_info), ps->limits->packed_input);
6966
6968 shader_addline(buffer, "void setup_vs_output(in vec4 outputs[%u])\n{\n", vs->limits->packed_output);
6969 shader_glsl_setup_sm3_rasterizer_input(priv, gl_info, ps->u.ps.input_reg_map, &ps->input_signature,
6970 &ps->reg_maps, 0, &vs->output_signature, &vs->reg_maps, per_vertex_point_size);
6971 }
6972
6973 shader_addline(buffer, "}\n");
6974
6975 ret = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
6976 checkGLcall("glCreateShader(GL_VERTEX_SHADER)");
6977 shader_glsl_compile(gl_info, ret, buffer->buffer);
6978
6979 return ret;
6980}
6981
6983 const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc)
6984{
6986 unsigned int i;
6987
6988 shader_addline(buffer, "out shader_in_out\n{\n");
6989 for (i = 0; i < so_desc->element_count; ++i)
6990 {
6991 const struct wined3d_stream_output_element *e = &so_desc->elements[i];
6992
6993 if (e->stream_idx)
6994 {
6995 FIXME("Unhandled stream %u.\n", e->stream_idx);
6996 continue;
6997 }
6998 if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
6999 continue;
7000
7001 if (e->component_idx || e->component_count != 4)
7002 {
7003 if (e->component_count == 1)
7004 shader_addline(buffer, "float");
7005 else
7006 shader_addline(buffer, "vec%u", e->component_count);
7007 shader_addline(buffer, " reg%u_%u_%u;\n",
7008 e->register_idx, e->component_idx, e->component_idx + e->component_count - 1);
7009 }
7010 else
7011 {
7012 shader_addline(buffer, "vec4 reg%u;\n", e->register_idx);
7013 }
7014 }
7015 shader_addline(buffer, "} shader_out;\n");
7016
7017 shader_addline(buffer, "void setup_gs_output(in vec4 outputs[%u])\n{\n",
7018 shader->limits->packed_output);
7019 for (i = 0; i < so_desc->element_count; ++i)
7020 {
7021 const struct wined3d_stream_output_element *e = &so_desc->elements[i];
7022
7023 if (e->stream_idx)
7024 {
7025 FIXME("Unhandled stream %u.\n", e->stream_idx);
7026 continue;
7027 }
7028 if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
7029 continue;
7030
7031 if (e->component_idx || e->component_count != 4)
7032 {
7033 DWORD write_mask;
7034 char str_mask[6];
7035
7036 write_mask = ((1u << e->component_count) - 1) << e->component_idx;
7037 shader_glsl_write_mask_to_str(write_mask, str_mask);
7038 shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n",
7039 e->register_idx, e->component_idx, e->component_idx + e->component_count - 1,
7040 e->register_idx, str_mask);
7041 }
7042 else
7043 {
7044 shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n",
7045 e->register_idx, e->register_idx);
7046 }
7047 }
7048 shader_addline(buffer, "}\n");
7049}
7050
7052 const struct wined3d_shader *shader, unsigned int input_count,
7053 const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup, const DWORD *interpolation_mode)
7054{
7055 const char *prefix = shader_glsl_get_prefix(shader->reg_maps.shader_version.type);
7057
7058 if (rasterizer_setup)
7059 input_count = min(vec4_varyings(4, gl_info), input_count);
7060
7061 if (input_count)
7062 shader_glsl_declare_shader_outputs(gl_info, buffer, input_count, rasterizer_setup, interpolation_mode);
7063
7064 shader_addline(buffer, "void setup_%s_output(in vec4 outputs[%u])\n{\n",
7065 prefix, shader->limits->packed_output);
7066
7067 if (rasterizer_setup)
7069 NULL, input_count, &shader->output_signature, &shader->reg_maps, FALSE);
7070 else
7071 shader_glsl_setup_sm4_shader_output(priv, input_count, &shader->output_signature,
7072 &shader->reg_maps, "shader_out", rasterizer_setup);
7073
7074 shader_addline(buffer, "}\n");
7075}
7076
7078 const struct wined3d_shader_signature_element *constant, unsigned int *user_constant_idx,
7079 const char *reg_mask)
7080{
7081 if (!constant->sysval_semantic)
7082 {
7083 shader_addline(buffer, "user_patch_constant[%u]%s", (*user_constant_idx)++, reg_mask);
7084 return;
7085 }
7086
7087 switch (constant->sysval_semantic)
7088 {
7093 shader_addline(buffer, "gl_TessLevelOuter[%u]", constant->semantic_idx);
7094 break;
7097 shader_addline(buffer, "gl_TessLevelInner[%u]", constant->semantic_idx);
7098 break;
7099 default:
7100 FIXME("Unhandled sysval semantic %#x.\n", constant->sysval_semantic);
7101 shader_addline(buffer, "vec4(0.0)%s", reg_mask);
7102 }
7103}
7104
7106 const struct wined3d_shader_signature *signature, BOOL input_setup)
7107{
7108 unsigned int i, register_count, user_constant_index, user_constant_count;
7109
7110 register_count = user_constant_count = 0;
7111 for (i = 0; i < signature->element_count; ++i)
7112 {
7113 const struct wined3d_shader_signature_element *constant = &signature->elements[i];
7114 register_count = max(constant->register_idx + 1, register_count);
7115 if (!constant->sysval_semantic)
7116 ++user_constant_count;
7117 }
7118
7119 if (user_constant_count)
7120 shader_addline(buffer, "patch %s vec4 user_patch_constant[%u];\n",
7121 input_setup ? "in" : "out", user_constant_count);
7122 if (input_setup)
7123 shader_addline(buffer, "vec4 vpc[%u];\n", register_count);
7124
7125 shader_addline(buffer, "void setup_patch_constant_%s()\n{\n", input_setup ? "input" : "output");
7126 for (i = 0, user_constant_index = 0; i < signature->element_count; ++i)
7127 {
7128 const struct wined3d_shader_signature_element *constant = &signature->elements[i];
7129 char reg_mask[6];
7130
7131 shader_glsl_write_mask_to_str(constant->mask, reg_mask);
7132
7133 if (input_setup)
7134 shader_addline(buffer, "vpc[%u]%s", constant->register_idx, reg_mask);
7135 else
7136 shader_glsl_generate_patch_constant_name(buffer, constant, &user_constant_index, reg_mask);
7137
7138 shader_addline(buffer, " = ");
7139
7140 if (input_setup)
7141 shader_glsl_generate_patch_constant_name(buffer, constant, &user_constant_index, reg_mask);
7142 else
7143 shader_addline(buffer, "hs_out[%u]%s", constant->register_idx, reg_mask);
7144
7145 shader_addline(buffer, ";\n");
7146 }
7147 shader_addline(buffer, "}\n");
7148}
7149
7151 const struct wined3d_gl_info *gl_info)
7152{
7153 const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
7154
7155 shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(srgb_const0.x));\n", output);
7156 shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n");
7157 shader_addline(buffer, "tmp1.xyz = %s.xyz * vec3(srgb_const0.w);\n", output);
7158 shader_addline(buffer, "bvec3 srgb_compare = lessThan(%s.xyz, vec3(srgb_const1.x));\n", output);
7159 shader_addline(buffer, "%s.xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n", output);
7160 shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", output, output);
7161}
7162
7164 const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode)
7165{
7166 const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
7167
7168 switch (mode)
7169 {
7171 return;
7172
7174 shader_addline(buffer, "float fog = (ffp_fog.end - ffp_varying_fogcoord) * ffp_fog.scale;\n");
7175 break;
7176
7178 shader_addline(buffer, "float fog = exp(-ffp_fog.density * ffp_varying_fogcoord);\n");
7179 break;
7180
7182 shader_addline(buffer, "float fog = exp(-ffp_fog.density * ffp_fog.density"
7183 " * ffp_varying_fogcoord * ffp_varying_fogcoord);\n");
7184 break;
7185
7186 default:
7187 ERR("Invalid fog mode %#x.\n", mode);
7188 return;
7189 }
7190
7191 shader_addline(buffer, "%s.xyz = mix(ffp_fog.color.xyz, %s.xyz, clamp(fog, 0.0, 1.0));\n",
7192 output, output);
7193}
7194
7196 const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func)
7197{
7198 const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
7199
7200 /* alpha_func is the PASS condition, not the DISCARD condition. Instead of
7201 * flipping all the operators here, just negate the comparison below. */
7202 static const char * const comparison_operator[] =
7203 {
7204 "", /* WINED3D_CMP_NEVER */
7205 "<", /* WINED3D_CMP_LESS */
7206 "==", /* WINED3D_CMP_EQUAL */
7207 "<=", /* WINED3D_CMP_LESSEQUAL */
7208 ">", /* WINED3D_CMP_GREATER */
7209 "!=", /* WINED3D_CMP_NOTEQUAL */
7210 ">=", /* WINED3D_CMP_GREATEREQUAL */
7211 "" /* WINED3D_CMP_ALWAYS */
7212 };
7213
7214 if (alpha_func == WINED3D_CMP_ALWAYS)
7215 return;
7216
7217 if (alpha_func != WINED3D_CMP_NEVER)
7218 shader_addline(buffer, "if (!(%s.a %s alpha_test_ref))\n",
7219 output, comparison_operator[alpha_func - WINED3D_CMP_NEVER]);
7220 shader_addline(buffer, " discard;\n");
7221}
7222
7224 const struct wined3d_gl_info *gl_info)
7225{
7226 if (gl_info->supported[ARB_CULL_DISTANCE])
7227 shader_addline(buffer, "#extension GL_ARB_cull_distance : enable\n");
7228 if (gl_info->supported[ARB_GPU_SHADER5])
7229 shader_addline(buffer, "#extension GL_ARB_gpu_shader5 : enable\n");
7231 shader_addline(buffer, "#extension GL_ARB_shader_atomic_counters : enable\n");
7232 if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
7233 shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n");
7235 shader_addline(buffer, "#extension GL_ARB_shader_image_load_store : enable\n");
7236 if (gl_info->supported[ARB_SHADER_IMAGE_SIZE])
7237 shader_addline(buffer, "#extension GL_ARB_shader_image_size : enable\n");
7239 shader_addline(buffer, "#extension GL_ARB_shader_storage_buffer_object : enable\n");
7241 shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n");
7243 shader_addline(buffer, "#extension GL_ARB_shading_language_packing : enable\n");
7245 shader_addline(buffer, "#extension GL_ARB_texture_cube_map_array : enable\n");
7246 if (gl_info->supported[ARB_TEXTURE_GATHER])
7247 shader_addline(buffer, "#extension GL_ARB_texture_gather : enable\n");
7248 if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS])
7249 shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n");
7251 shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n");
7252 if (gl_info->supported[EXT_GPU_SHADER4])
7253 shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
7254 if (gl_info->supported[EXT_TEXTURE_ARRAY])
7255 shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n");
7256}
7257
7258static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info,
7259 struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
7260 const struct ps_compile_args *args)
7261{
7262 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7263 const char *output = needs_legacy_glsl_syntax(gl_info) ? "gl_FragData[0]" : "ps_out0";
7264
7265 /* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */
7266 if (reg_maps->shader_version.major < 2)
7267 shader_addline(buffer, "%s = R0;\n", output);
7268
7269 if (args->srgb_correction)
7271
7272 /* SM < 3 does not replace the fog stage. */
7273 if (reg_maps->shader_version.major < 3)
7275
7276 shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1);
7277}
7278
7279/* Context activation is done by the caller. */
7281 struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers,
7282 const struct wined3d_shader *shader,
7283 const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info)
7284{
7285 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7286 const struct wined3d_shader_version *version = &reg_maps->shader_version;
7287 const char *prefix = shader_glsl_get_prefix(version->type);
7288 const struct wined3d_gl_info *gl_info = context->gl_info;
7289 const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
7290 unsigned int i, extra_constants_needed = 0;
7291 struct shader_glsl_ctx_priv priv_ctx;
7292 GLuint shader_id;
7293 DWORD map;
7294
7295 memset(&priv_ctx, 0, sizeof(priv_ctx));
7296 priv_ctx.cur_ps_args = args;
7297 priv_ctx.cur_np2fixup_info = np2fixup_info;
7298 priv_ctx.string_buffers = string_buffers;
7299
7301
7303 if (gl_info->supported[ARB_CONSERVATIVE_DEPTH])
7304 shader_addline(buffer, "#extension GL_ARB_conservative_depth : enable\n");
7305 if (gl_info->supported[ARB_DERIVATIVE_CONTROL])
7306 shader_addline(buffer, "#extension GL_ARB_derivative_control : enable\n");
7308 shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
7310 shader_addline(buffer, "#extension GL_ARB_fragment_coord_conventions : enable\n");
7312 shader_addline(buffer, "#extension GL_ARB_fragment_layer_viewport : enable\n");
7313 if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
7314 shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
7315 /* The spec says that it doesn't have to be explicitly enabled, but the
7316 * nvidia drivers write a warning if we don't do so. */
7317 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
7318 shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
7319
7320 /* Base Declarations */
7322
7323 if (gl_info->supported[ARB_CONSERVATIVE_DEPTH])
7324 {
7325 if (shader->u.ps.depth_output == WINED3DSPR_DEPTHOUTGE)
7326 shader_addline(buffer, "layout (depth_greater) out float gl_FragDepth;\n");
7327 else if (shader->u.ps.depth_output == WINED3DSPR_DEPTHOUTLE)
7328 shader_addline(buffer, "layout (depth_less) out float gl_FragDepth;\n");
7329 }
7330
7331 /* Declare uniforms for NP2 texcoord fixup:
7332 * This is NOT done inside the loop that declares the texture samplers
7333 * since the NP2 fixup code is currently only used for the GeforceFX
7334 * series and when forcing the ARB_npot extension off. Modern cards just
7335 * skip the code anyway, so put it inside a separate loop. */
7336 if (args->np2_fixup)
7337 {
7338 struct ps_np2fixup_info *fixup = priv_ctx.cur_np2fixup_info;
7339 unsigned int cur = 0;
7340
7341 /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
7342 * while D3D has them in the (normalized) [0,1]x[0,1] range.
7343 * samplerNP2Fixup stores texture dimensions and is updated through
7344 * shader_glsl_load_np2fixup_constants when the sampler changes. */
7345
7346 for (i = 0; i < shader->limits->sampler; ++i)
7347 {
7348 if (!reg_maps->resource_info[i].type || !(args->np2_fixup & (1u << i)))
7349 continue;
7350
7351 if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
7352 {
7353 FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
7354 continue;
7355 }
7356
7357 fixup->idx[i] = cur++;
7358 }
7359
7360 fixup->num_consts = (cur + 1) >> 1;
7361 fixup->active = args->np2_fixup;
7362 shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
7363 }
7364
7365 if (version->major < 3 || args->vp_mode != vertexshader)
7366 {
7367 shader_addline(buffer, "uniform struct\n{\n");
7368 shader_addline(buffer, " vec4 color;\n");
7369 shader_addline(buffer, " float density;\n");
7370 shader_addline(buffer, " float end;\n");
7371 shader_addline(buffer, " float scale;\n");
7372 shader_addline(buffer, "} ffp_fog;\n");
7373
7374 if (needs_legacy_glsl_syntax(gl_info))
7375 {
7377 shader_addline(buffer, "vec4 ffp_varying_diffuse;\n");
7379 shader_addline(buffer, "vec4 ffp_varying_specular;\n");
7380 shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
7381 shader_addline(buffer, "float ffp_varying_fogcoord;\n");
7382 }
7383 else
7384 {
7386 declare_in_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_diffuse;\n");
7388 declare_in_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_specular;\n");
7389 declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
7390 shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
7391 declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
7392 }
7393 }
7394
7395 if (version->major >= 3)
7396 {
7397 unsigned int in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
7398
7399 if (args->vp_mode == vertexshader && reg_maps->input_registers)
7400 shader_glsl_declare_shader_inputs(gl_info, buffer, in_count,
7401 shader->u.ps.interpolation_mode, version->major >= 4);
7402 shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
7403 }
7404
7405 for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
7406 {
7407 if (!(map & 1))
7408 continue;
7409
7410 shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", i);
7411
7412 if (reg_maps->luminanceparams & (1u << i))
7413 {
7414 shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", i);
7415 shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", i);
7416 extra_constants_needed++;
7417 }
7418
7419 extra_constants_needed++;
7420 }
7421
7422 if (args->srgb_correction)
7423 {
7424 shader_addline(buffer, "const vec4 srgb_const0 = ");
7426 shader_addline(buffer, ";\n");
7427 shader_addline(buffer, "const vec4 srgb_const1 = ");
7429 shader_addline(buffer, ";\n");
7430 }
7431 if (reg_maps->vpos || reg_maps->usesdsy)
7432 {
7433 if (reg_maps->usesdsy || !gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS])
7434 {
7435 ++extra_constants_needed;
7436 shader_addline(buffer, "uniform vec4 ycorrection;\n");
7437 }
7438 if (reg_maps->vpos)
7439 {
7441 {
7442 if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER)
7443 shader_addline(buffer, "layout(%spixel_center_integer) in vec4 gl_FragCoord;\n",
7444 args->render_offscreen ? "" : "origin_upper_left, ");
7445 else if (!args->render_offscreen)
7446 shader_addline(buffer, "layout(origin_upper_left) in vec4 gl_FragCoord;\n");
7447 }
7448 shader_addline(buffer, "vec4 vpos;\n");
7449 }
7450 }
7451
7452 if (args->alpha_test_func + 1 != WINED3D_CMP_ALWAYS)
7453 shader_addline(buffer, "uniform float alpha_test_ref;\n");
7454
7455 if (!needs_legacy_glsl_syntax(gl_info))
7456 {
7457 if (args->dual_source_blend)
7458 {
7459 for (i = 0; i < gl_info->limits.dual_buffers * 2; i++)
7460 {
7462 shader_addline(buffer, "layout(location = %u, index = %u) ", i / 2, i % 2);
7463 shader_addline(buffer, "out vec4 ps_out%u;\n", i);
7464 }
7465 }
7466 else
7467 {
7468 for (i = 0; i < gl_info->limits.buffers; i++)
7469 {
7471 shader_addline(buffer, "layout(location = %u) ", i);
7472 shader_addline(buffer, "out vec4 ps_out%u;\n", i);
7473 }
7474 }
7475 }
7476
7477 if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants)
7478 FIXME("Insufficient uniforms to run this shader.\n");
7479
7480 if (shader->u.ps.force_early_depth_stencil)
7481 shader_addline(buffer, "layout(early_fragment_tests) in;\n");
7482
7483 shader_addline(buffer, "void main()\n{\n");
7484
7485 /* Direct3D applications expect integer vPos values, while OpenGL drivers
7486 * add approximately 0.5. This causes off-by-one problems as spotted by
7487 * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
7488 * 0.5, but rather something like 0.49999999 or 0.50000001, which still
7489 * causes precision troubles when we just subtract 0.5.
7490 *
7491 * To deal with that, just floor() the position. This will eliminate the
7492 * fraction on all cards.
7493 *
7494 * TODO: Test how this behaves with multisampling.
7495 *
7496 * An advantage of floor is that it works even if the driver doesn't add
7497 * 0.5. It is somewhat questionable if 1.5, 2.5, ... are the proper values
7498 * to return in gl_FragCoord, even though coordinates specify the pixel
7499 * centers instead of the pixel corners. This code will behave correctly
7500 * on drivers that returns integer values. */
7501 if (reg_maps->vpos)
7502 {
7504 shader_addline(buffer, "vpos = gl_FragCoord;\n");
7505 else if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER)
7507 "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n");
7508 else
7510 "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1);\n");
7511 }
7512
7513 if (reg_maps->shader_version.major < 3 || args->vp_mode != vertexshader)
7514 {
7515 unsigned int i;
7516 WORD map = reg_maps->texcoord;
7517
7518 if (legacy_syntax)
7519 {
7521 shader_addline(buffer, "ffp_varying_diffuse = gl_Color;\n");
7523 shader_addline(buffer, "ffp_varying_specular = gl_SecondaryColor;\n");
7524 }
7525
7526 for (i = 0; map; map >>= 1, ++i)
7527 {
7528 if (map & 1)
7529 {
7530 if (args->pointsprite)
7531 shader_addline(buffer, "ffp_texcoord[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", i);
7532 else if (args->texcoords_initialized & (1u << i))
7533 shader_addline(buffer, "ffp_texcoord[%u] = %s[%u];\n", i,
7534 legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", i);
7535 else
7536 shader_addline(buffer, "ffp_texcoord[%u] = vec4(0.0);\n", i);
7537 shader_addline(buffer, "vec4 T%u = ffp_texcoord[%u];\n", i, i);
7538 }
7539 }
7540
7541 if (legacy_syntax)
7542 shader_addline(buffer, "ffp_varying_fogcoord = gl_FogFragCoord;\n");
7543 }
7544
7545 /* Pack 3.0 inputs */
7546 if (reg_maps->shader_version.major >= 3)
7547 shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps, args, gl_info,
7548 reg_maps->shader_version.major >= 4);
7549
7550 /* Base Shader Body */
7551 if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
7552 return 0;
7553
7554 /* In SM4+ the shader epilogue is generated by the "ret" instruction. */
7555 if (reg_maps->shader_version.major < 4)
7557
7558 shader_addline(buffer, "}\n");
7559
7560 shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
7561 TRACE("Compiling shader object %u.\n", shader_id);
7562 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
7563
7564 return shader_id;
7565}
7566
7567static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_info,
7568 struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
7569 const struct vs_compile_args *args)
7570{
7571 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7572 const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
7573 unsigned int i;
7574
7575 /* Unpack outputs. */
7576 shader_addline(buffer, "setup_vs_output(vs_out);\n");
7577
7578 /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
7579 * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
7580 * the fog frag coord is thrown away. If the fog frag coord is used, but not written by
7581 * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0).
7582 */
7583 if (reg_maps->shader_version.major < 3)
7584 {
7585 if (args->fog_src == VS_FOG_Z)
7586 shader_addline(buffer, "%s = gl_Position.z;\n",
7587 legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
7588 else if (!reg_maps->fog)
7589 shader_addline(buffer, "%s = 0.0;\n",
7590 legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
7591 }
7592
7593 /* We always store the clipplanes without y inversion. */
7594 if (args->clip_enabled)
7595 {
7596 if (legacy_syntax)
7597 shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
7598 else
7599 for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
7600 shader_addline(buffer, "gl_ClipDistance[%u] = dot(gl_Position, clip_planes[%u]);\n", i, i);
7601 }
7602
7603 if (args->point_size && !args->per_vertex_point_size)
7604 shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
7605
7606 if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
7608}
7609
7610/* Context activation is done by the caller. */
7612 struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct vs_compile_args *args)
7613{
7614 struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers;
7615 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7616 const struct wined3d_shader_version *version = &reg_maps->shader_version;
7618 const struct wined3d_gl_info *gl_info = context->gl_info;
7619 struct shader_glsl_ctx_priv priv_ctx;
7620 GLuint shader_id;
7621 unsigned int i;
7622
7623 memset(&priv_ctx, 0, sizeof(priv_ctx));
7624 priv_ctx.cur_vs_args = args;
7625 priv_ctx.string_buffers = string_buffers;
7626
7628
7630 if (gl_info->supported[ARB_DRAW_INSTANCED])
7631 shader_addline(buffer, "#extension GL_ARB_draw_instanced : enable\n");
7633 shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
7634
7635 /* Base Declarations */
7637
7638 for (i = 0; i < shader->input_signature.element_count; ++i)
7639 shader_glsl_declare_generic_vertex_attribute(buffer, gl_info, &shader->input_signature.elements[i]);
7640
7641 if (args->point_size && !args->per_vertex_point_size)
7642 {
7643 shader_addline(buffer, "uniform struct\n{\n");
7644 shader_addline(buffer, " float size;\n");
7645 shader_addline(buffer, " float size_min;\n");
7646 shader_addline(buffer, " float size_max;\n");
7647 shader_addline(buffer, "} ffp_point;\n");
7648 }
7649
7650 if (!needs_legacy_glsl_syntax(gl_info))
7651 {
7652 if (args->clip_enabled)
7653 shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.user_clip_distances);
7654
7655 if (version->major < 3)
7656 {
7657 declare_out_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_diffuse;\n");
7658 declare_out_varying(gl_info, buffer, args->flatshading, "vec4 ffp_varying_specular;\n");
7659 declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
7660 declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
7661 }
7662 }
7663
7664 if (version->major < 4)
7665 shader_addline(buffer, "void setup_vs_output(in vec4[%u]);\n", shader->limits->packed_output);
7666
7667 if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
7668 shader_addline(buffer, "uniform vec4 pos_fixup;\n");
7669
7670 if (reg_maps->shader_version.major >= 4)
7671 shader_glsl_generate_sm4_output_setup(priv, shader, args->next_shader_input_count,
7672 gl_info, args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL, args->interpolation_mode);
7673
7674 shader_addline(buffer, "void main()\n{\n");
7675
7676 if (reg_maps->input_rel_addressing)
7677 {
7678 unsigned int highest_input_register = wined3d_log2i(reg_maps->input_registers);
7679 shader_addline(buffer, "vec4 vs_in[%u];\n", highest_input_register + 1);
7680 for (i = 0; i < shader->input_signature.element_count; ++i)
7681 {
7682 const struct wined3d_shader_signature_element *e = &shader->input_signature.elements[i];
7683 shader_addline(buffer, "vs_in[%u] = vs_in%u;\n", e->register_idx, e->register_idx);
7684 }
7685 }
7686
7687 if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
7688 return 0;
7689
7690 /* In SM4+ the shader epilogue is generated by the "ret" instruction. */
7691 if (reg_maps->shader_version.major < 4)
7693
7694 shader_addline(buffer, "}\n");
7695
7696 shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
7697 TRACE("Compiling shader object %u.\n", shader_id);
7698 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
7699
7700 return shader_id;
7701}
7702
7704 struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps)
7705{
7706 const struct wined3d_shader_signature *output_signature = &shader->output_signature;
7707 char reg_mask[6];
7708 unsigned int i;
7709
7710 for (i = 0; i < output_signature->element_count; ++i)
7711 {
7712 const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
7713
7714 shader_glsl_write_mask_to_str(output->mask, reg_mask);
7715 shader_addline(buffer, "shader_out[gl_InvocationID].reg[%u]%s = shader_in[gl_InvocationID].reg[%u]%s;\n",
7716 output->register_idx, reg_mask, output->register_idx, reg_mask);
7717 }
7718}
7719
7721 struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps,
7722 struct shader_glsl_ctx_priv *priv_ctx, const struct wined3d_shader_phase *phase,
7723 const char *phase_name, unsigned phase_idx)
7724{
7725 unsigned int i;
7726 HRESULT hr;
7727
7728 shader_addline(buffer, "void hs_%s_phase%u(%s)\n{\n",
7729 phase_name, phase_idx, phase->instance_count ? "int phase_instance_id" : "");
7730 for (i = 0; i < phase->temporary_count; ++i)
7731 shader_addline(buffer, "vec4 R%u;\n", i);
7732 hr = shader_generate_code(shader, buffer, reg_maps, priv_ctx, phase->start, phase->end);
7733 shader_addline(buffer, "}\n");
7734 return hr;
7735}
7736
7738 const struct wined3d_shader_phase *phase, const char *phase_name, unsigned int phase_idx)
7739{
7740 if (phase->instance_count)
7741 {
7742 shader_addline(buffer, "for (int i = 0; i < %u; ++i)\n{\n", phase->instance_count);
7743 shader_addline(buffer, "hs_%s_phase%u(i);\n", phase_name, phase_idx);
7744 shader_addline(buffer, "}\n");
7745 }
7746 else
7747 {
7748 shader_addline(buffer, "hs_%s_phase%u();\n", phase_name, phase_idx);
7749 }
7750}
7751
7753 struct shader_glsl_priv *priv, const struct wined3d_shader *shader)
7754{
7755 struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers;
7756 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7758 const struct wined3d_gl_info *gl_info = context->gl_info;
7759 const struct wined3d_hull_shader *hs = &shader->u.hs;
7760 const struct wined3d_shader_phase *phase;
7761 struct shader_glsl_ctx_priv priv_ctx;
7762 GLuint shader_id;
7763 unsigned int i;
7764
7765 memset(&priv_ctx, 0, sizeof(priv_ctx));
7766 priv_ctx.string_buffers = string_buffers;
7767
7769
7771 shader_addline(buffer, "#extension GL_ARB_tessellation_shader : enable\n");
7772
7774
7775 shader_addline(buffer, "layout(vertices = %u) out;\n", hs->output_vertex_count);
7776
7777 shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
7778 shader_addline(buffer, "out shader_in_out { vec4 reg[%u]; } shader_out[];\n", shader->limits->packed_output);
7779
7780 shader_glsl_generate_patch_constant_setup(buffer, &shader->patch_constant_signature, FALSE);
7781
7782 if (hs->phases.control_point)
7783 {
7784 shader_addline(buffer, "void setup_hs_output(in vec4 outputs[%u])\n{\n",
7785 shader->limits->packed_output);
7786 shader_glsl_setup_sm4_shader_output(priv, shader->limits->packed_output, &shader->output_signature,
7787 &shader->reg_maps, "shader_out[gl_InvocationID]", FALSE);
7788 shader_addline(buffer, "}\n");
7789 }
7790
7791 shader_addline(buffer, "void hs_control_point_phase()\n{\n");
7792 if ((phase = hs->phases.control_point))
7793 {
7794 for (i = 0; i < phase->temporary_count; ++i)
7795 shader_addline(buffer, "vec4 R%u;\n", i);
7796 if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, phase->start, phase->end)))
7797 return 0;
7798 shader_addline(buffer, "setup_hs_output(hs_out);\n");
7799 }
7800 else
7801 {
7803 }
7804 shader_addline(buffer, "}\n");
7805
7806 for (i = 0; i < hs->phases.fork_count; ++i)
7807 {
7808 if (FAILED(shader_glsl_generate_shader_phase(shader, buffer, reg_maps, &priv_ctx,
7809 &hs->phases.fork[i], "fork", i)))
7810 return 0;
7811 }
7812
7813 for (i = 0; i < hs->phases.join_count; ++i)
7814 {
7815 if (FAILED(shader_glsl_generate_shader_phase(shader, buffer, reg_maps, &priv_ctx,
7816 &hs->phases.join[i], "join", i)))
7817 return 0;
7818 }
7819
7820 shader_addline(buffer, "void main()\n{\n");
7821 shader_addline(buffer, "hs_control_point_phase();\n");
7822 if (reg_maps->vocp)
7823 shader_addline(buffer, "barrier();\n");
7824 for (i = 0; i < hs->phases.fork_count; ++i)
7826 for (i = 0; i < hs->phases.join_count; ++i)
7828 shader_addline(buffer, "setup_patch_constant_output();\n");
7829 shader_addline(buffer, "}\n");
7830
7831 shader_id = GL_EXTCALL(glCreateShader(GL_TESS_CONTROL_SHADER));
7832 TRACE("Compiling shader object %u.\n", shader_id);
7833 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
7834
7835 return shader_id;
7836}
7837
7838static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_info,
7839 struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
7840 const struct ds_compile_args *args)
7841{
7842 shader_addline(buffer, "setup_ds_output(ds_out);\n");
7843
7844 if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
7846}
7847
7849 struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct ds_compile_args *args)
7850{
7851 struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers;
7852 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7854 const struct wined3d_gl_info *gl_info = context->gl_info;
7855 struct shader_glsl_ctx_priv priv_ctx;
7856 GLuint shader_id;
7857
7858 memset(&priv_ctx, 0, sizeof(priv_ctx));
7859 priv_ctx.cur_ds_args = args;
7860 priv_ctx.string_buffers = string_buffers;
7861
7863
7865 shader_addline(buffer, "#extension GL_ARB_tessellation_shader : enable\n");
7866
7868
7869 shader_addline(buffer, "layout(");
7870 switch (shader->u.ds.tessellator_domain)
7871 {
7873 shader_addline(buffer, "isolines");
7874 break;
7876 shader_addline(buffer, "quads");
7877 break;
7879 shader_addline(buffer, "triangles");
7880 break;
7881 }
7882 switch (args->tessellator_output_primitive)
7883 {
7885 if (args->render_offscreen)
7886 shader_addline(buffer, ", ccw");
7887 else
7888 shader_addline(buffer, ", cw");
7889 break;
7891 if (args->render_offscreen)
7892 shader_addline(buffer, ", cw");
7893 else
7894 shader_addline(buffer, ", ccw");
7895 break;
7897 shader_addline(buffer, ", point_mode");
7898 break;
7900 break;
7901 }
7902 switch (args->tessellator_partitioning)
7903 {
7905 shader_addline(buffer, ", fractional_odd_spacing");
7906 break;
7908 shader_addline(buffer, ", fractional_even_spacing");
7909 break;
7912 shader_addline(buffer, ", equal_spacing");
7913 break;
7914 }
7915 shader_addline(buffer, ") in;\n");
7916
7917 shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
7918
7919 if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
7920 shader_addline(buffer, "uniform vec4 pos_fixup;\n");
7921
7922 shader_glsl_generate_sm4_output_setup(priv, shader, args->output_count, gl_info,
7923 args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL, args->interpolation_mode);
7924 shader_glsl_generate_patch_constant_setup(buffer, &shader->patch_constant_signature, TRUE);
7925
7926 shader_addline(buffer, "void main()\n{\n");
7927 shader_addline(buffer, "setup_patch_constant_input();\n");
7928
7929 if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
7930 return 0;
7931
7932 shader_addline(buffer, "}\n");
7933
7934 shader_id = GL_EXTCALL(glCreateShader(GL_TESS_EVALUATION_SHADER));
7935 TRACE("Compiling shader object %u.\n", shader_id);
7936 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
7937
7938 return shader_id;
7939}
7940
7941/* Context activation is done by the caller. */
7943 struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct gs_compile_args *args)
7944{
7945 struct wined3d_string_buffer_list *string_buffers = &priv->string_buffers;
7946 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
7948 const struct wined3d_gl_info *gl_info = context->gl_info;
7949 struct shader_glsl_ctx_priv priv_ctx;
7950 GLuint shader_id;
7951
7952 memset(&priv_ctx, 0, sizeof(priv_ctx));
7953 priv_ctx.string_buffers = string_buffers;
7954
7956
7958
7960
7961 shader_addline(buffer, "layout(%s", glsl_primitive_type_from_d3d(shader->u.gs.input_type));
7962 if (shader->u.gs.instance_count > 1)
7963 shader_addline(buffer, ", invocations = %u", shader->u.gs.instance_count);
7964 shader_addline(buffer, ") in;\n");
7965 shader_addline(buffer, "layout(%s, max_vertices = %u) out;\n",
7966 glsl_primitive_type_from_d3d(shader->u.gs.output_type), shader->u.gs.vertices_out);
7967 shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
7968
7969 if (!gl_info->supported[ARB_CLIP_CONTROL])
7970 shader_addline(buffer, "uniform vec4 pos_fixup;\n");
7971
7973 {
7975 }
7976 else
7977 {
7979 gl_info, TRUE, args->interpolation_mode);
7980 }
7981 shader_addline(buffer, "void main()\n{\n");
7982 if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL)))
7983 return 0;
7984 shader_addline(buffer, "}\n");
7985
7986 shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
7987 TRACE("Compiling shader object %u.\n", shader_id);
7988 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
7989
7990 return shader_id;
7991}
7992
7994{
7995 const struct shader_glsl_ctx_priv *priv = ctx->backend_data;
7996 const struct wined3d_gl_info *gl_info = ctx->gl_info;
7997 struct wined3d_string_buffer *buffer = ctx->buffer;
7998 const struct wined3d_shader *shader = ctx->shader;
7999
8000 switch (shader->reg_maps.shader_version.type)
8001 {
8004 break;
8007 break;
8010 break;
8013 break;
8014 default:
8015 FIXME("Unhandled shader type %#x.\n", shader->reg_maps.shader_version.type);
8016 break;
8017 }
8018}
8019
8020/* Context activation is done by the caller. */
8022 struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers,
8023 const struct wined3d_shader *shader)
8024{
8025 const struct wined3d_shader_thread_group_size *thread_group_size = &shader->u.cs.thread_group_size;
8026 const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
8027 const struct wined3d_gl_info *gl_info = context->gl_info;
8028 struct shader_glsl_ctx_priv priv_ctx;
8029 GLuint shader_id;
8030 unsigned int i;
8031
8032 memset(&priv_ctx, 0, sizeof(priv_ctx));
8033 priv_ctx.string_buffers = string_buffers;
8034
8036
8038 shader_addline(buffer, "#extension GL_ARB_compute_shader : enable\n");
8039
8041
8042 for (i = 0; i < reg_maps->tgsm_count; ++i)
8043 {
8044 if (reg_maps->tgsm[i].size)
8045 shader_addline(buffer, "shared uint cs_g%u[%u];\n", i, reg_maps->tgsm[i].size);
8046 }
8047
8048 shader_addline(buffer, "layout(local_size_x = %u, local_size_y = %u, local_size_z = %u) in;\n",
8049 thread_group_size->x, thread_group_size->y, thread_group_size->z);
8050
8051 shader_addline(buffer, "void main()\n{\n");
8052 shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL);
8053 shader_addline(buffer, "}\n");
8054
8055 shader_id = GL_EXTCALL(glCreateShader(GL_COMPUTE_SHADER));
8056 TRACE("Compiling shader object %u.\n", shader_id);
8057 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
8058
8059 return shader_id;
8060}
8061
8064 struct wined3d_shader *shader,
8065 const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
8066{
8067 struct glsl_ps_compiled_shader *gl_shaders, *new_array;
8068 struct glsl_shader_private *shader_data;
8069 struct ps_np2fixup_info *np2fixup;
8070 UINT i;
8071 DWORD new_size;
8072 GLuint ret;
8073
8074 if (!shader->backend_data)
8075 {
8076 if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
8077 {
8078 ERR("Failed to allocate backend data.\n");
8079 return 0;
8080 }
8081 }
8082 shader_data = shader->backend_data;
8083 gl_shaders = shader_data->gl_shaders.ps;
8084
8085 /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
8086 * so a linear search is more performant than a hashmap or a binary search
8087 * (cache coherency etc)
8088 */
8089 for (i = 0; i < shader_data->num_gl_shaders; ++i)
8090 {
8091 if (!memcmp(&gl_shaders[i].args, args, sizeof(*args)))
8092 {
8093 if (args->np2_fixup)
8094 *np2fixup_info = &gl_shaders[i].np2fixup;
8095 return gl_shaders[i].id;
8096 }
8097 }
8098
8099 TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
8100 if (shader_data->shader_array_size == shader_data->num_gl_shaders)
8101 {
8102 if (shader_data->num_gl_shaders)
8103 {
8104 new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
8105 new_array = heap_realloc(shader_data->gl_shaders.ps, new_size * sizeof(*gl_shaders));
8106 }
8107 else
8108 {
8109 new_array = heap_alloc(sizeof(*gl_shaders));
8110 new_size = 1;
8111 }
8112
8113 if(!new_array) {
8114 ERR("Out of memory\n");
8115 return 0;
8116 }
8117 shader_data->gl_shaders.ps = new_array;
8118 shader_data->shader_array_size = new_size;
8119 gl_shaders = new_array;
8120 }
8121
8122 gl_shaders[shader_data->num_gl_shaders].args = *args;
8123
8124 np2fixup = &gl_shaders[shader_data->num_gl_shaders].np2fixup;
8125 memset(np2fixup, 0, sizeof(*np2fixup));
8126 *np2fixup_info = args->np2_fixup ? np2fixup : NULL;
8127
8129
8131 ret = shader_glsl_generate_pshader(context, buffer, string_buffers, shader, args, np2fixup);
8132 gl_shaders[shader_data->num_gl_shaders++].id = ret;
8133
8134 return ret;
8135}
8136
8137static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new,
8138 const DWORD use_map)
8139{
8140 if((stored->swizzle_map & use_map) != new->swizzle_map) return FALSE;
8141 if((stored->clip_enabled) != new->clip_enabled) return FALSE;
8142 if (stored->point_size != new->point_size)
8143 return FALSE;
8144 if (stored->per_vertex_point_size != new->per_vertex_point_size)
8145 return FALSE;
8146 if (stored->flatshading != new->flatshading)
8147 return FALSE;
8148 if (stored->next_shader_type != new->next_shader_type)
8149 return FALSE;
8150 if (stored->next_shader_input_count != new->next_shader_input_count)
8151 return FALSE;
8152 return stored->fog_src == new->fog_src;
8153}
8154
8156 struct wined3d_shader *shader, const struct vs_compile_args *args)
8157{
8158 UINT i;
8159 DWORD new_size;
8160 DWORD use_map = context->stream_info.use_map;
8161 struct glsl_vs_compiled_shader *gl_shaders, *new_array;
8162 struct glsl_shader_private *shader_data;
8163 GLuint ret;
8164
8165 if (!shader->backend_data)
8166 {
8167 if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
8168 {
8169 ERR("Failed to allocate backend data.\n");
8170 return 0;
8171 }
8172 }
8173 shader_data = shader->backend_data;
8174 gl_shaders = shader_data->gl_shaders.vs;
8175
8176 /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
8177 * so a linear search is more performant than a hashmap or a binary search
8178 * (cache coherency etc)
8179 */
8180 for (i = 0; i < shader_data->num_gl_shaders; ++i)
8181 {
8182 if (vs_args_equal(&gl_shaders[i].args, args, use_map))
8183 return gl_shaders[i].id;
8184 }
8185
8186 TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
8187
8188 if (shader_data->shader_array_size == shader_data->num_gl_shaders)
8189 {
8190 if (shader_data->num_gl_shaders)
8191 {
8192 new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
8193 new_array = heap_realloc(shader_data->gl_shaders.vs, new_size * sizeof(*gl_shaders));
8194 }
8195 else
8196 {
8197 new_array = heap_alloc(sizeof(*gl_shaders));
8198 new_size = 1;
8199 }
8200
8201 if(!new_array) {
8202 ERR("Out of memory\n");
8203 return 0;
8204 }
8205 shader_data->gl_shaders.vs = new_array;
8206 shader_data->shader_array_size = new_size;
8207 gl_shaders = new_array;
8208 }
8209
8210 gl_shaders[shader_data->num_gl_shaders].args = *args;
8211
8214 gl_shaders[shader_data->num_gl_shaders++].id = ret;
8215
8216 return ret;
8217}
8218
8220 struct shader_glsl_priv *priv, struct wined3d_shader *shader)
8221{
8222 struct glsl_hs_compiled_shader *gl_shaders, *new_array;
8223 struct glsl_shader_private *shader_data;
8224 unsigned int new_size;
8225 GLuint ret;
8226
8227 if (!shader->backend_data)
8228 {
8229 if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
8230 {
8231 ERR("Failed to allocate backend data.\n");
8232 return 0;
8233 }
8234 }
8235 shader_data = shader->backend_data;
8236 gl_shaders = shader_data->gl_shaders.hs;
8237
8238 if (shader_data->num_gl_shaders > 0)
8239 {
8240 assert(shader_data->num_gl_shaders == 1);
8241 return gl_shaders[0].id;
8242 }
8243
8244 TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
8245
8246 assert(!shader_data->gl_shaders.hs);
8247 new_size = 1;
8248 if (!(new_array = heap_alloc(sizeof(*new_array))))
8249 {
8250 ERR("Failed to allocate GL shaders array.\n");
8251 return 0;
8252 }
8253 shader_data->gl_shaders.hs = new_array;
8254 shader_data->shader_array_size = new_size;
8255 gl_shaders = new_array;
8256
8259 gl_shaders[shader_data->num_gl_shaders++].id = ret;
8260
8261 return ret;
8262}
8263
8265 struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct ds_compile_args *args)
8266{
8267 struct glsl_ds_compiled_shader *gl_shaders, *new_array;
8268 struct glsl_shader_private *shader_data;
8269 unsigned int i, new_size;
8270 GLuint ret;
8271
8272 if (!shader->backend_data)
8273 {
8274 if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
8275 {
8276 ERR("Failed to allocate backend data.\n");
8277 return 0;
8278 }
8279 }
8280 shader_data = shader->backend_data;
8281 gl_shaders = shader_data->gl_shaders.ds;
8282
8283 for (i = 0; i < shader_data->num_gl_shaders; ++i)
8284 {
8285 if (!memcmp(&gl_shaders[i].args, args, sizeof(*args)))
8286 return gl_shaders[i].id;
8287 }
8288
8289 TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
8290
8291 if (shader_data->num_gl_shaders)
8292 {
8293 new_size = shader_data->shader_array_size + 1;
8294 new_array = heap_realloc(shader_data->gl_shaders.ds, new_size * sizeof(*new_array));
8295 }
8296 else
8297 {
8298 new_array = heap_alloc(sizeof(*new_array));
8299 new_size = 1;
8300 }
8301
8302 if (!new_array)
8303 {
8304 ERR("Failed to allocate GL shaders array.\n");
8305 return 0;
8306 }
8307 shader_data->gl_shaders.ds = new_array;
8308 shader_data->shader_array_size = new_size;
8309 gl_shaders = new_array;
8310
8313 gl_shaders[shader_data->num_gl_shaders].args = *args;
8314 gl_shaders[shader_data->num_gl_shaders++].id = ret;
8315
8316 return ret;
8317}
8318
8320 struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct gs_compile_args *args)
8321{
8322 struct glsl_gs_compiled_shader *gl_shaders, *new_array;
8323 struct glsl_shader_private *shader_data;
8324 unsigned int i, new_size;
8325 GLuint ret;
8326
8327 if (!shader->backend_data)
8328 {
8329 if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
8330 {
8331 ERR("Failed to allocate backend data.\n");
8332 return 0;
8333 }
8334 }
8335 shader_data = shader->backend_data;
8336 gl_shaders = shader_data->gl_shaders.gs;
8337
8338 for (i = 0; i < shader_data->num_gl_shaders; ++i)
8339 {
8340 if (!memcmp(&gl_shaders[i].args, args, sizeof(*args)))
8341 return gl_shaders[i].id;
8342 }
8343
8344 TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
8345
8346 if (shader_data->num_gl_shaders)
8347 {
8348 new_size = shader_data->shader_array_size + 1;
8349 new_array = heap_realloc(shader_data->gl_shaders.gs, new_size * sizeof(*new_array));
8350 }
8351 else
8352 {
8353 new_array = heap_alloc(sizeof(*new_array));
8354 new_size = 1;
8355 }
8356
8357 if (!new_array)
8358 {
8359 ERR("Failed to allocate GL shaders array.\n");
8360 return 0;
8361 }
8362 shader_data->gl_shaders.gs = new_array;
8363 shader_data->shader_array_size = new_size;
8364 gl_shaders = new_array;
8365
8368 gl_shaders[shader_data->num_gl_shaders].args = *args;
8369 gl_shaders[shader_data->num_gl_shaders++].id = ret;
8370
8371 return ret;
8372}
8373
8374static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, const char *material)
8375{
8376 switch (mcs)
8377 {
8379 return material;
8380 case WINED3D_MCS_COLOR1:
8381 return "ffp_attrib_diffuse";
8382 case WINED3D_MCS_COLOR2:
8383 return "ffp_attrib_specular";
8384 default:
8385 ERR("Invalid material color source %#x.\n", mcs);
8386 return "<invalid>";
8387 }
8388}
8389
8391 const struct wined3d_ffp_vs_settings *settings, unsigned int idx)
8392{
8393 shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)"
8394 " * ffp_light[%u].diffuse.xyz * att;\n", idx);
8395 if (settings->localviewer)
8396 shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
8397 else
8398 shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n");
8399 shader_addline(buffer, "if (dot(dir, normal) > 0.0 && t > 0.0) specular +="
8400 " pow(t, ffp_material.shininess) * ffp_light[%u].specular * att;\n", idx);
8401}
8402
8404 const struct wined3d_ffp_vs_settings *settings, BOOL legacy_lighting)
8405{
8406 const char *diffuse, *specular, *emissive, *ambient;
8407 unsigned int i, idx;
8408
8409 if (!settings->lighting)
8410 {
8411 shader_addline(buffer, "ffp_varying_diffuse = ffp_attrib_diffuse;\n");
8412 shader_addline(buffer, "ffp_varying_specular = ffp_attrib_specular;\n");
8413 return;
8414 }
8415
8416 shader_addline(buffer, "vec3 ambient = ffp_light_ambient;\n");
8417 shader_addline(buffer, "vec3 diffuse = vec3(0.0);\n");
8418 shader_addline(buffer, "vec4 specular = vec4(0.0);\n");
8419 shader_addline(buffer, "vec3 dir, dst;\n");
8420 shader_addline(buffer, "float att, t;\n");
8421
8422 ambient = shader_glsl_ffp_mcs(settings->ambient_source, "ffp_material.ambient");
8423 diffuse = shader_glsl_ffp_mcs(settings->diffuse_source, "ffp_material.diffuse");
8424 specular = shader_glsl_ffp_mcs(settings->specular_source, "ffp_material.specular");
8425 emissive = shader_glsl_ffp_mcs(settings->emissive_source, "ffp_material.emissive");
8426
8427 idx = 0;
8428 for (i = 0; i < settings->point_light_count; ++i, ++idx)
8429 {
8430 shader_addline(buffer, "dir = ffp_light[%u].position.xyz - ec_pos.xyz;\n", idx);
8431 shader_addline(buffer, "dst.z = dot(dir, dir);\n");
8432 shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
8433 shader_addline(buffer, "dst.x = 1.0;\n");
8434 if (legacy_lighting)
8435 {
8436 shader_addline(buffer, "dst.y = (ffp_light[%u].range - dst.y) / ffp_light[%u].range;\n", idx, idx);
8437 shader_addline(buffer, "dst.z = dst.y * dst.y;\n");
8438 shader_addline(buffer, "if (dst.y > 0.0)\n{\n");
8439 }
8440 else
8441 {
8442 shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", idx);
8443 }
8444 shader_addline(buffer, "att = dot(dst.xyz, vec3(ffp_light[%u].c_att,"
8445 " ffp_light[%u].l_att, ffp_light[%u].q_att));\n", idx, idx, idx);
8446 if (!legacy_lighting)
8447 shader_addline(buffer, "att = 1.0 / att;\n");
8448 shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz * att;\n", idx);
8449 if (!settings->normal)
8450 {
8451 shader_addline(buffer, "}\n");
8452 continue;
8453 }
8454 shader_addline(buffer, "dir = normalize(dir);\n");
8456 shader_addline(buffer, "}\n");
8457 }
8458
8459 for (i = 0; i < settings->spot_light_count; ++i, ++idx)
8460 {
8461 shader_addline(buffer, "dir = ffp_light[%u].position.xyz - ec_pos.xyz;\n", idx);
8462 shader_addline(buffer, "dst.z = dot(dir, dir);\n");
8463 shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
8464 shader_addline(buffer, "dst.x = 1.0;\n");
8465 if (legacy_lighting)
8466 {
8467 shader_addline(buffer, "dst.y = (ffp_light[%u].range - dst.y) / ffp_light[%u].range;\n", idx, idx);
8468 shader_addline(buffer, "dst.z = dst.y * dst.y;\n");
8469 shader_addline(buffer, "if (dst.y > 0.0)\n{\n");
8470 }
8471 else
8472 {
8473 shader_addline(buffer, "if (dst.y <= ffp_light[%u].range)\n{\n", idx);
8474 }
8475 shader_addline(buffer, "dir = normalize(dir);\n");
8476 shader_addline(buffer, "t = dot(-dir, normalize(ffp_light[%u].direction));\n", idx);
8477 shader_addline(buffer, "if (t > ffp_light[%u].cos_htheta) att = 1.0;\n", idx);
8478 shader_addline(buffer, "else if (t <= ffp_light[%u].cos_hphi) att = 0.0;\n", idx);
8479 shader_addline(buffer, "else att = pow((t - ffp_light[%u].cos_hphi)"
8480 " / (ffp_light[%u].cos_htheta - ffp_light[%u].cos_hphi), ffp_light[%u].falloff);\n",
8481 idx, idx, idx, idx);
8482 if (legacy_lighting)
8483 shader_addline(buffer, "att *= dot(dst.xyz, vec3(ffp_light[%u].c_att,"
8484 " ffp_light[%u].l_att, ffp_light[%u].q_att));\n",
8485 idx, idx, idx);
8486 else
8487 shader_addline(buffer, "att /= dot(dst.xyz, vec3(ffp_light[%u].c_att,"
8488 " ffp_light[%u].l_att, ffp_light[%u].q_att));\n",
8489 idx, idx, idx);
8490 shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz * att;\n", idx);
8491 if (!settings->normal)
8492 {
8493 shader_addline(buffer, "}\n");
8494 continue;
8495 }
8497 shader_addline(buffer, "}\n");
8498 }
8499
8500 for (i = 0; i < settings->directional_light_count; ++i, ++idx)
8501 {
8502 shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", idx);
8503 if (!settings->normal)
8504 continue;
8505 shader_addline(buffer, "att = 1.0;\n");
8506 shader_addline(buffer, "dir = normalize(ffp_light[%u].direction.xyz);\n", idx);
8508 }
8509
8510 for (i = 0; i < settings->parallel_point_light_count; ++i, ++idx)
8511 {
8512 shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", idx);
8513 if (!settings->normal)
8514 continue;
8515 shader_addline(buffer, "att = 1.0;\n");
8516 shader_addline(buffer, "dir = normalize(ffp_light[%u].position.xyz);\n", idx);
8518 }
8519
8520 shader_addline(buffer, "ffp_varying_diffuse.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
8521 ambient, diffuse, emissive);
8522 shader_addline(buffer, "ffp_varying_diffuse.w = %s.w;\n", diffuse);
8523 shader_addline(buffer, "ffp_varying_specular = %s * specular;\n", specular);
8524}
8525
8526/* Context activation is done by the caller. */
8528 const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
8529{
8530 static const struct attrib_info
8531 {
8532 const char type[6];
8533 const char name[24];
8534 }
8535 attrib_info[] =
8536 {
8537 {"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */
8538 {"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */
8539 {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */
8540 {"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */
8541 {"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */
8542 {"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */
8543 {"vec4", "ffp_attrib_specular"}, /* WINED3D_FFP_SPECULAR */
8544 };
8545 const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
8547 BOOL output_legacy_fogcoord = legacy_syntax;
8548 BOOL legacy_lighting = priv->legacy_lighting;
8549 GLuint shader_obj;
8550 unsigned int i;
8551 char var[64];
8552
8554
8556
8558 shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
8559
8560 for (i = 0; i < WINED3D_FFP_ATTRIBS_COUNT; ++i)
8561 {
8562 const char *type = i < ARRAY_SIZE(attrib_info) ? attrib_info[i].type : "vec4";
8563
8565 shader_addline(buffer, "layout(location = %u) ", i);
8566 shader_addline(buffer, "%s %s vs_in%u;\n", get_attribute_keyword(gl_info), type, i);
8567 }
8568 shader_addline(buffer, "\n");
8569
8570 shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
8571 shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n", MAX_VERTEX_INDEX_BLENDS);
8572 shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
8573 shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES);
8574
8575 shader_addline(buffer, "uniform struct\n{\n");
8576 shader_addline(buffer, " vec4 emissive;\n");
8577 shader_addline(buffer, " vec4 ambient;\n");
8578 shader_addline(buffer, " vec4 diffuse;\n");
8579 shader_addline(buffer, " vec4 specular;\n");
8580 shader_addline(buffer, " float shininess;\n");
8581 shader_addline(buffer, "} ffp_material;\n");
8582
8583 shader_addline(buffer, "uniform vec3 ffp_light_ambient;\n");
8584 shader_addline(buffer, "uniform struct\n{\n");
8585 shader_addline(buffer, " vec4 diffuse;\n");
8586 shader_addline(buffer, " vec4 specular;\n");
8587 shader_addline(buffer, " vec4 ambient;\n");
8588 shader_addline(buffer, " vec4 position;\n");
8589 shader_addline(buffer, " vec3 direction;\n");
8590 shader_addline(buffer, " float range;\n");
8591 shader_addline(buffer, " float falloff;\n");
8592 shader_addline(buffer, " float c_att;\n");
8593 shader_addline(buffer, " float l_att;\n");
8594 shader_addline(buffer, " float q_att;\n");
8595 shader_addline(buffer, " float cos_htheta;\n");
8596 shader_addline(buffer, " float cos_hphi;\n");
8597 shader_addline(buffer, "} ffp_light[%u];\n", MAX_ACTIVE_LIGHTS);
8598
8599 if (settings->point_size)
8600 {
8601 shader_addline(buffer, "uniform struct\n{\n");
8602 shader_addline(buffer, " float size;\n");
8603 shader_addline(buffer, " float size_min;\n");
8604 shader_addline(buffer, " float size_max;\n");
8605 shader_addline(buffer, " float c_att;\n");
8606 shader_addline(buffer, " float l_att;\n");
8607 shader_addline(buffer, " float q_att;\n");
8608 shader_addline(buffer, "} ffp_point;\n");
8609 }
8610
8611 if (legacy_syntax)
8612 {
8613 shader_addline(buffer, "vec4 ffp_varying_diffuse;\n");
8614 shader_addline(buffer, "vec4 ffp_varying_specular;\n");
8615 shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
8616 shader_addline(buffer, "float ffp_varying_fogcoord;\n");
8617 }
8618 else
8619 {
8620 if (settings->clipping)
8621 shader_addline(buffer, "uniform vec4 clip_planes[%u];\n", gl_info->limits.user_clip_distances);
8622
8623 declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n");
8624 declare_out_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n");
8625 declare_out_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
8626 declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
8627 }
8628
8629 shader_addline(buffer, "\nvoid main()\n{\n");
8630 shader_addline(buffer, "float m;\n");
8631 shader_addline(buffer, "vec3 r;\n");
8632
8633 for (i = 0; i < ARRAY_SIZE(attrib_info); ++i)
8634 {
8635 if (attrib_info[i].name[0])
8636 shader_addline(buffer, "%s %s = vs_in%u%s;\n", attrib_info[i].type, attrib_info[i].name,
8637 i, settings->swizzle_map & (1u << i) ? ".zyxw" : "");
8638 }
8639 for (i = 0; i < MAX_TEXTURES; ++i)
8640 {
8641 unsigned int coord_idx = settings->texgen[i] & 0x0000ffff;
8642 if ((settings->texgen[i] & 0xffff0000) == WINED3DTSS_TCI_PASSTHRU
8643 && settings->texcoords & (1u << i))
8644 shader_addline(buffer, "vec4 ffp_attrib_texcoord%u = vs_in%u;\n", i, coord_idx + WINED3D_FFP_TEXCOORD0);
8645 }
8646
8647 shader_addline(buffer, "ffp_attrib_blendweight[%u] = 1.0;\n", settings->vertexblends);
8648
8649 if (settings->transformed)
8650 {
8651 shader_addline(buffer, "vec4 ec_pos = vec4(ffp_attrib_position.xyz, 1.0);\n");
8652 shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
8653 shader_addline(buffer, "if (ffp_attrib_position.w != 0.0) gl_Position /= ffp_attrib_position.w;\n");
8654 }
8655 else
8656 {
8657 if (!settings->sw_blending)
8658 {
8659 for (i = 0; i < settings->vertexblends; ++i)
8660 shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
8661
8662 shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
8663 for (i = 0; i < settings->vertexblends + 1; ++i)
8664 {
8665 sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
8666 shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%s] * ffp_attrib_position);\n", i, var);
8667 }
8668 }
8669 else
8670 {
8671 shader_addline(buffer, "vec4 ec_pos = ffp_attrib_position;\n");
8672 }
8673
8674 shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
8675 if (settings->clipping)
8676 {
8677 if (legacy_syntax)
8678 shader_addline(buffer, "gl_ClipVertex = ec_pos;\n");
8679 else
8680 for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
8681 shader_addline(buffer, "gl_ClipDistance[%u] = dot(ec_pos, clip_planes[%u]);\n", i, i);
8682 }
8683 shader_addline(buffer, "ec_pos /= ec_pos.w;\n");
8684 }
8685
8686 shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
8687 if (settings->normal)
8688 {
8689 if (!settings->sw_blending)
8690 {
8691 for (i = 0; i < settings->vertexblends + 1; ++i)
8692 {
8693 sprintf(var, settings->vb_indices ? "int(ffp_attrib_blendindices[%u] + 0.1)" : "%u", i);
8694 shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%s] * ffp_attrib_normal);\n", i, var);
8695 }
8696 }
8697 else
8698 {
8699 shader_addline(buffer, "normal = ffp_attrib_normal;\n");
8700 }
8701
8702 if (settings->normalize)
8703 shader_addline(buffer, "normal = normalize(normal);\n");
8704 }
8705
8707 if (legacy_syntax)
8708 {
8709 shader_addline(buffer, "gl_FrontColor = ffp_varying_diffuse;\n");
8710 shader_addline(buffer, "gl_FrontSecondaryColor = ffp_varying_specular;\n");
8711 }
8712 else
8713 {
8714 shader_addline(buffer, "ffp_varying_diffuse = clamp(ffp_varying_diffuse, 0.0, 1.0);\n");
8715 shader_addline(buffer, "ffp_varying_specular = clamp(ffp_varying_specular, 0.0, 1.0);\n");
8716 }
8717
8718 for (i = 0; i < MAX_TEXTURES; ++i)
8719 {
8720 BOOL output_legacy_texcoord = legacy_syntax;
8721
8722 switch (settings->texgen[i] & 0xffff0000)
8723 {
8725 if (settings->texcoords & (1u << i))
8726 shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ffp_attrib_texcoord%u;\n",
8727 i, i, i);
8728 else if (gl_info->limits.glsl_varyings >= wined3d_max_compat_varyings(gl_info))
8729 shader_addline(buffer, "ffp_varying_texcoord[%u] = vec4(0.0);\n", i);
8730 else
8731 output_legacy_texcoord = FALSE;
8732 break;
8733
8735 shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * vec4(normal, 1.0);\n", i, i);
8736 break;
8737
8739 shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ec_pos;\n", i, i);
8740 break;
8741
8743 shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]"
8744 " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i);
8745 break;
8746
8748 shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n");
8749 shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n");
8750 shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]"
8751 " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i);
8752 break;
8753
8754 default:
8755 ERR("Unhandled texgen %#x.\n", settings->texgen[i]);
8756 break;
8757 }
8758 if (output_legacy_texcoord)
8759 shader_addline(buffer, "gl_TexCoord[%u] = ffp_varying_texcoord[%u];\n", i, i);
8760 }
8761
8762 switch (settings->fog_mode)
8763 {
8765 output_legacy_fogcoord = FALSE;
8766 break;
8767
8769 shader_addline(buffer, "ffp_varying_fogcoord = ffp_attrib_specular.w * 255.0;\n");
8770 break;
8771
8773 shader_addline(buffer, "ffp_varying_fogcoord = length(ec_pos.xyz);\n");
8774 break;
8775
8777 if (settings->ortho_fog)
8778 {
8779 if (gl_info->supported[ARB_CLIP_CONTROL])
8780 shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z;\n");
8781 else
8782 /* Need to undo the [0.0 - 1.0] -> [-1.0 - 1.0] transformation from D3D to GL coordinates. */
8783 shader_addline(buffer, "ffp_varying_fogcoord = gl_Position.z * 0.5 + 0.5;\n");
8784 }
8785 else if (settings->transformed)
8786 {
8787 shader_addline(buffer, "ffp_varying_fogcoord = ec_pos.z;\n");
8788 }
8789 else
8790 {
8791 shader_addline(buffer, "ffp_varying_fogcoord = abs(ec_pos.z);\n");
8792 }
8793 break;
8794
8795 default:
8796 ERR("Unhandled fog mode %#x.\n", settings->fog_mode);
8797 break;
8798 }
8799 if (output_legacy_fogcoord)
8800 shader_addline(buffer, "gl_FogFragCoord = ffp_varying_fogcoord;\n");
8801
8802 if (settings->point_size)
8803 {
8804 shader_addline(buffer, "gl_PointSize = %s / sqrt(ffp_point.c_att"
8805 " + ffp_point.l_att * length(ec_pos.xyz)"
8806 " + ffp_point.q_att * dot(ec_pos.xyz, ec_pos.xyz));\n",
8807 settings->per_vertex_point_size ? "ffp_attrib_psize" : "ffp_point.size");
8808 shader_addline(buffer, "gl_PointSize = clamp(gl_PointSize, ffp_point.size_min, ffp_point.size_max);\n");
8809 }
8810
8811 shader_addline(buffer, "}\n");
8812
8813 shader_obj = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
8814 shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
8815
8816 return shader_obj;
8817}
8818
8820 DWORD argnum, unsigned int stage, DWORD arg)
8821{
8822 const char *ret;
8823
8824 if (arg == ARG_UNUSED)
8825 return "<unused arg>";
8826
8827 switch (arg & WINED3DTA_SELECTMASK)
8828 {
8829 case WINED3DTA_DIFFUSE:
8830 ret = "ffp_varying_diffuse";
8831 break;
8832
8833 case WINED3DTA_CURRENT:
8834 ret = "ret";
8835 break;
8836
8837 case WINED3DTA_TEXTURE:
8838 switch (stage)
8839 {
8840 case 0: ret = "tex0"; break;
8841 case 1: ret = "tex1"; break;
8842 case 2: ret = "tex2"; break;
8843 case 3: ret = "tex3"; break;
8844 case 4: ret = "tex4"; break;
8845 case 5: ret = "tex5"; break;
8846 case 6: ret = "tex6"; break;
8847 case 7: ret = "tex7"; break;
8848 default:
8849 ret = "<invalid texture>";
8850 break;
8851 }
8852 break;
8853
8854 case WINED3DTA_TFACTOR:
8855 ret = "tex_factor";
8856 break;
8857
8858 case WINED3DTA_SPECULAR:
8859 ret = "ffp_varying_specular";
8860 break;
8861
8862 case WINED3DTA_TEMP:
8863 ret = "temp_reg";
8864 break;
8865
8866 case WINED3DTA_CONSTANT:
8867 switch (stage)
8868 {
8869 case 0: ret = "tss_const0"; break;
8870 case 1: ret = "tss_const1"; break;
8871 case 2: ret = "tss_const2"; break;
8872 case 3: ret = "tss_const3"; break;
8873 case 4: ret = "tss_const4"; break;
8874 case 5: ret = "tss_const5"; break;
8875 case 6: ret = "tss_const6"; break;
8876 case 7: ret = "tss_const7"; break;
8877 default:
8878 ret = "<invalid constant>";
8879 break;
8880 }
8881 break;
8882
8883 default:
8884 return "<unhandled arg>";
8885 }
8886
8888 {
8889 shader_addline(buffer, "arg%u = vec4(1.0) - %s;\n", argnum, ret);
8890 if (argnum == 0)
8891 ret = "arg0";
8892 else if (argnum == 1)
8893 ret = "arg1";
8894 else if (argnum == 2)
8895 ret = "arg2";
8896 }
8897
8899 {
8900 shader_addline(buffer, "arg%u = vec4(%s.w);\n", argnum, ret);
8901 if (argnum == 0)
8902 ret = "arg0";
8903 else if (argnum == 1)
8904 ret = "arg1";
8905 else if (argnum == 2)
8906 ret = "arg2";
8907 }
8908
8909 return ret;
8910}
8911
8912static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color,
8913 BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
8914{
8915 const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
8916
8917 if (color && alpha)
8918 dstmask = "";
8919 else if (color)
8920 dstmask = ".xyz";
8921 else
8922 dstmask = ".w";
8923
8924 if (dst == tempreg)
8925 dstreg = "temp_reg";
8926 else
8927 dstreg = "ret";
8928
8929 arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0);
8930 arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1);
8931 arg2 = shader_glsl_get_ffp_fragment_op_arg(buffer, 2, stage, dw_arg2);
8932
8933 switch (op)
8934 {
8936 break;
8937
8939 shader_addline(buffer, "%s%s = %s%s;\n", dstreg, dstmask, arg1, dstmask);
8940 break;
8941
8943 shader_addline(buffer, "%s%s = %s%s;\n", dstreg, dstmask, arg2, dstmask);
8944 break;
8945
8947 shader_addline(buffer, "%s%s = %s%s * %s%s;\n", dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8948 break;
8949
8951 shader_addline(buffer, "%s%s = clamp(%s%s * %s%s * 4.0, 0.0, 1.0);\n",
8952 dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8953 break;
8954
8956 shader_addline(buffer, "%s%s = clamp(%s%s * %s%s * 2.0, 0.0, 1.0);\n",
8957 dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8958 break;
8959
8960 case WINED3D_TOP_ADD:
8961 shader_addline(buffer, "%s%s = clamp(%s%s + %s%s, 0.0, 1.0);\n",
8962 dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8963 break;
8964
8966 shader_addline(buffer, "%s%s = clamp(%s%s + (%s - vec4(0.5))%s, 0.0, 1.0);\n",
8967 dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8968 break;
8969
8971 shader_addline(buffer, "%s%s = clamp((%s%s + (%s - vec4(0.5))%s) * 2.0, 0.0, 1.0);\n",
8972 dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8973 break;
8974
8976 shader_addline(buffer, "%s%s = clamp(%s%s - %s%s, 0.0, 1.0);\n",
8977 dstreg, dstmask, arg1, dstmask, arg2, dstmask);
8978 break;
8979
8981 shader_addline(buffer, "%s%s = clamp((vec4(1.0) - %s)%s * %s%s + %s%s, 0.0, 1.0);\n",
8982 dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg1, dstmask);
8983 break;
8984
8987 shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
8988 dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
8989 break;
8990
8993 shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
8994 dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
8995 break;
8996
8999 shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
9000 dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
9001 break;
9002
9005 shader_addline(buffer, "%s%s = clamp(%s%s * (1.0 - %s.w) + %s%s, 0.0, 1.0);\n",
9006 dstreg, dstmask, arg2, dstmask, arg0, arg1, dstmask);
9007 break;
9008
9011 shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
9012 dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
9013 break;
9014
9016 shader_addline(buffer, "%s%s = clamp(%s%s * %s.w + %s%s, 0.0, 1.0);\n",
9017 dstreg, dstmask, arg2, dstmask, arg1, arg1, dstmask);
9018 break;
9019
9021 shader_addline(buffer, "%s%s = clamp(%s%s * %s%s + %s.w, 0.0, 1.0);\n",
9022 dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg1);
9023 break;
9024
9026 shader_addline(buffer, "%s%s = clamp(%s%s * (1.0 - %s.w) + %s%s, 0.0, 1.0);\n",
9027 dstreg, dstmask, arg2, dstmask, arg1, arg1, dstmask);
9028 break;
9030 shader_addline(buffer, "%s%s = clamp((vec4(1.0) - %s)%s * %s%s + %s.w, 0.0, 1.0);\n",
9031 dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg1);
9032 break;
9033
9036 /* These are handled in the first pass, nothing to do. */
9037 break;
9038
9040 shader_addline(buffer, "%s%s = vec4(clamp(dot(%s.xyz - 0.5, %s.xyz - 0.5) * 4.0, 0.0, 1.0))%s;\n",
9041 dstreg, dstmask, arg1, arg2, dstmask);
9042 break;
9043
9045 shader_addline(buffer, "%s%s = clamp(%s%s * %s%s + %s%s, 0.0, 1.0);\n",
9046 dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg0, dstmask);
9047 break;
9048
9049 case WINED3D_TOP_LERP:
9050 /* MSDN isn't quite right here. */
9051 shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s%s);\n",
9052 dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0, dstmask);
9053 break;
9054
9055 default:
9056 FIXME("Unhandled operation %#x.\n", op);
9057 break;
9058 }
9059}
9060
9061/* Context activation is done by the caller. */
9063 const struct ffp_frag_settings *settings, const struct wined3d_context *context)
9064{
9065 const char *output = needs_legacy_glsl_syntax(context->gl_info) ? "gl_FragData[0]" : "ps_out0";
9066 struct wined3d_string_buffer *tex_reg_name = string_buffer_get(&priv->string_buffers);
9067 enum wined3d_cmp_func alpha_test_func = settings->alpha_test_func + 1;
9069 BYTE lum_map = 0, bump_map = 0, tex_map = 0, tss_const_map = 0;
9070 const struct wined3d_gl_info *gl_info = context->gl_info;
9071 const BOOL legacy_syntax = needs_legacy_glsl_syntax(gl_info);
9072 BOOL tempreg_used = FALSE, tfactor_used = FALSE;
9073 UINT lowest_disabled_stage;
9074 GLuint shader_id;
9075 DWORD arg0, arg1, arg2;
9076 unsigned int stage;
9077
9079
9080 /* Find out which textures are read */
9081 for (stage = 0; stage < MAX_TEXTURES; ++stage)
9082 {
9083 if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
9084 break;
9085
9086 arg0 = settings->op[stage].carg0 & WINED3DTA_SELECTMASK;
9087 arg1 = settings->op[stage].carg1 & WINED3DTA_SELECTMASK;
9088 arg2 = settings->op[stage].carg2 & WINED3DTA_SELECTMASK;
9089
9091 || (stage == 0 && settings->color_key_enabled))
9092 tex_map |= 1u << stage;
9094 tfactor_used = TRUE;
9095 if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
9096 tempreg_used = TRUE;
9097 if (settings->op[stage].dst == tempreg)
9098 tempreg_used = TRUE;
9100 tss_const_map |= 1u << stage;
9101
9102 switch (settings->op[stage].cop)
9103 {
9105 lum_map |= 1u << stage;
9106 /* fall through */
9108 bump_map |= 1u << stage;
9109 /* fall through */
9112 tex_map |= 1u << stage;
9113 break;
9114
9116 tfactor_used = TRUE;
9117 break;
9118
9119 default:
9120 break;
9121 }
9122
9123 if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
9124 continue;
9125
9126 arg0 = settings->op[stage].aarg0 & WINED3DTA_SELECTMASK;
9127 arg1 = settings->op[stage].aarg1 & WINED3DTA_SELECTMASK;
9128 arg2 = settings->op[stage].aarg2 & WINED3DTA_SELECTMASK;
9129
9131 tex_map |= 1u << stage;
9133 tfactor_used = TRUE;
9134 if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
9135 tempreg_used = TRUE;
9137 tss_const_map |= 1u << stage;
9138 }
9139 lowest_disabled_stage = stage;
9140
9142
9144 shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
9146 shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n");
9147 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
9148 shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
9149
9150 if (!needs_legacy_glsl_syntax(gl_info))
9151 {
9153 shader_addline(buffer, "layout(location = 0) ");
9154 shader_addline(buffer, "out vec4 ps_out0;\n");
9155 }
9156
9157 shader_addline(buffer, "vec4 tmp0, tmp1;\n");
9158 shader_addline(buffer, "vec4 ret;\n");
9159 if (tempreg_used || settings->sRGB_write)
9160 shader_addline(buffer, "vec4 temp_reg = vec4(0.0);\n");
9161 shader_addline(buffer, "vec4 arg0, arg1, arg2;\n");
9162
9163 for (stage = 0; stage < MAX_TEXTURES; ++stage)
9164 {
9165 const char *sampler_type;
9166
9167 if (tss_const_map & (1u << stage))
9168 shader_addline(buffer, "uniform vec4 tss_const%u;\n", stage);
9169
9170 if (!(tex_map & (1u << stage)))
9171 continue;
9172
9173 switch (settings->op[stage].tex_type)
9174 {
9176 sampler_type = "1D";
9177 break;
9179 sampler_type = "2D";
9180 break;
9182 sampler_type = "3D";
9183 break;
9185 sampler_type = "Cube";
9186 break;
9188 sampler_type = "2DRect";
9189 break;
9190 default:
9191 FIXME("Unhandled sampler type %#x.\n", settings->op[stage].tex_type);
9192 sampler_type = NULL;
9193 break;
9194 }
9195 if (sampler_type)
9196 {
9199 shader_addline(buffer, "uniform sampler%s ps_sampler%u;\n", sampler_type, stage);
9200 }
9201
9202 shader_addline(buffer, "vec4 tex%u;\n", stage);
9203
9204 if (!(bump_map & (1u << stage)))
9205 continue;
9206 shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", stage);
9207
9208 if (!(lum_map & (1u << stage)))
9209 continue;
9210 shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", stage);
9211 shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", stage);
9212 }
9213 if (tfactor_used)
9214 shader_addline(buffer, "uniform vec4 tex_factor;\n");
9215 if (settings->color_key_enabled)
9216 shader_addline(buffer, "uniform vec4 color_key[2];\n");
9217 shader_addline(buffer, "uniform vec4 specular_enable;\n");
9218
9219 if (settings->sRGB_write)
9220 {
9221 shader_addline(buffer, "const vec4 srgb_const0 = ");
9223 shader_addline(buffer, ";\n");
9224 shader_addline(buffer, "const vec4 srgb_const1 = ");
9226 shader_addline(buffer, ";\n");
9227 }
9228
9229 shader_addline(buffer, "uniform struct\n{\n");
9230 shader_addline(buffer, " vec4 color;\n");
9231 shader_addline(buffer, " float density;\n");
9232 shader_addline(buffer, " float end;\n");
9233 shader_addline(buffer, " float scale;\n");
9234 shader_addline(buffer, "} ffp_fog;\n");
9235
9236 if (alpha_test_func != WINED3D_CMP_ALWAYS)
9237 shader_addline(buffer, "uniform float alpha_test_ref;\n");
9238
9239 if (legacy_syntax)
9240 {
9241 shader_addline(buffer, "vec4 ffp_varying_diffuse;\n");
9242 shader_addline(buffer, "vec4 ffp_varying_specular;\n");
9243 shader_addline(buffer, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
9244 shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
9245 shader_addline(buffer, "float ffp_varying_fogcoord;\n");
9246 }
9247 else
9248 {
9249 declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_diffuse;\n");
9250 declare_in_varying(gl_info, buffer, settings->flatshading, "vec4 ffp_varying_specular;\n");
9251 declare_in_varying(gl_info, buffer, FALSE, "vec4 ffp_varying_texcoord[%u];\n", MAX_TEXTURES);
9252 shader_addline(buffer, "vec4 ffp_texcoord[%u];\n", MAX_TEXTURES);
9253 declare_in_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n");
9254 }
9255
9256 shader_addline(buffer, "void main()\n{\n");
9257
9258 if (legacy_syntax)
9259 {
9260 shader_addline(buffer, "ffp_varying_diffuse = gl_Color;\n");
9261 shader_addline(buffer, "ffp_varying_specular = gl_SecondaryColor;\n");
9262 }
9263
9264 for (stage = 0; stage < MAX_TEXTURES; ++stage)
9265 {
9266 if (tex_map & (1u << stage))
9267 {
9268 if (settings->pointsprite)
9269 shader_addline(buffer, "ffp_texcoord[%u] = vec4(gl_PointCoord.xy, 0.0, 0.0);\n", stage);
9270 else if (settings->texcoords_initialized & (1u << stage))
9271 shader_addline(buffer, "ffp_texcoord[%u] = %s[%u];\n",
9272 stage, legacy_syntax ? "gl_TexCoord" : "ffp_varying_texcoord", stage);
9273 else
9274 shader_addline(buffer, "ffp_texcoord[%u] = vec4(0.0);\n", stage);
9275 }
9276 }
9277
9278 if (legacy_syntax && settings->fog != WINED3D_FFP_PS_FOG_OFF)
9279 shader_addline(buffer, "ffp_varying_fogcoord = gl_FogFragCoord;\n");
9280
9281 if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
9282 shader_addline(buffer, "if (any(lessThan(ffp_texcoord[7], vec4(0.0)))) discard;\n");
9283
9284 /* Generate texture sampling instructions */
9285 for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage)
9286 {
9287 const char *texture_function, *coord_mask;
9288 BOOL proj;
9289
9290 if (!(tex_map & (1u << stage)))
9291 continue;
9292
9293 if (settings->op[stage].projected == proj_none)
9294 {
9295 proj = FALSE;
9296 }
9297 else if (settings->op[stage].projected == proj_count4
9298 || settings->op[stage].projected == proj_count3)
9299 {
9300 proj = TRUE;
9301 }
9302 else
9303 {
9304 FIXME("Unexpected projection mode %d\n", settings->op[stage].projected);
9305 proj = TRUE;
9306 }
9307
9308 if (settings->op[stage].tex_type == WINED3D_GL_RES_TYPE_TEX_CUBE)
9309 proj = FALSE;
9310
9311 switch (settings->op[stage].tex_type)
9312 {
9314 if (proj)
9315 {
9316 texture_function = "texture1DProj";
9317 coord_mask = "xw";
9318 }
9319 else
9320 {
9321 texture_function = "texture1D";
9322 coord_mask = "x";
9323 }
9324 break;
9326 if (proj)
9327 {
9328 texture_function = "texture2DProj";
9329 coord_mask = "xyw";
9330 }
9331 else
9332 {
9333 texture_function = "texture2D";
9334 coord_mask = "xy";
9335 }
9336 break;
9338 if (proj)
9339 {
9340 texture_function = "texture3DProj";
9341 coord_mask = "xyzw";
9342 }
9343 else
9344 {
9345 texture_function = "texture3D";
9346 coord_mask = "xyz";
9347 }
9348 break;
9350 texture_function = "textureCube";
9351 coord_mask = "xyz";
9352 break;
9354 if (proj)
9355 {
9356 texture_function = "texture2DRectProj";
9357 coord_mask = "xyw";
9358 }
9359 else
9360 {
9361 texture_function = "texture2DRect";
9362 coord_mask = "xy";
9363 }
9364 break;
9365 default:
9366 FIXME("Unhandled texture type %#x.\n", settings->op[stage].tex_type);
9367 texture_function = "";
9368 coord_mask = "xyzw";
9369 break;
9370 }
9371 if (!legacy_syntax)
9372 texture_function = proj ? "textureProj" : "texture";
9373
9374 if (stage > 0
9375 && (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
9376 || settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE))
9377 {
9378 shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1);
9379
9380 /* With projective textures, texbem only divides the static
9381 * texture coord, not the displacement, so multiply the
9382 * displacement with the dividing parameter before passing it to
9383 * TXP. */
9384 if (settings->op[stage].projected != proj_none)
9385 {
9386 if (settings->op[stage].projected == proj_count4)
9387 {
9388 shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].w) + ffp_texcoord[%u].xy;\n",
9389 stage, stage);
9390 shader_addline(buffer, "ret.zw = ffp_texcoord[%u].ww;\n", stage);
9391 }
9392 else
9393 {
9394 shader_addline(buffer, "ret.xy = (ret.xy * ffp_texcoord[%u].z) + ffp_texcoord[%u].xy;\n",
9395 stage, stage);
9396 shader_addline(buffer, "ret.zw = ffp_texcoord[%u].zz;\n", stage);
9397 }
9398 }
9399 else
9400 {
9401 shader_addline(buffer, "ret = ffp_texcoord[%u] + ret.xyxy;\n", stage);
9402 }
9403
9404 shader_addline(buffer, "tex%u = %s(ps_sampler%u, ret.%s);\n",
9405 stage, texture_function, stage, coord_mask);
9406
9407 if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
9408 shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n",
9409 stage, stage - 1, stage - 1, stage - 1);
9410 }
9411 else if (settings->op[stage].projected == proj_count3)
9412 {
9413 shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].xyz);\n",
9414 stage, texture_function, stage, stage);
9415 }
9416 else
9417 {
9418 shader_addline(buffer, "tex%u = %s(ps_sampler%u, ffp_texcoord[%u].%s);\n",
9419 stage, texture_function, stage, stage, coord_mask);
9420 }
9421
9422 string_buffer_sprintf(tex_reg_name, "tex%u", stage);
9424 settings->op[stage].color_fixup);
9425 }
9426
9427 if (settings->color_key_enabled)
9428 {
9429 shader_addline(buffer, "if (all(greaterThanEqual(tex0, color_key[0])) && all(lessThan(tex0, color_key[1])))\n");
9430 shader_addline(buffer, " discard;\n");
9431 }
9432
9433 shader_addline(buffer, "ret = ffp_varying_diffuse;\n");
9434
9435 /* Generate the main shader */
9436 for (stage = 0; stage < MAX_TEXTURES; ++stage)
9437 {
9438 BOOL op_equal;
9439
9440 if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
9441 break;
9442
9443 if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG1
9444 && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG1)
9445 op_equal = settings->op[stage].carg1 == settings->op[stage].aarg1;
9446 else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG1
9447 && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG2)
9448 op_equal = settings->op[stage].carg1 == settings->op[stage].aarg2;
9449 else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG2
9450 && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG1)
9451 op_equal = settings->op[stage].carg2 == settings->op[stage].aarg1;
9452 else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG2
9453 && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG2)
9454 op_equal = settings->op[stage].carg2 == settings->op[stage].aarg2;
9455 else
9456 op_equal = settings->op[stage].aop == settings->op[stage].cop
9457 && settings->op[stage].carg0 == settings->op[stage].aarg0
9458 && settings->op[stage].carg1 == settings->op[stage].aarg1
9459 && settings->op[stage].carg2 == settings->op[stage].aarg2;
9460
9461 if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
9462 {
9463 shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
9464 settings->op[stage].cop, settings->op[stage].carg0,
9465 settings->op[stage].carg1, settings->op[stage].carg2);
9466 }
9467 else if (op_equal)
9468 {
9469 shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst,
9470 settings->op[stage].cop, settings->op[stage].carg0,
9471 settings->op[stage].carg1, settings->op[stage].carg2);
9472 }
9473 else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP
9474 && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
9475 {
9476 shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
9477 settings->op[stage].cop, settings->op[stage].carg0,
9478 settings->op[stage].carg1, settings->op[stage].carg2);
9479 shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst,
9480 settings->op[stage].aop, settings->op[stage].aarg0,
9481 settings->op[stage].aarg1, settings->op[stage].aarg2);
9482 }
9483 }
9484
9485 shader_addline(buffer, "%s = ffp_varying_specular * specular_enable + ret;\n", output);
9486
9487 if (settings->sRGB_write)
9489
9491
9492 shader_glsl_generate_alpha_test(buffer, gl_info, alpha_test_func);
9493
9494 shader_addline(buffer, "}\n");
9495
9496 shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
9497 shader_glsl_compile(gl_info, shader_id, buffer->buffer);
9498
9499 string_buffer_release(&priv->string_buffers, tex_reg_name);
9500 return shader_id;
9501}
9502
9504 const struct wined3d_gl_info *gl_info, const struct wined3d_ffp_vs_settings *settings)
9505{
9507 const struct wine_rb_entry *entry;
9508
9511
9512 if (!(shader = heap_alloc(sizeof(*shader))))
9513 return NULL;
9514
9515 shader->desc.settings = *settings;
9517 list_init(&shader->linked_programs);
9518 if (wine_rb_put(&priv->ffp_vertex_shaders, &shader->desc.settings, &shader->desc.entry) == -1)
9519 ERR("Failed to insert ffp vertex shader.\n");
9520
9521 return shader;
9522}
9523
9525 const struct ffp_frag_settings *args, const struct wined3d_context *context)
9526{
9527 struct glsl_ffp_fragment_shader *glsl_desc;
9528 const struct ffp_frag_desc *desc;
9529
9532
9533 if (!(glsl_desc = heap_alloc(sizeof(*glsl_desc))))
9534 return NULL;
9535
9536 glsl_desc->entry.settings = *args;
9538 list_init(&glsl_desc->linked_programs);
9539 add_ffp_frag_shader(&priv->ffp_fragment_shaders, &glsl_desc->entry);
9540
9541 return glsl_desc;
9542}
9543
9544
9546 struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
9547{
9548 unsigned int i;
9550
9551 for (i = 0; i < vs_c_count; ++i)
9552 {
9553 string_buffer_sprintf(name, "vs_c[%u]", i);
9554 vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9555 }
9556 memset(&vs->uniform_f_locations[vs_c_count], 0xff, (WINED3D_MAX_VS_CONSTS_F - vs_c_count) * sizeof(GLuint));
9557
9558 for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
9559 {
9560 string_buffer_sprintf(name, "vs_i[%u]", i);
9561 vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9562 }
9563
9564 for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i)
9565 {
9566 string_buffer_sprintf(name, "vs_b[%u]", i);
9567 vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9568 }
9569
9570 vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
9571
9572 for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
9573 {
9574 string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
9575 vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9576 }
9577 for (i = 0; i < MAX_VERTEX_INDEX_BLENDS; ++i)
9578 {
9579 string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i);
9580 vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9581 }
9582 vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix"));
9583 for (i = 0; i < MAX_TEXTURES; ++i)
9584 {
9585 string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i);
9586 vs->texture_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9587 }
9588 vs->material_ambient_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.ambient"));
9589 vs->material_diffuse_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.diffuse"));
9590 vs->material_specular_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.specular"));
9591 vs->material_emissive_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.emissive"));
9592 vs->material_shininess_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_material.shininess"));
9593 vs->light_ambient_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_light_ambient"));
9594 for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
9595 {
9596 string_buffer_sprintf(name, "ffp_light[%u].diffuse", i);
9597 vs->light_location[i].diffuse = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9598 string_buffer_sprintf(name, "ffp_light[%u].specular", i);
9599 vs->light_location[i].specular = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9600 string_buffer_sprintf(name, "ffp_light[%u].ambient", i);
9601 vs->light_location[i].ambient = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9602 string_buffer_sprintf(name, "ffp_light[%u].position", i);
9603 vs->light_location[i].position = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9604 string_buffer_sprintf(name, "ffp_light[%u].direction", i);
9605 vs->light_location[i].direction = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9606 string_buffer_sprintf(name, "ffp_light[%u].range", i);
9607 vs->light_location[i].range = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9608 string_buffer_sprintf(name, "ffp_light[%u].falloff", i);
9609 vs->light_location[i].falloff = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9610 string_buffer_sprintf(name, "ffp_light[%u].c_att", i);
9611 vs->light_location[i].c_att = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9612 string_buffer_sprintf(name, "ffp_light[%u].l_att", i);
9613 vs->light_location[i].l_att = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9614 string_buffer_sprintf(name, "ffp_light[%u].q_att", i);
9615 vs->light_location[i].q_att = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9616 string_buffer_sprintf(name, "ffp_light[%u].cos_htheta", i);
9617 vs->light_location[i].cos_htheta = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9618 string_buffer_sprintf(name, "ffp_light[%u].cos_hphi", i);
9619 vs->light_location[i].cos_hphi = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9620 }
9621 vs->pointsize_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.size"));
9622 vs->pointsize_min_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.size_min"));
9623 vs->pointsize_max_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.size_max"));
9624 vs->pointsize_c_att_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.c_att"));
9625 vs->pointsize_l_att_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.l_att"));
9626 vs->pointsize_q_att_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_point.q_att"));
9627 vs->clip_planes_location = GL_EXTCALL(glGetUniformLocation(program_id, "clip_planes"));
9628
9630}
9631
9633 struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ds_program *ds)
9634{
9635 ds->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
9636}
9637
9639 struct shader_glsl_priv *priv, GLuint program_id, struct glsl_gs_program *gs)
9640{
9641 gs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
9642}
9643
9645 struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count)
9646{
9647 unsigned int i;
9649
9650 for (i = 0; i < ps_c_count; ++i)
9651 {
9652 string_buffer_sprintf(name, "ps_c[%u]", i);
9653 ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9654 }
9655 memset(&ps->uniform_f_locations[ps_c_count], 0xff, (WINED3D_MAX_PS_CONSTS_F - ps_c_count) * sizeof(GLuint));
9656
9657 for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
9658 {
9659 string_buffer_sprintf(name, "ps_i[%u]", i);
9660 ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9661 }
9662
9663 for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i)
9664 {
9665 string_buffer_sprintf(name, "ps_b[%u]", i);
9666 ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9667 }
9668
9669 for (i = 0; i < MAX_TEXTURES; ++i)
9670 {
9671 string_buffer_sprintf(name, "bumpenv_mat%u", i);
9672 ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9673 string_buffer_sprintf(name, "bumpenv_lum_scale%u", i);
9674 ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9675 string_buffer_sprintf(name, "bumpenv_lum_offset%u", i);
9676 ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9677 string_buffer_sprintf(name, "tss_const%u", i);
9678 ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
9679 }
9680
9681 ps->tex_factor_location = GL_EXTCALL(glGetUniformLocation(program_id, "tex_factor"));
9682 ps->specular_enable_location = GL_EXTCALL(glGetUniformLocation(program_id, "specular_enable"));
9683
9684 ps->fog_color_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.color"));
9685 ps->fog_density_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.density"));
9686 ps->fog_end_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.end"));
9687 ps->fog_scale_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.scale"));
9688
9689 ps->alpha_test_ref_location = GL_EXTCALL(glGetUniformLocation(program_id, "alpha_test_ref"));
9690
9691 ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup"));
9692 ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection"));
9693 ps->color_key_location = GL_EXTCALL(glGetUniformLocation(program_id, "color_key"));
9694
9696}
9697
9699 const struct wined3d_context *context, struct wined3d_shader *shader)
9700{
9701 struct glsl_context_data *ctx_data = context->shader_backend_data;
9703 const struct wined3d_gl_info *gl_info = context->gl_info;
9704 struct glsl_cs_compiled_shader *gl_shaders;
9705 struct glsl_shader_private *shader_data;
9707 GLuint shader_id, program_id;
9708
9709 if (!(entry = heap_alloc(sizeof(*entry))))
9710 {
9711 ERR("Out of memory.\n");
9712 return E_OUTOFMEMORY;
9713 }
9714
9715 if (!(shader->backend_data = heap_alloc_zero(sizeof(*shader_data))))
9716 {
9717 ERR("Failed to allocate backend data.\n");
9719 return E_OUTOFMEMORY;
9720 }
9721 shader_data = shader->backend_data;
9722 gl_shaders = shader_data->gl_shaders.cs;
9723
9724 if (!(shader_data->gl_shaders.cs = heap_alloc(sizeof(*gl_shaders))))
9725 {
9726 ERR("Failed to allocate GL shader array.\n");
9728 heap_free(shader->backend_data);
9729 shader->backend_data = NULL;
9730 return E_OUTOFMEMORY;
9731 }
9732 shader_data->shader_array_size = 1;
9733 gl_shaders = shader_data->gl_shaders.cs;
9734
9735 TRACE("Compiling compute shader %p.\n", shader);
9736
9739 gl_shaders[shader_data->num_gl_shaders++].id = shader_id;
9740
9741 program_id = GL_EXTCALL(glCreateProgram());
9742 TRACE("Created new GLSL shader program %u.\n", program_id);
9743
9744 entry->id = program_id;
9745 entry->vs.id = 0;
9746 entry->hs.id = 0;
9747 entry->ds.id = 0;
9748 entry->gs.id = 0;
9749 entry->ps.id = 0;
9750 entry->cs.id = shader_id;
9751 entry->constant_version = 0;
9752 entry->shader_controlled_clip_distances = 0;
9753 entry->ps.np2_fixup_info = NULL;
9755
9756 TRACE("Attaching GLSL shader object %u to program %u.\n", shader_id, program_id);
9757 GL_EXTCALL(glAttachShader(program_id, shader_id));
9758 checkGLcall("glAttachShader");
9759
9760 list_add_head(&shader->linked_programs, &entry->cs.shader_entry);
9761
9762 TRACE("Linking GLSL shader program %u.\n", program_id);
9763 GL_EXTCALL(glLinkProgram(program_id));
9764 shader_glsl_validate_link(gl_info, program_id);
9765
9766 GL_EXTCALL(glUseProgram(program_id));
9767 checkGLcall("glUseProgram");
9769 shader_glsl_load_images(gl_info, priv, program_id, &shader->reg_maps);
9770
9771 entry->constant_update_mask = 0;
9772
9773 GL_EXTCALL(glUseProgram(ctx_data->glsl_program ? ctx_data->glsl_program->id : 0));
9774 checkGLcall("glUseProgram");
9775 return WINED3D_OK;
9776}
9777
9779 struct shader_glsl_priv *priv, struct wined3d_shader *shader)
9780{
9781 struct glsl_shader_private *shader_data;
9782
9783 if (!shader->backend_data)
9784 {
9785 WARN("Failed to find GLSL program for compute shader %p.\n", shader);
9787 {
9788 ERR("Failed to compile compute shader %p.\n", shader);
9789 return 0;
9790 }
9791 }
9792 shader_data = shader->backend_data;
9793 return shader_data->gl_shaders.cs[0].id;
9794}
9795
9796/* Context activation is done by the caller. */
9798 const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
9799{
9801 struct wined3d_shader *shader;
9802 struct glsl_program_key key;
9803 GLuint cs_id;
9804
9805 if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE)))
9806 return;
9807
9808 if (!(shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE]))
9809 {
9810 WARN("Compute shader is NULL.\n");
9811 ctx_data->glsl_program = NULL;
9812 return;
9813 }
9814
9816 memset(&key, 0, sizeof(key));
9817 key.cs_id = cs_id;
9818 if (!(entry = get_glsl_program_entry(priv, &key)))
9819 ERR("Failed to find GLSL program for compute shader %p.\n", shader);
9820 ctx_data->glsl_program = entry;
9821}
9822
9823/* Context activation is done by the caller. */
9824static void set_glsl_shader_program(const struct wined3d_context *context, const struct wined3d_state *state,
9825 struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
9826{
9827 const struct wined3d_d3d_info *d3d_info = context->d3d_info;
9828 const struct wined3d_gl_info *gl_info = context->gl_info;
9829 const struct wined3d_shader *pre_rasterization_shader;
9830 const struct ps_np2fixup_info *np2fixup_info = NULL;
9831 struct wined3d_shader *hshader, *dshader, *gshader;
9833 struct wined3d_shader *vshader = NULL;
9834 struct wined3d_shader *pshader = NULL;
9835 GLuint reorder_shader_id = 0;
9836 struct glsl_program_key key;
9837 GLuint program_id;
9838 unsigned int i;
9839 GLuint vs_id = 0;
9840 GLuint hs_id = 0;
9841 GLuint ds_id = 0;
9842 GLuint gs_id = 0;
9843 GLuint ps_id = 0;
9844 struct list *ps_list = NULL, *vs_list = NULL;
9845 WORD attribs_map;
9847
9848 if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_VERTEX)) && ctx_data->glsl_program)
9849 {
9850 vs_id = ctx_data->glsl_program->vs.id;
9851 vs_list = &ctx_data->glsl_program->vs.shader_entry;
9852
9853 if (use_vs(state))
9854 vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
9855 }
9856 else if (use_vs(state))
9857 {
9859
9860 vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
9861
9862 find_vs_compile_args(state, vshader, context->stream_info.swizzle_map, &vs_compile_args, context);
9863 vs_id = find_glsl_vshader(context, priv, vshader, &vs_compile_args);
9864 vs_list = &vshader->linked_programs;
9865 }
9866 else if (priv->vertex_pipe == &glsl_vertex_pipe)
9867 {
9868 struct glsl_ffp_vertex_shader *ffp_shader;
9870
9872 ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings);
9873 vs_id = ffp_shader->id;
9874 vs_list = &ffp_shader->linked_programs;
9875 }
9876
9877 hshader = state->shader[WINED3D_SHADER_TYPE_HULL];
9878 if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_HULL)) && ctx_data->glsl_program)
9879 hs_id = ctx_data->glsl_program->hs.id;
9880 else if (hshader)
9881 hs_id = find_glsl_hull_shader(context, priv, hshader);
9882
9883 dshader = state->shader[WINED3D_SHADER_TYPE_DOMAIN];
9884 if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_DOMAIN)) && ctx_data->glsl_program)
9885 {
9886 ds_id = ctx_data->glsl_program->ds.id;
9887 }
9888 else if (dshader)
9889 {
9890 struct ds_compile_args args;
9891
9893 ds_id = find_glsl_domain_shader(context, priv, dshader, &args);
9894 }
9895
9896 gshader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
9897 if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY)) && ctx_data->glsl_program)
9898 {
9899 gs_id = ctx_data->glsl_program->gs.id;
9900 }
9901 else if (gshader)
9902 {
9903 struct gs_compile_args args;
9904
9906 gs_id = find_glsl_geometry_shader(context, priv, gshader, &args);
9907 }
9908
9909 /* A pixel shader is not used when rasterization is disabled. */
9910 if (is_rasterization_disabled(gshader))
9911 {
9912 ps_id = 0;
9913 ps_list = NULL;
9914 }
9915 else if (!(context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_PIXEL)) && ctx_data->glsl_program)
9916 {
9917 ps_id = ctx_data->glsl_program->ps.id;
9918 ps_list = &ctx_data->glsl_program->ps.shader_entry;
9919
9920 if (use_ps(state))
9921 pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
9922 }
9923 else if (use_ps(state))
9924 {
9926 pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
9927 find_ps_compile_args(state, pshader, context->stream_info.position_transformed, &ps_compile_args, context);
9928 ps_id = find_glsl_pshader(context, &priv->shader_buffer, &priv->string_buffers,
9929 pshader, &ps_compile_args, &np2fixup_info);
9930 ps_list = &pshader->linked_programs;
9931 }
9932 else if (priv->fragment_pipe == &glsl_fragment_pipe
9933 && !(vshader && vshader->reg_maps.shader_version.major >= 4))
9934 {
9935 struct glsl_ffp_fragment_shader *ffp_shader;
9937
9940 ps_id = ffp_shader->id;
9941 ps_list = &ffp_shader->linked_programs;
9942 }
9943
9944 key.vs_id = vs_id;
9945 key.hs_id = hs_id;
9946 key.ds_id = ds_id;
9947 key.gs_id = gs_id;
9948 key.ps_id = ps_id;
9949 key.cs_id = 0;
9950 if ((!vs_id && !hs_id && !ds_id && !gs_id && !ps_id) || (entry = get_glsl_program_entry(priv, &key)))
9951 {
9952 ctx_data->glsl_program = entry;
9953 return;
9954 }
9955
9956 /* If we get to this point, then no matching program exists, so we create one */
9957 program_id = GL_EXTCALL(glCreateProgram());
9958 TRACE("Created new GLSL shader program %u.\n", program_id);
9959
9960 /* Create the entry */
9961 entry = heap_alloc(sizeof(*entry));
9962 entry->id = program_id;
9963 entry->vs.id = vs_id;
9964 entry->hs.id = hs_id;
9965 entry->ds.id = ds_id;
9966 entry->gs.id = gs_id;
9967 entry->ps.id = ps_id;
9968 entry->cs.id = 0;
9969 entry->constant_version = 0;
9970 entry->shader_controlled_clip_distances = 0;
9971 entry->ps.np2_fixup_info = np2fixup_info;
9972 /* Add the hash table entry */
9974
9975 /* Set the current program */
9976 ctx_data->glsl_program = entry;
9977
9978 /* Attach GLSL vshader */
9979 if (vs_id)
9980 {
9981 TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, program_id);
9982 GL_EXTCALL(glAttachShader(program_id, vs_id));
9983 checkGLcall("glAttachShader");
9984
9985 list_add_head(vs_list, &entry->vs.shader_entry);
9986 }
9987
9988 if (vshader)
9989 {
9990 attribs_map = vshader->reg_maps.input_registers;
9991 if (vshader->reg_maps.shader_version.major < 4)
9992 {
9993 reorder_shader_id = shader_glsl_generate_vs3_rasterizer_input_setup(priv, vshader, pshader,
9994 state->gl_primitive_type == GL_POINTS && vshader->reg_maps.point_size,
9995 d3d_info->emulated_flatshading
9996 && state->render_states[WINED3D_RS_SHADEMODE] == WINED3D_SHADE_FLAT, gl_info);
9997 TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id);
9998 GL_EXTCALL(glAttachShader(program_id, reorder_shader_id));
9999 checkGLcall("glAttachShader");
10000 /* Flag the reorder function for deletion, it will be freed
10001 * automatically when the program is destroyed. */
10002 GL_EXTCALL(glDeleteShader(reorder_shader_id));
10003 }
10004 }
10005 else
10006 {
10007 attribs_map = (1u << WINED3D_FFP_ATTRIBS_COUNT) - 1;
10008 }
10009
10011 {
10012 /* Bind vertex attributes to a corresponding index number to match
10013 * the same index numbers as ARB_vertex_programs (makes loading
10014 * vertex attributes simpler). With this method, we can use the
10015 * exact same code to load the attributes later for both ARB and
10016 * GLSL shaders.
10017 *
10018 * We have to do this here because we need to know the Program ID
10019 * in order to make the bindings work, and it has to be done prior
10020 * to linking the GLSL program. */
10022 for (i = 0; attribs_map; attribs_map >>= 1, ++i)
10023 {
10024 if (!(attribs_map & 1))
10025 continue;
10026
10027 string_buffer_sprintf(tmp_name, "vs_in%u", i);
10028 GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer));
10029 if (vshader && vshader->reg_maps.shader_version.major >= 4)
10030 {
10031 string_buffer_sprintf(tmp_name, "vs_in_uint%u", i);
10032 GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer));
10033 string_buffer_sprintf(tmp_name, "vs_in_int%u", i);
10034 GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer));
10035 }
10036 }
10037 checkGLcall("glBindAttribLocation");
10039
10040 if (!needs_legacy_glsl_syntax(gl_info))
10041 {
10042 char var[12];
10043
10044 if (wined3d_dualblend_enabled(state, gl_info))
10045 {
10046 for (i = 0; i < gl_info->limits.dual_buffers * 2; i++)
10047 {
10048 sprintf(var, "ps_out%u", i);
10049 GL_EXTCALL(glBindFragDataLocationIndexed(program_id, i / 2, i % 2, var));
10050 checkGLcall("glBindFragDataLocationIndexed");
10051 }
10052 }
10053 else
10054 {
10055 for (i = 0; i < gl_info->limits.buffers; i++)
10056 {
10057 sprintf(var, "ps_out%u", i);
10058 GL_EXTCALL(glBindFragDataLocation(program_id, i, var));
10059 checkGLcall("glBindFragDataLocation");
10060 }
10061 }
10062 }
10063 }
10064
10065 if (hshader)
10066 {
10067 TRACE("Attaching GLSL tessellation control shader object %u to program %u.\n", hs_id, program_id);
10068 GL_EXTCALL(glAttachShader(program_id, hs_id));
10069 checkGLcall("glAttachShader");
10070
10071 list_add_head(&hshader->linked_programs, &entry->hs.shader_entry);
10072 }
10073
10074 if (dshader)
10075 {
10076 TRACE("Attaching GLSL tessellation evaluation shader object %u to program %u.\n", ds_id, program_id);
10077 GL_EXTCALL(glAttachShader(program_id, ds_id));
10078 checkGLcall("glAttachShader");
10079
10080 list_add_head(&dshader->linked_programs, &entry->ds.shader_entry);
10081 }
10082
10083 if (gshader)
10084 {
10085 TRACE("Attaching GLSL geometry shader object %u to program %u.\n", gs_id, program_id);
10086 GL_EXTCALL(glAttachShader(program_id, gs_id));
10087 checkGLcall("glAttachShader");
10088
10089 shader_glsl_init_transform_feedback(context, priv, program_id, gshader);
10090
10091 list_add_head(&gshader->linked_programs, &entry->gs.shader_entry);
10092 }
10093
10094 /* Attach GLSL pshader */
10095 if (ps_id)
10096 {
10097 TRACE("Attaching GLSL shader object %u to program %u.\n", ps_id, program_id);
10098 GL_EXTCALL(glAttachShader(program_id, ps_id));
10099 checkGLcall("glAttachShader");
10100
10101 list_add_head(ps_list, &entry->ps.shader_entry);
10102 }
10103
10104 /* Link the program */
10105 TRACE("Linking GLSL shader program %u.\n", program_id);
10106 GL_EXTCALL(glLinkProgram(program_id));
10107 shader_glsl_validate_link(gl_info, program_id);
10108
10109 shader_glsl_init_vs_uniform_locations(gl_info, priv, program_id, &entry->vs,
10110 vshader ? vshader->limits->constant_float : 0);
10111 shader_glsl_init_ds_uniform_locations(gl_info, priv, program_id, &entry->ds);
10112 shader_glsl_init_gs_uniform_locations(gl_info, priv, program_id, &entry->gs);
10113 shader_glsl_init_ps_uniform_locations(gl_info, priv, program_id, &entry->ps,
10114 pshader ? pshader->limits->constant_float : 0);
10115 checkGLcall("find glsl program uniform locations");
10116
10117 pre_rasterization_shader = gshader ? gshader : dshader ? dshader : vshader;
10118 if (pre_rasterization_shader && pre_rasterization_shader->reg_maps.shader_version.major >= 4)
10119 {
10120 unsigned int clip_distance_count = wined3d_popcount(pre_rasterization_shader->reg_maps.clip_distance_mask);
10121 entry->shader_controlled_clip_distances = 1;
10122 entry->clip_distance_mask = (1u << clip_distance_count) - 1;
10123 }
10124
10125 if (needs_legacy_glsl_syntax(gl_info))
10126 {
10127 if (pshader && pshader->reg_maps.shader_version.major >= 3
10128 && pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info))
10129 {
10130 TRACE("Shader %d needs vertex color clamping disabled.\n", program_id);
10131 entry->vs.vertex_color_clamp = GL_FALSE;
10132 }
10133 else
10134 {
10135 entry->vs.vertex_color_clamp = GL_FIXED_ONLY_ARB;
10136 }
10137 }
10138 else
10139 {
10140 /* With core profile we never change vertex_color_clamp from
10141 * GL_FIXED_ONLY_MODE (which is also the initial value) so we never call
10142 * glClampColorARB(). */
10143 entry->vs.vertex_color_clamp = GL_FIXED_ONLY_ARB;
10144 }
10145
10146 /* Set the shader to allow uniform loading on it */
10147 GL_EXTCALL(glUseProgram(program_id));
10148 checkGLcall("glUseProgram");
10149
10150 entry->constant_update_mask = 0;
10151 if (vshader)
10152 {
10153 entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
10154 if (vshader->reg_maps.integer_constants)
10155 entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_I;
10156 if (vshader->reg_maps.boolean_constants)
10157 entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B;
10158 if (entry->vs.pos_fixup_location != -1)
10159 entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP;
10160
10161 shader_glsl_load_program_resources(context, priv, program_id, vshader);
10162 }
10163 else
10164 {
10165 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
10167
10168 for (i = 1; i < MAX_VERTEX_INDEX_BLENDS; ++i)
10169 {
10170 if (entry->vs.modelview_matrix_location[i] != -1)
10171 {
10172 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
10173 break;
10174 }
10175 }
10176
10177 for (i = 0; i < MAX_TEXTURES; ++i)
10178 {
10179 if (entry->vs.texture_matrix_location[i] != -1)
10180 {
10181 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX;
10182 break;
10183 }
10184 }
10185 if (entry->vs.material_ambient_location != -1 || entry->vs.material_diffuse_location != -1
10186 || entry->vs.material_specular_location != -1
10187 || entry->vs.material_emissive_location != -1
10188 || entry->vs.material_shininess_location != -1)
10189 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MATERIAL;
10190 if (entry->vs.light_ambient_location != -1)
10191 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_LIGHTS;
10192 }
10193 if (entry->vs.clip_planes_location != -1)
10194 entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES;
10195 if (entry->vs.pointsize_min_location != -1)
10196 entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE;
10197
10198 if (hshader)
10199 shader_glsl_load_program_resources(context, priv, program_id, hshader);
10200
10201 if (dshader)
10202 {
10203 if (entry->ds.pos_fixup_location != -1)
10204 entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP;
10205
10206 shader_glsl_load_program_resources(context, priv, program_id, dshader);
10207 }
10208
10209 if (gshader)
10210 {
10211 if (entry->gs.pos_fixup_location != -1)
10212 entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP;
10213
10214 shader_glsl_load_program_resources(context, priv, program_id, gshader);
10215 }
10216
10217 if (ps_id)
10218 {
10219 if (pshader)
10220 {
10221 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
10222 if (pshader->reg_maps.integer_constants)
10223 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_I;
10224 if (pshader->reg_maps.boolean_constants)
10225 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_B;
10226 if (entry->ps.ycorrection_location != -1)
10227 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR;
10228
10229 shader_glsl_load_program_resources(context, priv, program_id, pshader);
10230 shader_glsl_load_images(gl_info, priv, program_id, &pshader->reg_maps);
10231 }
10232 else
10233 {
10234 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS;
10235
10236 shader_glsl_load_samplers(context, priv, program_id, NULL);
10237 }
10238
10239 for (i = 0; i < MAX_TEXTURES; ++i)
10240 {
10241 if (entry->ps.bumpenv_mat_location[i] != -1)
10242 {
10243 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV;
10244 break;
10245 }
10246 }
10247
10248 if (entry->ps.fog_color_location != -1)
10249 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG;
10250 if (entry->ps.alpha_test_ref_location != -1)
10251 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_ALPHA_TEST;
10252 if (entry->ps.np2_fixup_location != -1)
10253 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
10254 if (entry->ps.color_key_location != -1)
10255 entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_COLOR_KEY;
10256 }
10257}
10258
10259static void shader_glsl_precompile(void *shader_priv, struct wined3d_shader *shader)
10260{
10261 struct wined3d_device *device = shader->device;
10262 struct wined3d_context *context;
10263
10264 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
10265 {
10269 }
10270}
10271
10272/* Context activation is done by the caller. */
10273static void shader_glsl_select(void *shader_priv, struct wined3d_context *context,
10274 const struct wined3d_state *state)
10275{
10276 struct glsl_context_data *ctx_data = context->shader_backend_data;
10277 const struct wined3d_gl_info *gl_info = context->gl_info;
10278 struct shader_glsl_priv *priv = shader_priv;
10279 struct glsl_shader_prog_link *glsl_program;
10280 GLenum current_vertex_color_clamp;
10281 GLuint program_id, prev_id;
10282
10283 priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
10284 priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
10285
10286 prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0;
10287 set_glsl_shader_program(context, state, priv, ctx_data);
10288 glsl_program = ctx_data->glsl_program;
10289
10290 if (glsl_program)
10291 {
10292 program_id = glsl_program->id;
10293 current_vertex_color_clamp = glsl_program->vs.vertex_color_clamp;
10294 if (glsl_program->shader_controlled_clip_distances)
10296 }
10297 else
10298 {
10299 program_id = 0;
10300 current_vertex_color_clamp = GL_FIXED_ONLY_ARB;
10301 }
10302
10303 if (ctx_data->vertex_color_clamp != current_vertex_color_clamp)
10304 {
10305 ctx_data->vertex_color_clamp = current_vertex_color_clamp;
10306 if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT])
10307 {
10308 GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, current_vertex_color_clamp));
10309 checkGLcall("glClampColorARB");
10310 }
10311 else
10312 {
10313 FIXME("Vertex color clamp needs to be changed, but extension not supported.\n");
10314 }
10315 }
10316
10317 TRACE("Using GLSL program %u.\n", program_id);
10318
10319 if (prev_id != program_id)
10320 {
10321 GL_EXTCALL(glUseProgram(program_id));
10322 checkGLcall("glUseProgram");
10323
10324 if (glsl_program)
10325 context->constant_update_mask |= glsl_program->constant_update_mask;
10326 }
10327
10328 context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
10329}
10330
10331/* Context activation is done by the caller. */
10332static void shader_glsl_select_compute(void *shader_priv, struct wined3d_context *context,
10333 const struct wined3d_state *state)
10334{
10335 struct glsl_context_data *ctx_data = context->shader_backend_data;
10336 const struct wined3d_gl_info *gl_info = context->gl_info;
10337 struct shader_glsl_priv *priv = shader_priv;
10338 GLuint program_id, prev_id;
10339
10340 prev_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0;
10342 program_id = ctx_data->glsl_program ? ctx_data->glsl_program->id : 0;
10343
10344 TRACE("Using GLSL program %u.\n", program_id);
10345
10346 if (prev_id != program_id)
10347 {
10348 GL_EXTCALL(glUseProgram(program_id));
10349 checkGLcall("glUseProgram");
10350 }
10351
10352 context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_PIXEL)
10355 | (1u << WINED3D_SHADER_TYPE_HULL)
10357}
10358
10359/* "context" is not necessarily the currently active context. */
10361{
10362 struct glsl_context_data *ctx_data = context->shader_backend_data;
10363
10364 ctx_data->glsl_program = NULL;
10365 context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
10368 | (1u << WINED3D_SHADER_TYPE_HULL)
10371}
10372
10373/* Context activation is done by the caller. */
10374static void shader_glsl_disable(void *shader_priv, struct wined3d_context *context)
10375{
10376 struct glsl_context_data *ctx_data = context->shader_backend_data;
10377 const struct wined3d_gl_info *gl_info = context->gl_info;
10378 struct shader_glsl_priv *priv = shader_priv;
10379
10381 GL_EXTCALL(glUseProgram(0));
10382 checkGLcall("glUseProgram");
10383
10384 priv->vertex_pipe->vp_enable(gl_info, FALSE);
10385 priv->fragment_pipe->enable_extension(gl_info, FALSE);
10386
10388 {
10391 checkGLcall("glClampColorARB");
10392 }
10393}
10394
10396 const struct glsl_shader_prog_link *program)
10397{
10398 const struct glsl_context_data *ctx_data;
10399 struct wined3d_context *context;
10400 unsigned int i;
10401
10402 for (i = 0; i < device->context_count; ++i)
10403 {
10404 context = device->contexts[i];
10405 ctx_data = context->shader_backend_data;
10406
10407 if (ctx_data->glsl_program == program)
10409 }
10410}
10411
10413{
10414 struct glsl_shader_private *shader_data = shader->backend_data;
10415 struct wined3d_device *device = shader->device;
10416 struct shader_glsl_priv *priv = device->shader_priv;
10417 const struct wined3d_gl_info *gl_info;
10418 const struct list *linked_programs;
10419 struct wined3d_context *context;
10420
10421 if (!shader_data || !shader_data->num_gl_shaders)
10422 {
10423 heap_free(shader_data);
10424 shader->backend_data = NULL;
10425 return;
10426 }
10427
10429 gl_info = context->gl_info;
10430
10431 TRACE("Deleting linked programs.\n");
10432 linked_programs = &shader->linked_programs;
10433 if (linked_programs->next)
10434 {
10435 struct glsl_shader_prog_link *entry, *entry2;
10436 UINT i;
10437
10438 switch (shader->reg_maps.shader_version.type)
10439 {
10441 {
10442 struct glsl_ps_compiled_shader *gl_shaders = shader_data->gl_shaders.ps;
10443
10444 for (i = 0; i < shader_data->num_gl_shaders; ++i)
10445 {
10446 TRACE("Deleting pixel shader %u.\n", gl_shaders[i].id);
10447 GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
10448 checkGLcall("glDeleteShader");
10449 }
10450 heap_free(shader_data->gl_shaders.ps);
10451
10452 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
10453 struct glsl_shader_prog_link, ps.shader_entry)
10454 {
10456 delete_glsl_program_entry(priv, gl_info, entry);
10457 }
10458
10459 break;
10460 }
10461
10463 {
10464 struct glsl_vs_compiled_shader *gl_shaders = shader_data->gl_shaders.vs;
10465
10466 for (i = 0; i < shader_data->num_gl_shaders; ++i)
10467 {
10468 TRACE("Deleting vertex shader %u.\n", gl_shaders[i].id);
10469 GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
10470 checkGLcall("glDeleteShader");
10471 }
10472 heap_free(shader_data->gl_shaders.vs);
10473
10474 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
10475 struct glsl_shader_prog_link, vs.shader_entry)
10476 {
10478 delete_glsl_program_entry(priv, gl_info, entry);
10479 }
10480
10481 break;
10482 }
10483
10485 {
10486 struct glsl_hs_compiled_shader *gl_shaders = shader_data->gl_shaders.hs;
10487
10488 for (i = 0; i < shader_data->num_gl_shaders; ++i)
10489 {
10490 TRACE("Deleting hull shader %u.\n", gl_shaders[i].id);
10491 GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
10492 checkGLcall("glDeleteShader");
10493 }
10494 heap_free(shader_data->gl_shaders.hs);
10495
10496 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
10497 struct glsl_shader_prog_link, hs.shader_entry)
10498 {
10500 delete_glsl_program_entry(priv, gl_info, entry);
10501 }
10502
10503 break;
10504 }
10505
10507 {
10508 struct glsl_ds_compiled_shader *gl_shaders = shader_data->gl_shaders.ds;
10509
10510 for (i = 0; i < shader_data->num_gl_shaders; ++i)
10511 {
10512 TRACE("Deleting domain shader %u.\n", gl_shaders[i].id);
10513 GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
10514 checkGLcall("glDeleteShader");
10515 }
10516 heap_free(shader_data->gl_shaders.ds);
10517
10518 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
10519 struct glsl_shader_prog_link, ds.shader_entry)
10520 {
10522 delete_glsl_program_entry(priv, gl_info, entry);
10523 }
10524
10525 break;
10526 }
10527
10529 {
10530 struct glsl_gs_compiled_shader *gl_shaders = shader_data->gl_shaders.gs;
10531
10532 for (i = 0; i < shader_data->num_gl_shaders; ++i)
10533 {
10534 TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id);
10535 GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
10536 checkGLcall("glDeleteShader");
10537 }
10538 heap_free(shader_data->gl_shaders.gs);
10539
10540 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
10541 struct glsl_shader_prog_link, gs.shader_entry)
10542 {
10544 delete_glsl_program_entry(priv, gl_info, entry);
10545 }
10546
10547 break;
10548 }
10549
10551 {
10552 struct glsl_cs_compiled_shader *gl_shaders = shader_data->gl_shaders.cs;
10553
10554 for (i = 0; i < shader_data->num_gl_shaders; ++i)
10555 {
10556 TRACE("Deleting compute shader %u.\n", gl_shaders[i].id);
10557 GL_EXTCALL(glDeleteShader(gl_shaders[i].id));
10558 checkGLcall("glDeleteShader");
10559 }
10560 heap_free(shader_data->gl_shaders.cs);
10561
10562 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
10563 struct glsl_shader_prog_link, cs.shader_entry)
10564 {
10566 delete_glsl_program_entry(priv, gl_info, entry);
10567 }
10568
10569 break;
10570 }
10571
10572 default:
10573 ERR("Unhandled shader type %#x.\n", shader->reg_maps.shader_version.type);
10574 break;
10575 }
10576 }
10577
10578 heap_free(shader->backend_data);
10579 shader->backend_data = NULL;
10580
10582}
10583
10584static int glsl_program_key_compare(const void *key, const struct wine_rb_entry *entry)
10585{
10586 const struct glsl_program_key *k = key;
10589
10590 if (k->vs_id > prog->vs.id) return 1;
10591 else if (k->vs_id < prog->vs.id) return -1;
10592
10593 if (k->gs_id > prog->gs.id) return 1;
10594 else if (k->gs_id < prog->gs.id) return -1;
10595
10596 if (k->ps_id > prog->ps.id) return 1;
10597 else if (k->ps_id < prog->ps.id) return -1;
10598
10599 if (k->hs_id > prog->hs.id) return 1;
10600 else if (k->hs_id < prog->hs.id) return -1;
10601
10602 if (k->ds_id > prog->ds.id) return 1;
10603 else if (k->ds_id < prog->ds.id) return -1;
10604
10605 if (k->cs_id > prog->cs.id) return 1;
10606 else if (k->cs_id < prog->cs.id) return -1;
10607
10608 return 0;
10609}
10610
10612{
10613 SIZE_T size = (constant_count + 1) * sizeof(*heap->entries)
10614 + constant_count * sizeof(*heap->contained)
10615 + constant_count * sizeof(*heap->positions);
10616 void *mem;
10617
10618 if (!(mem = heap_alloc(size)))
10619 {
10620 ERR("Failed to allocate memory\n");
10621 return FALSE;
10622 }
10623
10624 heap->entries = mem;
10625 heap->entries[1].version = 0;
10626 heap->contained = (BOOL *)(heap->entries + constant_count + 1);
10627 memset(heap->contained, 0, constant_count * sizeof(*heap->contained));
10628 heap->positions = (unsigned int *)(heap->contained + constant_count);
10629 heap->size = 1;
10630
10631 return TRUE;
10632}
10633
10635{
10636 heap_free(heap->entries);
10637}
10638
10640 const struct fragment_pipeline *fragment_pipe)
10641{
10643 const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
10645 void *vertex_priv, *fragment_priv;
10646 struct shader_glsl_priv *priv;
10647
10648 if (!(priv = heap_alloc_zero(sizeof(*priv))))
10649 return E_OUTOFMEMORY;
10650
10652
10653 if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
10654 {
10655 ERR("Failed to initialize vertex pipe.\n");
10656 heap_free(priv);
10657 return E_FAIL;
10658 }
10659
10660 if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv)))
10661 {
10662 ERR("Failed to initialize fragment pipe.\n");
10663 vertex_pipe->vp_free(device);
10664 heap_free(priv);
10665 return E_FAIL;
10666 }
10667
10668 if (!string_buffer_init(&priv->shader_buffer))
10669 {
10670 ERR("Failed to initialize shader buffer.\n");
10671 goto fail;
10672 }
10673
10674 if (!(priv->stack = heap_calloc(stack_size, sizeof(*priv->stack))))
10675 {
10676 ERR("Failed to allocate memory.\n");
10677 goto fail;
10678 }
10679
10681 {
10682 ERR("Failed to initialize vertex shader constant heap\n");
10683 goto fail;
10684 }
10685
10687 {
10688 ERR("Failed to initialize pixel shader constant heap\n");
10689 goto fail;
10690 }
10691
10693
10694 priv->next_constant_version = 1;
10695 priv->vertex_pipe = vertex_pipe;
10697 fragment_pipe->get_caps(gl_info, &fragment_caps);
10699 priv->legacy_lighting = device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING;
10700
10701 device->vertex_priv = vertex_priv;
10702 device->fragment_priv = fragment_priv;
10703 device->shader_priv = priv;
10704
10705 return WINED3D_OK;
10706
10707fail:
10710 heap_free(priv->stack);
10712 fragment_pipe->free_private(device);
10713 vertex_pipe->vp_free(device);
10714 heap_free(priv);
10715 return E_OUTOFMEMORY;
10716}
10717
10718/* Context activation is done by the caller. */
10720{
10721 struct shader_glsl_priv *priv = device->shader_priv;
10722
10726 heap_free(priv->stack);
10729 priv->fragment_pipe->free_private(device);
10730 priv->vertex_pipe->vp_free(device);
10731
10732 heap_free(device->shader_priv);
10733 device->shader_priv = NULL;
10734}
10735
10737{
10738 struct glsl_context_data *ctx_data;
10739
10740 if (!(ctx_data = heap_alloc_zero(sizeof(*ctx_data))))
10741 return FALSE;
10743 context->shader_backend_data = ctx_data;
10744 return TRUE;
10745}
10746
10748{
10749 heap_free(context->shader_backend_data);
10750}
10751
10753{
10754 const struct wined3d_gl_info *gl_info = context->gl_info;
10755
10756 gl_info->gl_ops.gl.p_glEnable(GL_PROGRAM_POINT_SIZE);
10757 checkGLcall("GL_PROGRAM_POINT_SIZE");
10758}
10759
10760static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *gl_info)
10761{
10762 BOOL shader_model_4 = gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)
10764 && gl_info->supported[ARB_SAMPLER_OBJECTS]
10766 && gl_info->supported[ARB_TEXTURE_SWIZZLE];
10767
10768 if (shader_model_4
10769 && gl_info->supported[ARB_COMPUTE_SHADER]
10770 && gl_info->supported[ARB_CULL_DISTANCE]
10772 && gl_info->supported[ARB_DRAW_INDIRECT]
10773 && gl_info->supported[ARB_GPU_SHADER5]
10776 && gl_info->supported[ARB_SHADER_IMAGE_SIZE]
10779 && gl_info->supported[ARB_TEXTURE_GATHER]
10781 return 5;
10782
10783 if (shader_model_4)
10784 return 4;
10785
10786 /* Support for texldd and texldl instructions in pixel shaders is required
10787 * for SM3. */
10789 return 3;
10790
10791 return 2;
10792}
10793
10794static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
10795{
10796 unsigned int shader_model = shader_glsl_get_shader_model(gl_info);
10797
10798 TRACE("Shader model %u.\n", shader_model);
10799
10800 caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model);
10801 caps->hs_version = min(wined3d_settings.max_sm_hs, shader_model);
10802 caps->ds_version = min(wined3d_settings.max_sm_ds, shader_model);
10803 caps->gs_version = min(wined3d_settings.max_sm_gs, shader_model);
10804 caps->ps_version = min(wined3d_settings.max_sm_ps, shader_model);
10805 caps->cs_version = min(wined3d_settings.max_sm_cs, shader_model);
10806
10807 caps->vs_version = gl_info->supported[ARB_VERTEX_SHADER] ? caps->vs_version : 0;
10808 caps->ps_version = gl_info->supported[ARB_FRAGMENT_SHADER] ? caps->ps_version : 0;
10809
10810 caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants);
10811 caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants);
10812 caps->varying_count = gl_info->limits.glsl_varyings;
10813
10814 /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
10815 * Direct3D minimum requirement.
10816 *
10817 * Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
10818 * of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
10819 *
10820 * The problem is that the refrast clamps temporary results in the shader to
10821 * [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
10822 * then applications may miss the clamping behavior. On the other hand, if it is smaller,
10823 * the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
10824 * offer a way to query this.
10825 */
10826 if (shader_model >= 4)
10827 caps->ps_1x_max_value = FLT_MAX;
10828 else
10829 caps->ps_1x_max_value = 1024.0f;
10830
10831 /* Ideally we'd only set caps like sRGB writes here if supported by both
10832 * the shader backend and the fragment pipe, but we can get called before
10833 * shader_glsl_alloc(). */
10836}
10837
10839{
10840 /* We support everything except YUV conversions. */
10841 return !is_complex_fixup(fixup);
10842}
10843
10845{
10846 /* WINED3DSIH_ABS */ shader_glsl_map2gl,
10847 /* WINED3DSIH_ADD */ shader_glsl_binop,
10848 /* WINED3DSIH_AND */ shader_glsl_binop,
10849 /* WINED3DSIH_ATOMIC_AND */ shader_glsl_atomic,
10850 /* WINED3DSIH_ATOMIC_CMP_STORE */ shader_glsl_atomic,
10851 /* WINED3DSIH_ATOMIC_IADD */ shader_glsl_atomic,
10852 /* WINED3DSIH_ATOMIC_IMAX */ shader_glsl_atomic,
10853 /* WINED3DSIH_ATOMIC_IMIN */ shader_glsl_atomic,
10854 /* WINED3DSIH_ATOMIC_OR */ shader_glsl_atomic,
10855 /* WINED3DSIH_ATOMIC_UMAX */ shader_glsl_atomic,
10856 /* WINED3DSIH_ATOMIC_UMIN */ shader_glsl_atomic,
10857 /* WINED3DSIH_ATOMIC_XOR */ shader_glsl_atomic,
10858 /* WINED3DSIH_BEM */ shader_glsl_bem,
10859 /* WINED3DSIH_BFI */ shader_glsl_bitwise_op,
10860 /* WINED3DSIH_BFREV */ shader_glsl_map2gl,
10861 /* WINED3DSIH_BREAK */ shader_glsl_break,
10862 /* WINED3DSIH_BREAKC */ shader_glsl_breakc,
10863 /* WINED3DSIH_BREAKP */ shader_glsl_conditional_op,
10864 /* WINED3DSIH_BUFINFO */ shader_glsl_bufinfo,
10865 /* WINED3DSIH_CALL */ shader_glsl_call,
10866 /* WINED3DSIH_CALLNZ */ shader_glsl_callnz,
10867 /* WINED3DSIH_CASE */ shader_glsl_case,
10868 /* WINED3DSIH_CMP */ shader_glsl_conditional_move,
10869 /* WINED3DSIH_CND */ shader_glsl_cnd,
10870 /* WINED3DSIH_CONTINUE */ shader_glsl_continue,
10871 /* WINED3DSIH_CONTINUEP */ shader_glsl_conditional_op,
10872 /* WINED3DSIH_COUNTBITS */ shader_glsl_map2gl,
10873 /* WINED3DSIH_CRS */ shader_glsl_cross,
10874 /* WINED3DSIH_CUT */ shader_glsl_cut,
10875 /* WINED3DSIH_CUT_STREAM */ shader_glsl_cut,
10876 /* WINED3DSIH_DCL */ shader_glsl_nop,
10877 /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_glsl_nop,
10878 /* WINED3DSIH_DCL_FUNCTION_BODY */ NULL,
10879 /* WINED3DSIH_DCL_FUNCTION_TABLE */ NULL,
10880 /* WINED3DSIH_DCL_GLOBAL_FLAGS */ shader_glsl_nop,
10881 /* WINED3DSIH_DCL_GS_INSTANCES */ shader_glsl_nop,
10882 /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ shader_glsl_nop,
10883 /* WINED3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT */ shader_glsl_nop,
10884 /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR */ shader_glsl_nop,
10885 /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ shader_glsl_nop,
10886 /* WINED3DSIH_DCL_INDEX_RANGE */ shader_glsl_nop,
10887 /* WINED3DSIH_DCL_INDEXABLE_TEMP */ shader_glsl_nop,
10888 /* WINED3DSIH_DCL_INPUT */ shader_glsl_nop,
10889 /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ shader_glsl_nop,
10890 /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop,
10891 /* WINED3DSIH_DCL_INPUT_PS */ shader_glsl_nop,
10892 /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL,
10893 /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL,
10894 /* WINED3DSIH_DCL_INPUT_SGV */ shader_glsl_nop,
10895 /* WINED3DSIH_DCL_INPUT_SIV */ shader_glsl_nop,
10896 /* WINED3DSIH_DCL_INTERFACE */ NULL,
10897 /* WINED3DSIH_DCL_OUTPUT */ shader_glsl_nop,
10898 /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT */ shader_glsl_nop,
10899 /* WINED3DSIH_DCL_OUTPUT_SIV */ shader_glsl_nop,
10900 /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_glsl_nop,
10901 /* WINED3DSIH_DCL_RESOURCE_RAW */ shader_glsl_nop,
10902 /* WINED3DSIH_DCL_RESOURCE_STRUCTURED */ shader_glsl_nop,
10903 /* WINED3DSIH_DCL_SAMPLER */ shader_glsl_nop,
10904 /* WINED3DSIH_DCL_STREAM */ NULL,
10905 /* WINED3DSIH_DCL_TEMPS */ shader_glsl_nop,
10906 /* WINED3DSIH_DCL_TESSELLATOR_DOMAIN */ shader_glsl_nop,
10907 /* WINED3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE */ shader_glsl_nop,
10908 /* WINED3DSIH_DCL_TESSELLATOR_PARTITIONING */ shader_glsl_nop,
10909 /* WINED3DSIH_DCL_TGSM_RAW */ shader_glsl_nop,
10910 /* WINED3DSIH_DCL_TGSM_STRUCTURED */ shader_glsl_nop,
10911 /* WINED3DSIH_DCL_THREAD_GROUP */ shader_glsl_nop,
10912 /* WINED3DSIH_DCL_UAV_RAW */ shader_glsl_nop,
10913 /* WINED3DSIH_DCL_UAV_STRUCTURED */ shader_glsl_nop,
10914 /* WINED3DSIH_DCL_UAV_TYPED */ shader_glsl_nop,
10915 /* WINED3DSIH_DCL_VERTICES_OUT */ shader_glsl_nop,
10916 /* WINED3DSIH_DEF */ shader_glsl_nop,
10917 /* WINED3DSIH_DEFAULT */ shader_glsl_default,
10918 /* WINED3DSIH_DEFB */ shader_glsl_nop,
10919 /* WINED3DSIH_DEFI */ shader_glsl_nop,
10920 /* WINED3DSIH_DIV */ shader_glsl_binop,
10921 /* WINED3DSIH_DP2 */ shader_glsl_dot,
10922 /* WINED3DSIH_DP2ADD */ shader_glsl_dp2add,
10923 /* WINED3DSIH_DP3 */ shader_glsl_dot,
10924 /* WINED3DSIH_DP4 */ shader_glsl_dot,
10925 /* WINED3DSIH_DST */ shader_glsl_dst,
10926 /* WINED3DSIH_DSX */ shader_glsl_map2gl,
10927 /* WINED3DSIH_DSX_COARSE */ shader_glsl_map2gl,
10928 /* WINED3DSIH_DSX_FINE */ shader_glsl_map2gl,
10929 /* WINED3DSIH_DSY */ shader_glsl_map2gl,
10930 /* WINED3DSIH_DSY_COARSE */ shader_glsl_map2gl,
10931 /* WINED3DSIH_DSY_FINE */ shader_glsl_map2gl,
10932 /* WINED3DSIH_EVAL_SAMPLE_INDEX */ NULL,
10933 /* WINED3DSIH_ELSE */ shader_glsl_else,
10934 /* WINED3DSIH_EMIT */ shader_glsl_emit,
10935 /* WINED3DSIH_EMIT_STREAM */ shader_glsl_emit,
10936 /* WINED3DSIH_ENDIF */ shader_glsl_end,
10937 /* WINED3DSIH_ENDLOOP */ shader_glsl_end,
10938 /* WINED3DSIH_ENDREP */ shader_glsl_end,
10939 /* WINED3DSIH_ENDSWITCH */ shader_glsl_end,
10940 /* WINED3DSIH_EQ */ shader_glsl_relop,
10941 /* WINED3DSIH_EXP */ shader_glsl_scalar_op,
10942 /* WINED3DSIH_EXPP */ shader_glsl_expp,
10943 /* WINED3DSIH_F16TOF32 */ shader_glsl_float16,
10944 /* WINED3DSIH_F32TOF16 */ shader_glsl_float16,
10945 /* WINED3DSIH_FCALL */ NULL,
10946 /* WINED3DSIH_FIRSTBIT_HI */ shader_glsl_map2gl,
10947 /* WINED3DSIH_FIRSTBIT_LO */ shader_glsl_map2gl,
10948 /* WINED3DSIH_FIRSTBIT_SHI */ shader_glsl_map2gl,
10949 /* WINED3DSIH_FRC */ shader_glsl_map2gl,
10950 /* WINED3DSIH_FTOI */ shader_glsl_to_int,
10951 /* WINED3DSIH_FTOU */ shader_glsl_to_uint,
10952 /* WINED3DSIH_GATHER4 */ shader_glsl_gather4,
10953 /* WINED3DSIH_GATHER4_C */ shader_glsl_gather4,
10954 /* WINED3DSIH_GATHER4_PO */ shader_glsl_gather4,
10955 /* WINED3DSIH_GATHER4_PO_C */ shader_glsl_gather4,
10956 /* WINED3DSIH_GE */ shader_glsl_relop,
10957 /* WINED3DSIH_HS_CONTROL_POINT_PHASE */ shader_glsl_nop,
10958 /* WINED3DSIH_HS_DECLS */ shader_glsl_nop,
10959 /* WINED3DSIH_HS_FORK_PHASE */ shader_glsl_nop,
10960 /* WINED3DSIH_HS_JOIN_PHASE */ shader_glsl_nop,
10961 /* WINED3DSIH_IADD */ shader_glsl_binop,
10962 /* WINED3DSIH_IBFE */ shader_glsl_bitwise_op,
10963 /* WINED3DSIH_IEQ */ shader_glsl_relop,
10964 /* WINED3DSIH_IF */ shader_glsl_if,
10965 /* WINED3DSIH_IFC */ shader_glsl_ifc,
10966 /* WINED3DSIH_IGE */ shader_glsl_relop,
10967 /* WINED3DSIH_ILT */ shader_glsl_relop,
10968 /* WINED3DSIH_IMAD */ shader_glsl_mad,
10969 /* WINED3DSIH_IMAX */ shader_glsl_map2gl,
10970 /* WINED3DSIH_IMIN */ shader_glsl_map2gl,
10971 /* WINED3DSIH_IMM_ATOMIC_ALLOC */ shader_glsl_uav_counter,
10972 /* WINED3DSIH_IMM_ATOMIC_AND */ shader_glsl_atomic,
10973 /* WINED3DSIH_IMM_ATOMIC_CMP_EXCH */ shader_glsl_atomic,
10974 /* WINED3DSIH_IMM_ATOMIC_CONSUME */ shader_glsl_uav_counter,
10975 /* WINED3DSIH_IMM_ATOMIC_EXCH */ shader_glsl_atomic,
10976 /* WINED3DSIH_IMM_ATOMIC_IADD */ shader_glsl_atomic,
10977 /* WINED3DSIH_IMM_ATOMIC_IMAX */ shader_glsl_atomic,
10978 /* WINED3DSIH_IMM_ATOMIC_IMIN */ shader_glsl_atomic,
10979 /* WINED3DSIH_IMM_ATOMIC_OR */ shader_glsl_atomic,
10980 /* WINED3DSIH_IMM_ATOMIC_UMAX */ shader_glsl_atomic,
10981 /* WINED3DSIH_IMM_ATOMIC_UMIN */ shader_glsl_atomic,
10982 /* WINED3DSIH_IMM_ATOMIC_XOR */ shader_glsl_atomic,
10983 /* WINED3DSIH_IMUL */ shader_glsl_mul_extended,
10984 /* WINED3DSIH_INE */ shader_glsl_relop,
10985 /* WINED3DSIH_INEG */ shader_glsl_unary_op,
10986 /* WINED3DSIH_ISHL */ shader_glsl_binop,
10987 /* WINED3DSIH_ISHR */ shader_glsl_binop,
10988 /* WINED3DSIH_ITOF */ shader_glsl_to_float,
10989 /* WINED3DSIH_LABEL */ shader_glsl_label,
10990 /* WINED3DSIH_LD */ shader_glsl_ld,
10991 /* WINED3DSIH_LD2DMS */ shader_glsl_ld,
10992 /* WINED3DSIH_LD_RAW */ shader_glsl_ld_raw_structured,
10993 /* WINED3DSIH_LD_STRUCTURED */ shader_glsl_ld_raw_structured,
10994 /* WINED3DSIH_LD_UAV_TYPED */ shader_glsl_ld_uav,
10995 /* WINED3DSIH_LIT */ shader_glsl_lit,
10996 /* WINED3DSIH_LOD */ NULL,
10997 /* WINED3DSIH_LOG */ shader_glsl_scalar_op,
10998 /* WINED3DSIH_LOGP */ shader_glsl_scalar_op,
10999 /* WINED3DSIH_LOOP */ shader_glsl_loop,
11000 /* WINED3DSIH_LRP */ shader_glsl_lrp,
11001 /* WINED3DSIH_LT */ shader_glsl_relop,
11002 /* WINED3DSIH_M3x2 */ shader_glsl_mnxn,
11003 /* WINED3DSIH_M3x3 */ shader_glsl_mnxn,
11004 /* WINED3DSIH_M3x4 */ shader_glsl_mnxn,
11005 /* WINED3DSIH_M4x3 */ shader_glsl_mnxn,
11006 /* WINED3DSIH_M4x4 */ shader_glsl_mnxn,
11007 /* WINED3DSIH_MAD */ shader_glsl_mad,
11008 /* WINED3DSIH_MAX */ shader_glsl_map2gl,
11009 /* WINED3DSIH_MIN */ shader_glsl_map2gl,
11010 /* WINED3DSIH_MOV */ shader_glsl_mov,
11011 /* WINED3DSIH_MOVA */ shader_glsl_mov,
11012 /* WINED3DSIH_MOVC */ shader_glsl_conditional_move,
11013 /* WINED3DSIH_MUL */ shader_glsl_binop,
11014 /* WINED3DSIH_NE */ shader_glsl_relop,
11015 /* WINED3DSIH_NOP */ shader_glsl_nop,
11016 /* WINED3DSIH_NOT */ shader_glsl_unary_op,
11017 /* WINED3DSIH_NRM */ shader_glsl_nrm,
11018 /* WINED3DSIH_OR */ shader_glsl_binop,
11019 /* WINED3DSIH_PHASE */ shader_glsl_nop,
11020 /* WINED3DSIH_POW */ shader_glsl_pow,
11021 /* WINED3DSIH_RCP */ shader_glsl_scalar_op,
11022 /* WINED3DSIH_REP */ shader_glsl_rep,
11023 /* WINED3DSIH_RESINFO */ shader_glsl_resinfo,
11024 /* WINED3DSIH_RET */ shader_glsl_ret,
11025 /* WINED3DSIH_RETP */ shader_glsl_conditional_op,
11026 /* WINED3DSIH_ROUND_NE */ shader_glsl_map2gl,
11027 /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl,
11028 /* WINED3DSIH_ROUND_PI */ shader_glsl_map2gl,
11029 /* WINED3DSIH_ROUND_Z */ shader_glsl_map2gl,
11030 /* WINED3DSIH_RSQ */ shader_glsl_scalar_op,
11031 /* WINED3DSIH_SAMPLE */ shader_glsl_sample,
11032 /* WINED3DSIH_SAMPLE_B */ shader_glsl_sample,
11033 /* WINED3DSIH_SAMPLE_C */ shader_glsl_sample_c,
11034 /* WINED3DSIH_SAMPLE_C_LZ */ shader_glsl_sample_c,
11035 /* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample,
11036 /* WINED3DSIH_SAMPLE_INFO */ NULL,
11037 /* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample,
11038 /* WINED3DSIH_SAMPLE_POS */ NULL,
11039 /* WINED3DSIH_SETP */ NULL,
11040 /* WINED3DSIH_SGE */ shader_glsl_compare,
11041 /* WINED3DSIH_SGN */ shader_glsl_sgn,
11042 /* WINED3DSIH_SINCOS */ shader_glsl_sincos,
11043 /* WINED3DSIH_SLT */ shader_glsl_compare,
11044 /* WINED3DSIH_SQRT */ shader_glsl_map2gl,
11045 /* WINED3DSIH_STORE_RAW */ shader_glsl_store_raw_structured,
11046 /* WINED3DSIH_STORE_STRUCTURED */ shader_glsl_store_raw_structured,
11047 /* WINED3DSIH_STORE_UAV_TYPED */ shader_glsl_store_uav,
11048 /* WINED3DSIH_SUB */ shader_glsl_binop,
11049 /* WINED3DSIH_SWAPC */ shader_glsl_swapc,
11050 /* WINED3DSIH_SWITCH */ shader_glsl_switch,
11051 /* WINED3DSIH_SYNC */ shader_glsl_sync,
11052 /* WINED3DSIH_TEX */ shader_glsl_tex,
11053 /* WINED3DSIH_TEXBEM */ shader_glsl_texbem,
11054 /* WINED3DSIH_TEXBEML */ shader_glsl_texbem,
11055 /* WINED3DSIH_TEXCOORD */ shader_glsl_texcoord,
11056 /* WINED3DSIH_TEXDEPTH */ shader_glsl_texdepth,
11057 /* WINED3DSIH_TEXDP3 */ shader_glsl_texdp3,
11058 /* WINED3DSIH_TEXDP3TEX */ shader_glsl_texdp3tex,
11059 /* WINED3DSIH_TEXKILL */ shader_glsl_texkill,
11060 /* WINED3DSIH_TEXLDD */ shader_glsl_texldd,
11061 /* WINED3DSIH_TEXLDL */ shader_glsl_texldl,
11062 /* WINED3DSIH_TEXM3x2DEPTH */ shader_glsl_texm3x2depth,
11063 /* WINED3DSIH_TEXM3x2PAD */ shader_glsl_texm3x2pad,
11064 /* WINED3DSIH_TEXM3x2TEX */ shader_glsl_texm3x2tex,
11065 /* WINED3DSIH_TEXM3x3 */ shader_glsl_texm3x3,
11066 /* WINED3DSIH_TEXM3x3DIFF */ NULL,
11067 /* WINED3DSIH_TEXM3x3PAD */ shader_glsl_texm3x3pad,
11068 /* WINED3DSIH_TEXM3x3SPEC */ shader_glsl_texm3x3spec,
11069 /* WINED3DSIH_TEXM3x3TEX */ shader_glsl_texm3x3tex,
11070 /* WINED3DSIH_TEXM3x3VSPEC */ shader_glsl_texm3x3vspec,
11071 /* WINED3DSIH_TEXREG2AR */ shader_glsl_texreg2ar,
11072 /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb,
11073 /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb,
11074 /* WINED3DSIH_UBFE */ shader_glsl_bitwise_op,
11075 /* WINED3DSIH_UDIV */ shader_glsl_udiv,
11076 /* WINED3DSIH_UGE */ shader_glsl_relop,
11077 /* WINED3DSIH_ULT */ shader_glsl_relop,
11078 /* WINED3DSIH_UMAX */ shader_glsl_map2gl,
11079 /* WINED3DSIH_UMIN */ shader_glsl_map2gl,
11080 /* WINED3DSIH_UMUL */ shader_glsl_mul_extended,
11081 /* WINED3DSIH_USHR */ shader_glsl_binop,
11082 /* WINED3DSIH_UTOF */ shader_glsl_to_float,
11083 /* WINED3DSIH_XOR */ shader_glsl_binop,
11084};
11085
11087 SHADER_HANDLER hw_fct;
11088
11089 /* Select handler */
11091
11092 /* Unhandled opcode */
11093 if (!hw_fct)
11094 {
11095 FIXME("Backend can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
11096 return;
11097 }
11098 hw_fct(ins);
11099
11101}
11102
11104{
11105 struct shader_glsl_priv *priv = shader_priv;
11106
11107 return priv->ffp_proj_control;
11108}
11109
11111{
11129};
11130
11131static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
11132
11133static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
11134{
11135 caps->xyzrhw = TRUE;
11148 caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 8; /* 8 texture coordinates. */
11149 caps->max_user_clip_planes = gl_info->limits.user_clip_distances;
11151}
11152
11154{
11157 return 0;
11158}
11159
11160static void *glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
11161{
11162 struct shader_glsl_priv *priv;
11163
11164 if (shader_backend == &glsl_shader_backend)
11165 {
11166 priv = shader_priv;
11168 return priv;
11169 }
11170
11171 FIXME("GLSL vertex pipe without GLSL shader backend not implemented.\n");
11172
11173 return NULL;
11174}
11175
11177{
11179 struct glsl_ffp_vertex_shader, desc.entry);
11180 struct glsl_shader_prog_link *program, *program2;
11182
11183 LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs,
11184 struct glsl_shader_prog_link, vs.shader_entry)
11185 {
11186 delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
11187 }
11188 ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id);
11190}
11191
11192/* Context activation is done by the caller. */
11194{
11195 struct shader_glsl_priv *priv = device->vertex_priv;
11197
11198 ctx.priv = priv;
11199 ctx.gl_info = &device->adapter->gl_info;
11201}
11202
11204 const struct wined3d_state *state, DWORD state_id) {}
11205
11207 const struct wined3d_state *state, DWORD state_id)
11208{
11209 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11210}
11211
11213 const struct wined3d_state *state, DWORD state_id)
11214{
11215 const struct wined3d_gl_info *gl_info = context->gl_info;
11216 BOOL normal = !!(context->stream_info.use_map & (1u << WINED3D_FFP_NORMAL));
11217 const BOOL legacy_clip_planes = needs_legacy_glsl_syntax(gl_info);
11218 BOOL transformed = context->stream_info.position_transformed;
11219 BOOL wasrhw = context->last_was_rhw;
11220 unsigned int i;
11221
11222 context->last_was_rhw = transformed;
11223
11224 /* If the vertex declaration contains a transformed position attribute,
11225 * the draw uses the fixed function vertex pipeline regardless of any
11226 * vertex shader set by the application. */
11227 if (transformed != wasrhw
11228 || context->stream_info.swizzle_map != context->last_swizzle_map)
11229 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11230
11231 context->last_swizzle_map = context->stream_info.swizzle_map;
11232
11233 if (!use_vs(state))
11234 {
11235 if (context->last_was_vshader)
11236 {
11237 if (legacy_clip_planes)
11238 for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
11240 else
11241 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES;
11242 }
11243
11244 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX;
11245
11246 /* Because of settings->texcoords, we have to regenerate the vertex
11247 * shader on a vdecl change if there aren't enough varyings to just
11248 * always output all the texture coordinates. */
11249 if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info)
11250 || normal != context->last_was_normal)
11251 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11252
11253 if (use_ps(state)
11254 && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.major == 1
11255 && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3)
11256 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11257 }
11258 else
11259 {
11260 if (!context->last_was_vshader)
11261 {
11262 /* Vertex shader clipping ignores the view matrix. Update all clip planes. */
11263 if (legacy_clip_planes)
11264 for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
11266 else
11267 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES;
11268 }
11269 }
11270
11271 context->last_was_vshader = use_vs(state);
11272 context->last_was_normal = normal;
11273}
11274
11276 const struct wined3d_state *state, DWORD state_id)
11277{
11278 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11279 /* Different vertex shaders potentially require a different vertex attributes setup. */
11282}
11283
11285 const struct wined3d_state *state, DWORD state_id)
11286{
11287 /* In Direct3D tessellator options (e.g. output primitive type, primitive
11288 * winding) are defined in Hull Shaders, while in GLSL those are
11289 * specified in Tessellation Evaluation Shaders. */
11290 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN;
11291
11292 if (state->shader[WINED3D_SHADER_TYPE_VERTEX])
11293 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11294}
11295
11297 const struct wined3d_state *state, DWORD state_id)
11298{
11299 struct glsl_context_data *ctx_data = context->shader_backend_data;
11301
11304 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11306
11307 if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
11308 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN;
11309 else if (state->shader[WINED3D_SHADER_TYPE_VERTEX]
11310 && state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.shader_version.major >= 4)
11311 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11312}
11313
11315 const struct wined3d_state *state, DWORD state_id)
11316{
11318 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_GEOMETRY;
11319 else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
11320 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_DOMAIN;
11321 else if (state->shader[WINED3D_SHADER_TYPE_VERTEX]
11322 && state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.shader_version.major >= 4)
11323 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11324}
11325
11327 const struct wined3d_state *state, DWORD state_id)
11328{
11329 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW;
11330}
11331
11333 const struct wined3d_state *state, DWORD state_id)
11334{
11335 int i = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
11336 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i);
11337}
11338
11339static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
11340{
11341 const struct wined3d_gl_info *gl_info = context->gl_info;
11342 unsigned int k;
11343
11344 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
11347
11348 if (needs_legacy_glsl_syntax(gl_info))
11349 {
11350 for (k = 0; k < gl_info->limits.user_clip_distances; ++k)
11351 {
11354 }
11355 }
11356 else
11357 {
11358 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES;
11359 }
11360}
11361
11363 const struct wined3d_state *state, DWORD state_id)
11364{
11365 /* Table fog behavior depends on the projection matrix. */
11366 if (state->render_states[WINED3D_RS_FOGENABLE]
11367 && state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
11368 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11369 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PROJ;
11370}
11371
11373 const struct wined3d_state *state, DWORD state_id)
11374{
11378 && state->render_states[WINED3D_RS_POINTSCALEENABLE])
11379 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE;
11380 context->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP;
11381}
11382
11384 const struct wined3d_state *state, DWORD state_id)
11385{
11386 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX;
11387}
11388
11390 const struct wined3d_state *state, DWORD state_id)
11391{
11392 DWORD sampler = state_id - STATE_SAMPLER(0);
11393 const struct wined3d_texture *texture = state->textures[sampler];
11394 BOOL np2;
11395
11396 if (!texture)
11397 return;
11398
11399 if (sampler >= MAX_TEXTURES)
11400 return;
11401
11402 if ((np2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
11403 || context->lastWasPow2Texture & (1u << sampler))
11404 {
11405 if (np2)
11406 context->lastWasPow2Texture |= 1u << sampler;
11407 else
11408 context->lastWasPow2Texture &= ~(1u << sampler);
11409
11410 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX;
11411 }
11412}
11413
11415 const struct wined3d_state *state, DWORD state_id)
11416{
11417 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MATERIAL;
11418}
11419
11421 const struct wined3d_state *state, DWORD state_id)
11422{
11423 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_LIGHTS;
11424}
11425
11427 const struct wined3d_state *state, DWORD state_id)
11428{
11429 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE;
11430}
11431
11433 const struct wined3d_state *state, DWORD state_id)
11434{
11435 if (!use_vs(state))
11436 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POINTSIZE;
11437}
11438
11440 const struct wined3d_state *state, DWORD state_id)
11441{
11442 static unsigned int once;
11443
11444 if (state->gl_primitive_type == GL_POINTS && !state->render_states[WINED3D_RS_POINTSPRITEENABLE] && !once++)
11445 FIXME("Non-point sprite points not supported in core profile.\n");
11446}
11447
11449 const struct wined3d_state *state, DWORD state_id)
11450{
11451 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
11452}
11453
11455 const struct wined3d_state *state, DWORD state_id)
11456{
11457 const struct wined3d_gl_info *gl_info = context->gl_info;
11458 UINT index = state_id - STATE_CLIPPLANE(0);
11459
11460 if (index >= gl_info->limits.user_clip_distances)
11461 return;
11462
11463 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES;
11464}
11465
11467{
11475 /* Clip planes */
11492 /* Lights */
11502 /* Viewport */
11504 /* Transform states */
11540 /* Fog */
11569 /* NP2 texture matrix fixups. They are not needed if
11570 * GL_ARB_texture_non_power_of_two is supported. Otherwise, register
11571 * glsl_vertex_pipe_texmatrix(), which takes care of updating the texture
11572 * matrix. */
11600 {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE },
11601};
11602
11603/* TODO:
11604 * - Implement vertex tweening. */
11606{
11613};
11614
11615static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
11616{
11617 /* Nothing to do. */
11618}
11619
11620static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
11621{
11654}
11655
11657{
11660 return 0;
11661}
11662
11663static void *glsl_fragment_pipe_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
11664{
11665 struct shader_glsl_priv *priv;
11666
11667 if (shader_backend == &glsl_shader_backend)
11668 {
11669 priv = shader_priv;
11671 return priv;
11672 }
11673
11674 FIXME("GLSL fragment pipe without GLSL shader backend not implemented.\n");
11675
11676 return NULL;
11677}
11678
11680{
11682 struct glsl_ffp_fragment_shader, entry.entry);
11683 struct glsl_shader_prog_link *program, *program2;
11685
11686 LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs,
11687 struct glsl_shader_prog_link, ps.shader_entry)
11688 {
11689 delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
11690 }
11691 ctx->gl_info->gl_ops.ext.p_glDeleteShader(shader->id);
11693}
11694
11695/* Context activation is done by the caller. */
11697{
11698 struct shader_glsl_priv *priv = device->fragment_priv;
11700
11701 ctx.priv = priv;
11702 ctx.gl_info = &device->adapter->gl_info;
11704}
11705
11707 const struct wined3d_state *state, DWORD state_id)
11708{
11709 context->last_was_pshader = use_ps(state);
11710
11711 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11712}
11713
11715 const struct wined3d_state *state, DWORD state_id)
11716{
11717 context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG;
11718}
11719
11721 const struct wined3d_state *state, DWORD state_id)
11722{
11723 BOOL use_vshader = use_vs(state);
11724 enum fogsource new_source;
11725 DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
11726 DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
11727
11728 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11729
11730 if (!state->render_states[WINED3D_RS_FOGENABLE])
11731 return;
11732
11733 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
11734 {
11735 if (use_vshader)
11736 new_source = FOGSOURCE_VS;
11737 else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->stream_info.position_transformed)
11738 new_source = FOGSOURCE_COORD;
11739 else
11740 new_source = FOGSOURCE_FFP;
11741 }
11742 else
11743 {
11744 new_source = FOGSOURCE_FFP;
11745 }
11746
11747 if (new_source != context->fog_source || fogstart == fogend)
11748 {
11749 context->fog_source = new_source;
11750 context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG;
11751 }
11752}
11753
11755 const struct wined3d_state *state, DWORD state_id)
11756{
11757 /* Because of settings->texcoords_initialized and args->texcoords_initialized. */
11758 if (context->gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(context->gl_info))
11759 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11760
11763}
11764
11766 const struct wined3d_state *state, DWORD state_id)
11767{
11768 /* Because of settings->texcoords_initialized and args->texcoords_initialized. */
11769 if (context->gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(context->gl_info))
11770 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11771}
11772
11774 const struct wined3d_state *state, DWORD state_id)
11775{
11776 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11777}
11778
11780 const struct wined3d_state *state, DWORD state_id)
11781{
11782 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PS;
11783}
11784
11786 const struct wined3d_state *state, DWORD state_id)
11787{
11788 const struct wined3d_gl_info *gl_info = context->gl_info;
11790 float ref = state->render_states[WINED3D_RS_ALPHAREF] / 255.0f;
11791
11792 if (func)
11793 {
11794 gl_info->gl_ops.gl.p_glAlphaFunc(func, ref);
11795 checkGLcall("glAlphaFunc");
11796 }
11797}
11798
11800 const struct wined3d_state *state, DWORD state_id)
11801{
11802 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11803}
11804
11806 const struct wined3d_state *state, DWORD state_id)
11807{
11808 const struct wined3d_gl_info *gl_info = context->gl_info;
11809
11810 if (state->render_states[WINED3D_RS_ALPHATESTENABLE])
11811 {
11812 gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
11813 checkGLcall("glEnable(GL_ALPHA_TEST)");
11814 }
11815 else
11816 {
11817 gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
11818 checkGLcall("glDisable(GL_ALPHA_TEST)");
11819 }
11820}
11821
11823 const struct wined3d_state *state, DWORD state_id)
11824{
11825 context->constant_update_mask |= WINED3D_SHADER_CONST_PS_ALPHA_TEST;
11826}
11827
11829 const struct wined3d_state *state, DWORD state_id)
11830{
11831 context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_COLOR_KEY;
11832}
11833
11835 const struct wined3d_state *state, DWORD state_id)
11836{
11837 context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
11838}
11839
11841{
11957 {0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE },
11958};
11959
11961{
11962 return TRUE;
11963}
11964
11966{
11967}
11968
11970{
11980};
#define compare
UCHAR src_mask[]
Definition: GetObject.c:14
struct mke2fs_defaults settings[]
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
static struct myctx * mcs
Definition: adnstest.c:53
reg_name
Definition: amd64_sup.c:11
static int state
Definition: maze.c:121
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:33
#define U(x)
Definition: wordpad.c:45
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:37
struct list * next
Definition: list.h:38
Definition: _map.h:48
Definition: _set.h:50
Definition: _stack.h:55
unsigned int component_count
#define PRINTF_ATTR(fmt, args)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
void context_enable_clip_distances(struct wined3d_context *context, unsigned int enable_mask)
Definition: context.c:2414
const DWORD * context_get_tex_unit_mapping(const struct wined3d_context *context, const struct wined3d_shader_version *shader_version, unsigned int *base, unsigned int *count)
Definition: context.c:2334
struct wined3d_context * context_acquire(const struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: context.c:4242
void context_release(struct wined3d_context *context)
Definition: context.c:1571
void string_buffer_list_cleanup(struct wined3d_string_buffer_list *list)
Definition: shader.c:555
void string_buffer_clear(struct wined3d_string_buffer *buffer)
Definition: shader.c:422
BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage)
Definition: shader.c:377
void find_ds_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, struct ds_compile_args *args, const struct wined3d_context *context)
Definition: shader.c:3748
void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, WORD swizzle_map, struct vs_compile_args *args, const struct wined3d_context *context)
Definition: shader.c:3463
const float wined3d_srgb_const0[]
Definition: shader.c:36
struct wined3d_string_buffer * string_buffer_get(struct wined3d_string_buffer_list *list)
Definition: shader.c:495
void find_gs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, struct gs_compile_args *args, const struct wined3d_context *context)
Definition: shader.c:3771
void find_ps_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader, BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context)
Definition: shader.c:3782
void string_buffer_free(struct wined3d_string_buffer *buffer)
Definition: shader.c:441
void string_buffer_sprintf(struct wined3d_string_buffer *buffer, const char *format,...)
Definition: shader.c:526
BOOL string_buffer_init(struct wined3d_string_buffer *buffer)
Definition: shader.c:428
int shader_addline(struct wined3d_string_buffer *buffer, const char *format,...)
Definition: shader.c:478
void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types)
Definition: shader.c:4073
int shader_vaddline(struct wined3d_string_buffer *buffer, const char *format, va_list args)
Definition: shader.c:464
BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc)
Definition: shader.c:446
const char * debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx)
Definition: shader.c:334
void string_buffer_release(struct wined3d_string_buffer_list *list, struct wined3d_string_buffer *buffer)
Definition: shader.c:543
void string_buffer_list_init(struct wined3d_string_buffer_list *list)
Definition: shader.c:550
const float wined3d_srgb_const1[]
Definition: shader.c:38
HRESULT shader_generate_code(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps, void *backend_ctx, const DWORD *start, const DWORD *end)
Definition: shader.c:2558
void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:1661
void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:4988
void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:709
void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:1648
void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:3836
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f)
Definition: state.c:348
void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:293
void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int index, struct wined3d_matrix *mat)
Definition: utils.c:4899
const struct ffp_frag_desc * find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders, const struct ffp_frag_settings *settings)
Definition: utils.c:6076
void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state, float *start, float *end)
Definition: utils.c:5179
BOOL invert_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
Definition: utils.c:5501
const char * debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
Definition: utils.c:4346
void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m)
Definition: utils.c:5705
void wined3d_ftoa(float value, char *s)
Definition: utils.c:6429
int wined3d_ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
Definition: utils.c:6230
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state, float *out_min, float *out_max)
Definition: utils.c:5128
void get_pointsize(const struct wined3d_context *context, const struct wined3d_state *state, float *out_pointsize, float *out_att)
Definition: utils.c:5147
unsigned int wined3d_max_compat_varyings(const struct wined3d_gl_info *gl_info)
Definition: utils.c:5744
unsigned int idx
Definition: utils.c:41
BOOL invert_matrix_3d(struct wined3d_matrix *out, const struct wined3d_matrix *in)
Definition: utils.c:5431
void wined3d_format_get_float_color_key(const struct wined3d_format *format, const struct wined3d_color_key *key, struct wined3d_color *float_colors)
Definition: utils.c:5321
void wined3d_gl_limits_get_uniform_block_range(const struct wined3d_gl_limits *gl_limits, enum wined3d_shader_type shader_type, unsigned int *base, unsigned int *count)
Definition: utils.c:6480
void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
Definition: utils.c:6083
void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state, struct ffp_frag_settings *settings, BOOL ignore_textype)
Definition: utils.c:5751
void get_texture_matrix(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int tex, struct wined3d_matrix *mat)
Definition: utils.c:5096
void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_ffp_vs_settings *settings)
Definition: utils.c:6238
void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_matrix *mat)
Definition: utils.c:4908
int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
Definition: utils.c:6387
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define TRACE_(x)
Definition: compat.h:76
#define TRACE_ON(x)
Definition: compat.h:75
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
static const WCHAR version[]
Definition: asmname.c:66
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxCollectionEntry * cur
#define FLT_MAX
Definition: gcc_float.h:107
GLuint start
Definition: gl.h:1545
float GLfloat
Definition: gl.h:161
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define GL_ALPHA_TEST
Definition: gl.h:366
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
unsigned int GLenum
Definition: gl.h:150
unsigned int GLuint
Definition: gl.h:159
#define GL_POINTS
Definition: gl.h:190
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define GL_FALSE
Definition: gl.h:173
int GLint
Definition: gl.h:156
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLenum GLuint texture
Definition: glext.h:6295
GLsizei stride
Definition: glext.h:5848
GLsizei const GLchar *const * varyings
Definition: glext.h:6214
#define GL_CLAMP_VERTEX_COLOR_ARB
Definition: glext.h:1622
#define GL_FRAGMENT_SHADER
Definition: glext.h:419
#define GL_GEOMETRY_SHADER
Definition: glext.h:820
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLuint address
Definition: glext.h:9393
GLenum src
Definition: glext.h:6340
GLsizei const GLint * locations
Definition: glext.h:10542
GLuint GLenum swizzle
Definition: glext.h:9511
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLuint buffer
Definition: glext.h:5915
#define GL_PROGRAM_POINT_SIZE
Definition: glext.h:816
GLfloat bias
Definition: glext.h:7909
GLuint color
Definition: glext.h:6243
GLenum condition
Definition: glext.h:9255
#define GL_INTERLEAVED_ATTRIBS
Definition: glext.h:555
#define GL_FIXED_ONLY_ARB
Definition: glext.h:1625
#define GL_TESS_CONTROL_SHADER
Definition: glext.h:2126
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint sampler
Definition: glext.h:7283
GLuint shader
Definition: glext.h:6030
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLint lod
Definition: glext.h:7795
GLuint program
Definition: glext.h:6723
const GLuint * shaders
Definition: glext.h:7538
GLuint GLenum matrix
Definition: glext.h:9407
#define GL_SHADER_SOURCE_LENGTH
Definition: glext.h:454
GLenum mode
Definition: glext.h:6217
GLenum GLenum dst
Definition: glext.h:6340
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
#define GL_COMPILE_STATUS
Definition: glext.h:447
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define GL_TESS_EVALUATION_SHADER
Definition: glext.h:2125
#define GL_SHADER_TYPE
Definition: glext.h:426
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean enable
Definition: glext.h:11120
GLfloat param
Definition: glext.h:5796
#define GL_VERTEX_SHADER
Definition: glext.h:420
GLenum GLenum GLenum input
Definition: glext.h:9031
#define GL_SEPARATE_ATTRIBS
Definition: glext.h:556
#define GL_LINK_STATUS
Definition: glext.h:448
#define GL_INFO_LOG_LENGTH
Definition: glext.h:450
#define GL_ATTACHED_SHADERS
Definition: glext.h:451
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint GLenum GLenum GLenum GLint GLuint GLenum GLenum GLfloat GLenum GLfloat GLenum GLint const GLfloat GLenum GLint const GLushort GLint GLint GLsizei GLsizei GLenum GLsizei GLsizei GLenum GLenum const GLvoid GLenum plane
Definition: glfuncs.h:270
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum light
Definition: glfuncs.h:170
static void shader_glsl_gen_modifier(enum wined3d_shader_src_modifier src_modifier, const char *in_reg, const char *in_regswizzle, char *out_str)
Definition: glsl_shader.c:2483
static void shader_glsl_expp(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4147
static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void append_transform_feedback_skip_components(const char **varyings, unsigned int *varying_count, char **strings, unsigned int *strings_length, struct wined3d_string_buffer *buffer, unsigned int component_count)
Definition: glsl_shader.c:790
static const char * shader_glsl_interpolation_qualifiers(enum wined3d_shader_interpolation_mode mode)
Definition: glsl_shader.c:1872
static void shader_glsl_generate_conditional_op(const struct wined3d_shader_instruction *ins, const char *op)
Definition: glsl_shader.c:4865
static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc)
Definition: glsl_shader.c:6982
static void shader_glsl_load_constants_f(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, unsigned int version)
Definition: glsl_shader.c:1120
static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4806
#define WINED3D_GLSL_SAMPLE_LOAD
Definition: glsl_shader.c:50
static void shader_glsl_break(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4912
#define WINED3D_GLSL_SAMPLE_LOD
Definition: glsl_shader.c:48
static BOOL needs_legacy_glsl_syntax(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1801
static void shader_glsl_ffp_vertex_material_uniform(const struct wined3d_context *context, const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1256
static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4893
static void glsl_vertex_pipe_vs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5161
static DWORD shader_glsl_append_dst(struct wined3d_string_buffer *buffer, const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3171
static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6209
static void glsl_vertex_pipe_clip_plane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
const struct wined3d_shader_backend_ops glsl_shader_backend
static void shader_glsl_color_correction_ext(struct wined3d_string_buffer *buffer, const char *reg_name, DWORD mask, struct color_fixup_desc fixup)
Definition: glsl_shader.c:3387
static void shader_glsl_ld_uav(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5361
static void glsl_fragment_pipe_vs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_generate_alpha_test(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, enum wined3d_cmp_func alpha_func)
Definition: glsl_shader.c:7195
static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5115
static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5995
static void set_glsl_shader_program(const struct wined3d_context *context, const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
Definition: glsl_shader.c:9824
static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
static unsigned int shader_glsl_get_version(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:392
static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4623
static BOOL shader_glsl_has_ffp_proj_control(void *shader_priv)
static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5670
static void shader_glsl_ffp_fragment_op(struct wined3d_string_buffer *buffer, unsigned int stage, BOOL color, BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
Definition: glsl_shader.c:8912
static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5088
static void glsl_vertex_pipe_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void glsl_fragment_pipe_color_key(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4898
static void glsl_fragment_pipe_tex_transform(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
Definition: glsl_shader.c:1061
static BOOL is_multisampled(enum wined3d_shader_resource_type resource_type)
Definition: glsl_shader.c:5659
static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3886
static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3732
static void shader_glsl_invalidate_current_program(struct wined3d_context *context)
static void shader_glsl_pointsize_uniform(const struct wined3d_context *context, const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1357
static void shader_glsl_to_uint(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4193
static void shader_glsl_unary_op(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3687
static GLuint find_glsl_geometry_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct gs_compile_args *args)
Definition: glsl_shader.c:8319
#define WINED3D_GLSL_SAMPLE_PROJECTED
Definition: glsl_shader.c:47
static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_shader_prog_link *entry)
Definition: glsl_shader.c:6569
static const char * shader_glsl_get_rel_op(enum wined3d_shader_rel_op op)
Definition: glsl_shader.c:3207
unsigned int coord_size
Definition: glsl_shader.c:55
static void glsl_vertex_pipe_pointscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6153
static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6411
static void shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6126
static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, enum wined3d_ffp_ps_fog_mode mode)
Definition: glsl_shader.c:7163
static void shader_glsl_declare_typed_vertex_attribute(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, const char *vector_type, const char *scalar_type, unsigned int index)
Definition: glsl_shader.c:2026
static void glsl_vertex_pipe_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, unsigned int element_count, const DWORD *interpolation_mode, BOOL unroll)
Definition: glsl_shader.c:1895
static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5759
static void shader_glsl_to_float(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4198
static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_generate_shader_phase_invocation(struct wined3d_string_buffer *buffer, const struct wined3d_shader_phase *phase, const char *phase_name, unsigned int phase_idx)
Definition: glsl_shader.c:7737
static void shader_glsl_texkill(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6428
static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct fragment_pipeline *fragment_pipe)
static BOOL glsl_fragment_pipe_alloc_context_data(struct wined3d_context *context)
static HRESULT shader_glsl_generate_shader_phase(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps, struct shader_glsl_ctx_priv *priv_ctx, const struct wined3d_shader_phase *phase, const char *phase_name, unsigned phase_idx)
Definition: glsl_shader.c:7720
static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[]
static void apply_clamped_constant(const struct wined3d_gl_info *gl_info, GLint location, const struct wined3d_vec4 *data)
Definition: glsl_shader.c:1045
static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context, struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct vs_compile_args *args)
Definition: glsl_shader.c:7611
static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4083
void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLuint program)
Definition: glsl_shader.c:577
static void shader_glsl_swapc(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4254
static const char * shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, const char *material)
Definition: glsl_shader.c:8374
static DWORD glsl_vertex_pipe_vp_get_emul_mask(const struct wined3d_gl_info *gl_info)
static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *priv, const struct ffp_frag_settings *settings, const struct wined3d_context *context)
Definition: glsl_shader.c:9062
static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6186
static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
static void glsl_vertex_pipe_vp_free(struct wined3d_device *device)
static void glsl_fragment_pipe_free(struct wined3d_device *device)
static const char *const shift_glsl_tab[]
Definition: glsl_shader.c:2463
static void shader_glsl_mul_extended(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3709
static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL rasterizer_setup, const DWORD *interpolation_mode)
Definition: glsl_shader.c:1925
static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4975
static GLuint find_glsl_domain_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct ds_compile_args *args)
Definition: glsl_shader.c:8264
static void glsl_vertex_pipe_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static BOOL shader_glsl_use_explicit_attrib_location(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1806
static void shader_glsl_generate_patch_constant_name(struct wined3d_string_buffer *buffer, const struct wined3d_shader_signature_element *constant, unsigned int *user_constant_idx, const char *reg_mask)
Definition: glsl_shader.c:7077
static const char * shader_glsl_get_ffp_fragment_op_arg(struct wined3d_string_buffer *buffer, DWORD argnum, unsigned int stage, DWORD arg)
Definition: glsl_shader.c:8819
static void shader_glsl_sample(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5800
static BOOL shader_glsl_has_core_grad(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:3223
static BOOL shader_glsl_use_layout_qualifier(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:594
static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLuint shader, const char *src)
Definition: glsl_shader.c:505
static void shader_glsl_free(struct wined3d_device *device)
static void glsl_vertex_pipe_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_clip_plane_uniform(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int index, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1406
static const struct StateEntryTemplate glsl_fragment_pipe_state_template[]
static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_context *ctx)
Definition: glsl_shader.c:7993
static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4876
static void shader_glsl_init_gs_uniform_locations(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, struct glsl_gs_program *gs)
Definition: glsl_shader.c:9638
static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context, struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, const struct wined3d_shader *shader, const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info)
Definition: glsl_shader.c:7280
static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:7223
static BOOL glsl_is_shadow_sampler(const struct wined3d_shader *shader, const struct ps_compile_args *ps_args, unsigned int resource_idx, unsigned int sampler_idx)
Definition: glsl_shader.c:2015
static void glsl_fragment_pipe_fogparams(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_init_transform_feedback(const struct wined3d_context *context, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
Definition: glsl_shader.c:888
static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer, const struct wined3d_ffp_vs_settings *settings, BOOL legacy_lighting)
Definition: glsl_shader.c:8403
static const char * shader_glsl_get_prefix(enum wined3d_shader_type type)
Definition: glsl_shader.c:364
static void shader_glsl_setup_vs3_output(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info, const DWORD *map, const struct wined3d_shader_signature *input_signature, const struct wined3d_shader_reg_maps *reg_maps_in, const struct wined3d_shader_signature *output_signature, const struct wined3d_shader_reg_maps *reg_maps_out)
Definition: glsl_shader.c:6617
static void shader_glsl_lrp(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4518
static void shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6455
static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer)
Definition: glsl_shader.c:3565
static const char * glsl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
Definition: glsl_shader.c:1960
static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_relop(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3625
static int glsl_program_key_compare(const void *key, const struct wine_rb_entry *entry)
static void shader_glsl_generate_srgb_write_correction(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:7150
static void shader_glsl_generate_patch_constant_setup(struct wined3d_string_buffer *buffer, const struct wined3d_shader_signature *signature, BOOL input_setup)
Definition: glsl_shader.c:7105
static void shader_glsl_append_sampler_binding_qualifier(struct wined3d_string_buffer *buffer, const struct wined3d_context *context, const struct wined3d_shader_version *shader_version, unsigned int sampler_idx)
Definition: glsl_shader.c:678
static void shader_glsl_invalidate_contexts_program(struct wined3d_device *device, const struct glsl_shader_prog_link *program)
static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3776
static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4966
static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4413
static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, const GLint locations[WINED3D_MAX_CONSTS_B], const BOOL *constants, WORD constants_set)
Definition: glsl_shader.c:1178
static void shader_glsl_load_samplers_range(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, const char *prefix, unsigned int base, unsigned int count, const DWORD *tex_unit_map)
Definition: glsl_shader.c:635
static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3828
static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count)
Definition: glsl_shader.c:9644
static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1790
static void shader_glsl_declare_generic_vertex_attribute(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, const struct wined3d_shader_signature_element *e)
Definition: glsl_shader.c:2036
static void shader_glsl_conditional_move(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4306
static void shader_glsl_append_fixup_arg(char *arguments, const char *reg_name, BOOL sign_fixup, enum fixup_channel_source channel_source)
Definition: glsl_shader.c:3345
static void shader_glsl_switch(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4844
static GLuint find_glsl_compute_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, struct wined3d_shader *shader)
Definition: glsl_shader.c:9778
static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4711
static void glsl_fragment_pipe_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_generate_glsl_declarations(const struct wined3d_context *context, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv)
Definition: glsl_shader.c:2079
static void shader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6084
static void shader_glsl_load_images(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
Definition: glsl_shader.c:729
#define WINED3D_GLSL_SAMPLE_GRAD
Definition: glsl_shader.c:49
static void shader_glsl_add_version_declaration(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:404
static void glsl_vertex_pipe_viewport(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void glsl_vertex_pipe_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3913
static void shader_glsl_generate_clip_or_cull_distances(struct wined3d_string_buffer *buffer, const struct wined3d_shader_signature_element *element, DWORD clip_or_cull_distance_mask)
Definition: glsl_shader.c:6751
#define WINED3D_GLSL_SAMPLE_OFFSET
Definition: glsl_shader.c:51
static BOOL shader_glsl_allocate_context_data(struct wined3d_context *context)
static void update_heap_entry(struct constant_heap *heap, unsigned int idx, DWORD new_version)
Definition: glsl_shader.c:1734
static void shader_glsl_init_context_state(struct wined3d_context *context)
static const struct @274 resource_type_info[]
static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6379
static const char * get_attribute_keyword(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1817
static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src)
Definition: glsl_shader.c:3111
static BOOL shader_glsl_use_layout_binding_qualifier(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:602
static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup)
static void shader_glsl_generate_sm4_output_setup(struct shader_glsl_priv *priv, const struct wined3d_shader *shader, unsigned int input_count, const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup, const DWORD *interpolation_mode)
Definition: glsl_shader.c:7051
static void shader_glsl_cut(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3873
static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *wined3d_dst, struct glsl_dst_param *glsl_dst)
Definition: glsl_shader.c:3120
static void shader_glsl_append_imm_vec4(struct wined3d_string_buffer *buffer, const float *values)
Definition: glsl_shader.c:410
static void shader_glsl_disable(void *shader_priv, struct wined3d_context *context)
static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6395
unsigned int resinfo_size
Definition: glsl_shader.c:56
static unsigned int shader_glsl_get_shader_model(const struct wined3d_gl_info *gl_info)
static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5881
static void shader_glsl_gather4(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5926
static void shader_glsl_conditional_op(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4930
static void shader_glsl_cross(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3859
static void glsl_vertex_pipe_texmatrix_np2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_generate_default_control_point_phase(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps)
Definition: glsl_shader.c:7703
static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct ds_compile_args *args)
Definition: glsl_shader.c:7838
static void glsl_vertex_pipe_hs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_select_compute(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state)
static void shader_glsl_uav_counter(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5347
static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct ds_compile_args *args)
Definition: glsl_shader.c:7848
static void multiply_vector_matrix(struct wined3d_vec4 *dest, const struct wined3d_vec4 *src1, const struct wined3d_matrix *src2)
Definition: glsl_shader.c:1289
static unsigned int shader_glsl_swizzle_get_component(DWORD swizzle, unsigned int component_idx)
Definition: glsl_shader.c:2989
static void glsl_fragment_pipe_fog(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_color_correction(const struct wined3d_shader_instruction *ins, struct color_fixup_desc fixup)
Definition: glsl_shader.c:3441
static void reset_program_constant_version(struct wine_rb_entry *entry, void *context)
Definition: glsl_shader.c:1205
static void shader_glsl_load_fog_uniform(const struct wined3d_context *context, const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1383
static void glsl_vertex_pipe_material(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
Definition: glsl_shader.c:1427
static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3999
static void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3177
static const char * get_info_log_line(const char **ptr)
Definition: glsl_shader.c:442
static BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new, const DWORD use_map)
Definition: glsl_shader.c:8137
static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4055
static void shader_glsl_cast(const struct wined3d_shader_instruction *ins, const char *vector_constructor, const char *scalar_constructor)
Definition: glsl_shader.c:4170
static void shader_glsl_handle_instruction(const struct wined3d_shader_instruction *ins)
static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask)
Definition: glsl_shader.c:2977
static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info, const DWORD *map, const struct wined3d_shader_signature *input_signature, const struct wined3d_shader_reg_maps *reg_maps_in, unsigned int input_count, const struct wined3d_shader_signature *output_signature, const struct wined3d_shader_reg_maps *reg_maps_out, BOOL per_vertex_point_size)
Definition: glsl_shader.c:6773
static DWORD glsl_fragment_pipe_get_emul_mask(const struct wined3d_gl_info *gl_info)
static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4788
static void shader_glsl_ffp_vertex_lightambient_uniform(const struct wined3d_context *context, const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1278
static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
static void shader_glsl_case(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4852
static BOOL is_mipmapped(enum wined3d_shader_resource_type resource_type)
Definition: glsl_shader.c:5665
static void shader_glsl_fixup_scalar_register_variable(char *register_name, const char *glsl_variable, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:2532
static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned int idx)
Definition: glsl_shader.c:1991
static void shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc, struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count, char *strings, unsigned int *strings_length, GLenum buffer_mode)
Definition: glsl_shader.c:808
static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6040
static GLuint find_glsl_vshader(const struct wined3d_context *context, struct shader_glsl_priv *priv, struct wined3d_shader *shader, const struct vs_compile_args *args)
Definition: glsl_shader.c:8155
static void shader_glsl_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
Definition: glsl_shader.c:1766
static void shader_glsl_ld_raw_structured(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5395
static struct glsl_shader_prog_link * get_glsl_program_entry(const struct shader_glsl_priv *priv, const struct glsl_program_key *key)
Definition: glsl_shader.c:6586
static void shader_glsl_load_constants_i(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info, const struct wined3d_ivec4 *constants, const GLint locations[WINED3D_MAX_CONSTS_I], WORD constants_set)
Definition: glsl_shader.c:1148
static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4961
static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context)
static void set_glsl_compute_shader_program(const struct wined3d_context *context, const struct wined3d_state *state, struct shader_glsl_priv *priv, struct glsl_context_data *ctx_data)
Definition: glsl_shader.c:9797
static void shader_glsl_binop(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3591
const struct fragment_pipeline glsl_fragment_pipe
static void shader_glsl_load_program_resources(const struct wined3d_context *context, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader *shader)
Definition: glsl_shader.c:759
static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
Definition: glsl_shader.c:607
static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4952
static void shader_glsl_setup_sm4_shader_output(struct shader_glsl_priv *priv, unsigned int input_count, const struct wined3d_shader_signature *output_signature, const struct wined3d_shader_reg_maps *reg_maps_out, const char *output_variable_name, BOOL rasterizer_setup)
Definition: glsl_shader.c:6721
static GLuint find_glsl_pshader(const struct wined3d_context *context, struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, struct wined3d_shader *shader, const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
Definition: glsl_shader.c:8062
static void shader_glsl_write_mask_to_str(DWORD write_mask, char *str)
Definition: glsl_shader.c:2949
static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct vs_compile_args *args)
Definition: glsl_shader.c:7567
static const struct wined3d_shader_resource_info * shader_glsl_get_resource_info(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_register *reg)
Definition: glsl_shader.c:5595
static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, const struct wined3d_shader_signature *input_signature, const struct wined3d_shader_reg_maps *reg_maps, const struct ps_compile_args *args, const struct wined3d_gl_info *gl_info, BOOL unroll)
Definition: glsl_shader.c:6479
static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6297
static void shader_glsl_load_icb(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
Definition: glsl_shader.c:708
static void shader_glsl_get_coord_size(enum wined3d_shader_resource_type resource_type, unsigned int *coord_size, unsigned int *deriv_size)
Definition: glsl_shader.c:3228
static GLuint find_glsl_hull_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, struct wined3d_shader *shader)
Definition: glsl_shader.c:8219
static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg, enum wined3d_data_type data_type, char *register_name, BOOL *is_color, const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:2545
static void * glsl_fragment_pipe_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
static void shader_glsl_init_ds_uniform_locations(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ds_program *ds)
Definition: glsl_shader.c:9632
static const char * shader_glsl_shader_output_name(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1867
static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4204
static void glsl_fragment_pipe_core_alpha_test_ref(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6364
static void glsl_fragment_pipe_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, DWORD resource_idx, DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function)
Definition: glsl_shader.c:3240
static void shader_glsl_sync(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5574
static void shader_glsl_precompile(void *shader_priv, struct wined3d_shader *shader)
static enum wined3d_shader_interpolation_mode wined3d_extract_interpolation_mode(const DWORD *packed_interpolation_mode, unsigned int register_idx)
Definition: glsl_shader.c:1888
static void glsl_fragment_pipe_alpha_test_func(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info, struct glsl_shader_prog_link *entry)
Definition: glsl_shader.c:6596
static void shader_glsl_ffp_vertex_lighting_footer(struct wined3d_string_buffer *buffer, const struct wined3d_ffp_vs_settings *settings, unsigned int idx)
Definition: glsl_shader.c:8390
static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLuint program)
Definition: glsl_shader.c:525
static void glsl_vertex_pointsprite_core(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
#define WINED3D_TO_STR(u)
static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6228
static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info, struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
Definition: glsl_shader.c:9545
static void shader_glsl_mad(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4441
static const char * debug_gl_shader_type(GLenum type)
Definition: glsl_shader.c:347
static struct glsl_ffp_fragment_shader * shader_glsl_find_ffp_fragment_shader(struct shader_glsl_priv *priv, const struct ffp_frag_settings *args, const struct wined3d_context *context)
Definition: glsl_shader.c:9524
static void glsl_vertex_pipe_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps, const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
Definition: glsl_shader.c:1211
static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE]
static void glsl_vertex_pipe_pointsize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_swizzle_to_str(DWORD swizzle, BOOL fixup, DWORD mask, char *str)
Definition: glsl_shader.c:2996
static void shader_glsl_load_samplers(const struct wined3d_context *context, struct shader_glsl_priv *priv, GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
Definition: glsl_shader.c:690
static void shader_glsl_ffp_vertex_light_uniform(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int light, const struct wined3d_light_info *light_info, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1302
static unsigned int shader_glsl_find_sampler(const struct wined3d_shader_sampler_map *sampler_map, unsigned int resource_idx, unsigned int sampler_idx)
Definition: glsl_shader.c:5144
static BOOL shader_glsl_use_interface_blocks(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1812
static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4694
static unsigned int shader_glsl_map_tex_unit(const struct wined3d_context *context, const struct wined3d_shader_version *shader_version, unsigned int sampler_idx)
Definition: glsl_shader.c:664
static GLuint shader_glsl_generate_hull_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, const struct wined3d_shader *shader)
Definition: glsl_shader.c:7752
static void shader_glsl_default(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4860
static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog)
Definition: glsl_shader.c:1240
static void shader_glsl_gen_sample_c_lz(const struct wined3d_shader_instruction *ins, unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, unsigned int coord_size, const char *coord_param, const char *ref_param)
Definition: glsl_shader.c:5854
static void shader_glsl_store_raw_structured(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5514
static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state)
Definition: glsl_shader.c:1455
static void shader_glsl_free_context_data(struct wined3d_context *context)
static void glsl_fragment_pipe_free_context_data(struct wined3d_context *context)
static struct glsl_ffp_vertex_shader * shader_glsl_find_ffp_vertex_shader(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info, const struct wined3d_ffp_vs_settings *settings)
Definition: glsl_shader.c:9503
static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4986
static void shader_glsl_nop(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4053
static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer, const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst, enum wined3d_data_type data_type)
Definition: glsl_shader.c:3134
const struct wined3d_vertex_pipe_ops glsl_vertex_pipe
static void shader_glsl_release_sample_function(const struct wined3d_shader_context *ctx, struct glsl_sample_function *sample_function)
Definition: glsl_shader.c:3337
static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param, enum wined3d_data_type dst_data_type, enum wined3d_data_type src_data_type)
Definition: glsl_shader.c:3022
static void glsl_vertex_pipe_light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
heap_node_op
Definition: glsl_shader.c:98
@ HEAP_NODE_POP
Definition: glsl_shader.c:101
@ HEAP_NODE_TRAVERSE_RIGHT
Definition: glsl_shader.c:100
@ HEAP_NODE_TRAVERSE_LEFT
Definition: glsl_shader.c:99
static HRESULT shader_glsl_compile_compute_shader(struct shader_glsl_priv *priv, const struct wined3d_context *context, struct wined3d_shader *shader)
Definition: glsl_shader.c:9698
static void glsl_fragment_pipe_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static const char * shader_glsl_shader_input_name(const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:1862
static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *param, char *write_mask)
Definition: glsl_shader.c:2960
static void shader_glsl_dst(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4594
static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6166
static void shader_glsl_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
Definition: glsl_shader.c:1778
static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void get_normal_matrix(struct wined3d_context *context, struct wined3d_matrix *mat, float *normal)
Definition: glsl_shader.c:1438
static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4881
static void shader_glsl_lit(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4541
static void shader_glsl_store_uav(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5482
static void constant_heap_free(struct constant_heap *heap)
static void shader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6105
static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param, BOOL fixup, DWORD mask, char *swizzle_str)
Definition: glsl_shader.c:3013
static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context *context, struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct gs_compile_args *args)
Definition: glsl_shader.c:7942
static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *priv, const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:8527
static void shader_glsl_breakc(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4918
static void walk_constant_heap(const struct wined3d_gl_info *gl_info, const struct wined3d_vec4 *constants, const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
Definition: glsl_shader.c:971
static void shader_glsl_bufinfo(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:5625
static void * glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
static void shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6140
static void shader_glsl_destroy(struct wined3d_shader *shader)
static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
const char * type_part
Definition: glsl_shader.c:57
static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info, struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader, const struct ps_compile_args *args)
Definition: glsl_shader.c:7258
static void glsl_fragment_pipe_core_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void glsl_vertex_pipe_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static void shader_glsl_select(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state)
static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context *context, struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers, const struct wined3d_shader *shader)
Definition: glsl_shader.c:8021
static void shader_glsl_float16(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:3975
static void shader_glsl_to_int(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4188
void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLuint id, BOOL program)
Definition: glsl_shader.c:459
static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:6261
static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, void *context)
static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4458
static void shader_glsl_append_imm_ivec(struct wined3d_string_buffer *buffer, const int *values, unsigned int size)
Definition: glsl_shader.c:421
static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instruction *ins, const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src, enum wined3d_data_type data_type)
Definition: glsl_shader.c:3067
static void shader_glsl_continue(const struct wined3d_shader_instruction *ins)
Definition: glsl_shader.c:4947
static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl_priv *priv, const struct wined3d_shader *vs, const struct wined3d_shader *ps, BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info)
Definition: glsl_shader.c:6839
static void append_transform_feedback_varying(const char **varyings, unsigned int *varying_count, char **strings, unsigned int *strings_length, struct wined3d_string_buffer *buffer)
Definition: glsl_shader.c:771
static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
static int is_array(const type_t *t)
Definition: header.h:64
#define ds
Definition: i386-dis.c:443
static int reg
Definition: i386-dis.c:1290
#define cs
Definition: i386-dis.c:442
#define gs
Definition: i386-dis.c:445
#define UINT_MAX
Definition: limits.h:41
_Check_return_ float __cdecl cosf(_In_ float x)
Definition: math.h:224
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
char * prog
Definition: isohybrid.c:47
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define resource
Definition: kernel32.h:9
#define location(file, line)
Definition: kmtest.h:18
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WARN_ON(c)
Definition: module.h:257
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR desc[]
Definition: protectdata.c:36
float specular[3]
Definition: d3drm.c:3373
float emissive[3]
Definition: d3drm.c:3374
const char * var
Definition: shader.c:5666
UINT constant_count
Definition: shader.c:5673
static const MAT2 mat
Definition: font.c:66
constants
Definition: resource.c:29
static char * dest
Definition: rtl.c:135
static vector_t * vs
Definition: server.c:127
static float(__cdecl *square_half_float)(float x
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
unsigned int UINT
Definition: ndis.h:50
@ normal
Definition: optimize.h:166
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define ERR_(ch,...)
Definition: debug.h:156
#define FIXME_ON(ch)
Definition: debug.h:407
static void * heap_calloc(SIZE_T count, SIZE_T size)
Definition: heap.h:49
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:115
static void wine_rb_destroy(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
Definition: rbtree.h:198
static void wine_rb_for_each_entry(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
Definition: rbtree.h:185
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
static struct wine_rb_entry * wine_rb_get(const struct wine_rb_tree *tree, const void *key)
Definition: rbtree.h:203
static void wine_rb_remove(struct wine_rb_tree *tree, struct wine_rb_entry *entry)
Definition: rbtree.h:283
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
static int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
Definition: rbtree.h:215
static HANDLE heap
Definition: heap.c:65
#define memset(x, y, z)
Definition: compat.h:39
static char * tmp_name
Definition: cache.c:24
#define log(outFile, fmt,...)
Definition: util.h:15
#define args
Definition: format.c:66
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: match.c:390
unsigned short x_source
unsigned short y_sign_fixup
unsigned short w_source
unsigned short x_sign_fixup
unsigned short z_sign_fixup
unsigned short y_source
unsigned short w_sign_fixup
unsigned short z_source
Definition: bug.cpp:8
Definition: glsl_shader.c:105
unsigned int version
Definition: glsl_shader.c:107
unsigned int idx
Definition: glsl_shader.c:106
BOOL * contained
Definition: glsl_shader.c:113
struct constant_entry * entries
Definition: glsl_shader.c:112
unsigned int size
Definition: glsl_shader.c:115
unsigned int * positions
Definition: glsl_shader.c:114
union constant::@236 value[4]
Definition: http.c:7252
Definition: tftpd.h:138
Definition: devices.h:37
Definition: dsound.c:943
DWORD MaxSimultaneousTextures
DWORD MaxTextureBlendStages
struct glsl_shader_prog_link * glsl_program
Definition: glsl_shader.c:271
GLenum vertex_color_clamp
Definition: glsl_shader.c:272
BOOL rasterization_disabled
Definition: glsl_shader.c:273
struct list shader_entry
Definition: glsl_shader.c:229
struct list shader_entry
Definition: glsl_shader.c:189
GLint pos_fixup_location
Definition: glsl_shader.c:192
char reg_name[150]
Definition: glsl_shader.c:76
char mask_str[6]
Definition: glsl_shader.c:77
struct shader_glsl_priv * priv
Definition: glsl_shader.c:341
const struct wined3d_gl_info * gl_info
Definition: glsl_shader.c:342
struct ffp_frag_desc entry
Definition: glsl_shader.c:334
struct list linked_programs
Definition: glsl_shader.c:336
struct wined3d_ffp_vs_desc desc
Definition: glsl_shader.c:327
struct list linked_programs
Definition: glsl_shader.c:329
struct list shader_entry
Definition: glsl_shader.c:197
GLint pos_fixup_location
Definition: glsl_shader.c:200
struct list shader_entry
Definition: glsl_shader.c:183
struct ps_compile_args args
Definition: glsl_shader.c:278
struct ps_np2fixup_info np2fixup
Definition: glsl_shader.c:279
GLint color_key_location
Definition: glsl_shader.c:223
GLint bumpenv_lum_scale_location[MAX_TEXTURES]
Definition: glsl_shader.c:211
GLint fog_density_location
Definition: glsl_shader.c:217
struct list shader_entry
Definition: glsl_shader.c:205
GLint tex_factor_location
Definition: glsl_shader.c:214
GLint alpha_test_ref_location
Definition: glsl_shader.c:220
GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]
Definition: glsl_shader.c:209
GLint tss_constant_location[MAX_TEXTURES]
Definition: glsl_shader.c:213
GLint fog_color_location
Definition: glsl_shader.c:216
GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]
Definition: glsl_shader.c:208
GLint fog_end_location
Definition: glsl_shader.c:218
GLint ycorrection_location
Definition: glsl_shader.c:221
GLint uniform_f_locations[WINED3D_MAX_PS_CONSTS_F]
Definition: glsl_shader.c:207
GLint specular_enable_location
Definition: glsl_shader.c:215
GLint np2_fixup_location
Definition: glsl_shader.c:222
GLint bumpenv_mat_location[MAX_TEXTURES]
Definition: glsl_shader.c:210
GLint bumpenv_lum_offset_location[MAX_TEXTURES]
Definition: glsl_shader.c:212
const struct ps_np2fixup_info * np2_fixup_info
Definition: glsl_shader.c:224
GLint fog_scale_location
Definition: glsl_shader.c:219
enum wined3d_data_type data_type
Definition: glsl_shader.c:91
unsigned int coord_mask
Definition: glsl_shader.c:89
struct wined3d_string_buffer * name
Definition: glsl_shader.c:88
unsigned int deriv_mask
Definition: glsl_shader.c:90
enum wined3d_shader_resource_type emulate_lod
Definition: glsl_shader.c:94
unsigned int offset_size
Definition: glsl_shader.c:93
unsigned int num_gl_shaders
Definition: glsl_shader.c:322
struct glsl_ds_compiled_shader * ds
Definition: glsl_shader.c:317
struct glsl_hs_compiled_shader * hs
Definition: glsl_shader.c:316
struct glsl_ps_compiled_shader * ps
Definition: glsl_shader.c:319
struct glsl_gs_compiled_shader * gs
Definition: glsl_shader.c:318
unsigned int shader_array_size
Definition: glsl_shader.c:322
union glsl_shader_private::@276 gl_shaders
struct glsl_cs_compiled_shader * cs
Definition: glsl_shader.c:320
struct glsl_vs_compiled_shader * vs
Definition: glsl_shader.c:315
char param_str[200]
Definition: glsl_shader.c:83
char reg_name[150]
Definition: glsl_shader.c:82
struct list shader_entry
Definition: glsl_shader.c:139
GLint pointsize_max_location
Definition: glsl_shader.c:174
GLint pointsize_l_att_location
Definition: glsl_shader.c:176
GLint pointsize_location
Definition: glsl_shader.c:172
GLint uniform_f_locations[WINED3D_MAX_VS_CONSTS_F]
Definition: glsl_shader.c:142
GLint clip_planes_location
Definition: glsl_shader.c:178
GLint projection_matrix_location
Definition: glsl_shader.c:149
GLenum vertex_color_clamp
Definition: glsl_shader.c:141
GLint texture_matrix_location[MAX_TEXTURES]
Definition: glsl_shader.c:150
GLint light_ambient_location
Definition: glsl_shader.c:156
GLint normal_matrix_location[MAX_VERTEX_INDEX_BLENDS]
Definition: glsl_shader.c:148
GLint material_shininess_location
Definition: glsl_shader.c:155
GLint pointsize_q_att_location
Definition: glsl_shader.c:177
GLint uniform_b_locations[WINED3D_MAX_CONSTS_B]
Definition: glsl_shader.c:144
GLint material_diffuse_location
Definition: glsl_shader.c:152
GLint material_emissive_location
Definition: glsl_shader.c:154
GLint uniform_i_locations[WINED3D_MAX_CONSTS_I]
Definition: glsl_shader.c:143
GLint material_specular_location
Definition: glsl_shader.c:153
GLint modelview_matrix_location[MAX_VERTEX_INDEX_BLENDS]
Definition: glsl_shader.c:147
GLint pointsize_min_location
Definition: glsl_shader.c:173
struct glsl_vs_program::@275 light_location[MAX_ACTIVE_LIGHTS]
GLint pointsize_c_att_location
Definition: glsl_shader.c:175
GLint material_ambient_location
Definition: glsl_shader.c:151
GLint pos_fixup_location
Definition: glsl_shader.c:145
Definition: copy.c:22
Definition: parser.c:49
Definition: list.h:15
Definition: mem.c:156
Definition: name.c:39
unsigned char idx[MAX_FRAGMENT_SAMPLERS]
Definition: send.c:48
unsigned int vs_version
unsigned int cs_version
DWORD vs_uniform_count
DWORD ps_uniform_count
unsigned int hs_version
unsigned int gs_version
unsigned int ps_version
unsigned int ds_version
const struct ds_compile_args * cur_ds_args
Definition: glsl_shader.c:263
const struct vs_compile_args * cur_vs_args
Definition: glsl_shader.c:262
struct ps_np2fixup_info * cur_np2fixup_info
Definition: glsl_shader.c:265
const struct ps_compile_args * cur_ps_args
Definition: glsl_shader.c:264
struct wined3d_string_buffer_list * string_buffers
Definition: glsl_shader.c:266
struct constant_heap pconst_heap
Definition: glsl_shader.c:125
unsigned char * stack
Definition: glsl_shader.c:126
struct wined3d_string_buffer_list string_buffers
Definition: glsl_shader.c:122
struct wine_rb_tree ffp_vertex_shaders
Definition: glsl_shader.c:131
UINT next_constant_version
Definition: glsl_shader.c:127
struct constant_heap vconst_heap
Definition: glsl_shader.c:124
struct wine_rb_tree ffp_fragment_shaders
Definition: glsl_shader.c:132
const struct fragment_pipeline * fragment_pipe
Definition: glsl_shader.c:130
struct wine_rb_tree program_lookup
Definition: glsl_shader.c:123
const struct wined3d_vertex_pipe_ops * vertex_pipe
Definition: glsl_shader.c:129
struct wined3d_string_buffer shader_buffer
Definition: glsl_shader.c:121
Definition: parse.h:23
float x
Definition: d3dx9_private.h:38
unsigned int next_shader_input_count
Definition: rbtree.h:36
const struct wined3d_gl_info * gl_info
BOOL supported[WINED3D_GL_EXT_COUNT]
struct opengl_funcs gl_ops
struct wined3d_gl_limits limits
unsigned int output_vertex_count
struct wined3d_hull_shader::@288 phases
struct wined3d_vec4 position
struct wined3d_light OriginalParms
struct wined3d_vec4 direction
unsigned int max_sm_hs
unsigned int max_sm_vs
unsigned int max_sm_ps
unsigned int max_sm_cs
unsigned int max_sm_ds
unsigned int max_sm_gs
struct wined3d_shader_register reg
DWORD data[MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE]
const struct wined3d_shader_src_param * src
const struct wined3d_shader_dst_param * dst
enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx
const struct wined3d_shader_context * ctx
struct wined3d_shader_texel_offset texel_offset
unsigned int instance_count
unsigned int temporary_count
UINT cb_sizes[WINED3D_MAX_CBS]
union wined3d_shader_reg_maps::@279 u
struct wined3d_shader_version shader_version
struct wined3d_shader_tgsm * tgsm
const struct wined3d_shader_immediate_constant_buffer * icb
struct wined3d_shader_sampler_map sampler_map
BYTE output_registers_mask[MAX_REG_OUTPUT]
struct wined3d_shader_resource_info resource_info[MAX_SHADER_RESOURCE_VIEWS]
struct wined3d_shader_resource_info uav_resource_info[MAX_UNORDERED_ACCESS_VIEWS]
enum wined3d_shader_resource_type type
enum wined3d_data_type data_type
unsigned int sampler_idx
unsigned int bind_idx
unsigned int resource_idx
struct wined3d_shader_sampler_map_entry * entries
enum wined3d_sysval_semantic sysval_semantic
Definition: wined3d.h:2037
struct wined3d_shader_signature_element * elements
Definition: wined3d.h:2046
enum wined3d_shader_src_modifier modifiers
struct wined3d_shader_register reg
enum wined3d_shader_type type
union wined3d_shader::@289 u
struct wined3d_shader_signature input_signature
struct wined3d_pixel_shader ps
const struct wined3d_shader_limits * limits
struct wined3d_shader_reg_maps reg_maps
struct list linked_programs
unsigned int buffer_strides[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]
Definition: wined3d.h:2073
struct wined3d_stream_output_element * elements
Definition: wined3d.h:2071
unsigned int element_count
Definition: wined3d.h:2072
unsigned int rasterizer_stream_idx
Definition: wined3d.h:2075
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
#define new(TYPE, numElems)
Definition: treelist.c:54
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
int ret
#define GL_COMPUTE_SHADER
Definition: wgl.h:689
type_t * reg_type(type_t *type, const char *name, struct namespace *namespace, int t)
#define WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
Definition: wined3d.h:1162
#define WINED3DPRASTERCAPS_FOGRANGE
Definition: wined3d.h:1206
#define WINED3DVTXPCAPS_LOCALVIEWER
Definition: wined3d.h:1282
#define WINED3DTEXOPCAPS_ADD
Definition: wined3d.h:1151
@ WINED3D_SHADE_FLAT
Definition: wined3d.h:479
#define WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
Definition: wined3d.h:1163
@ WINED3D_TYPE_UINT
Definition: wined3d.h:825
@ WINED3D_TYPE_UNKNOWN
Definition: wined3d.h:824
@ WINED3D_TYPE_FLOAT
Definition: wined3d.h:827
@ WINED3D_TYPE_INT
Definition: wined3d.h:826
#define WINED3DTA_TEMP
Definition: wined3d.h:872
#define WINED3DTA_SPECULAR
Definition: wined3d.h:871
static unsigned int wined3d_log2i(unsigned int x)
Definition: wined3d.h:2759
#define WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
Definition: wined3d.h:1156
#define WINED3D_TS_WORLD_MATRIX(index)
Definition: wined3d.h:664
@ WINED3D_FOG_NONE
Definition: wined3d.h:471
#define WINED3DTA_COMPLEMENT
Definition: wined3d.h:874
@ WINED3D_DECL_USAGE_PSIZE
Definition: wined3d.h:790
@ WINED3D_DECL_USAGE_POSITION
Definition: wined3d.h:786
@ WINED3D_DECL_USAGE_COLOR
Definition: wined3d.h:796
@ WINED3D_DECL_USAGE_TEXCOORD
Definition: wined3d.h:791
@ WINED3D_DECL_USAGE_FOG
Definition: wined3d.h:797
#define WINED3D_NO_RASTERIZER_STREAM
Definition: wined3d.h:1571
#define WINED3DPMISCCAPS_PERSTAGECONSTANT
Definition: wined3d.h:1105
#define WINED3DVTXPCAPS_POSITIONALLIGHTS
Definition: wined3d.h:1281
@ WINED3D_RS_TEXTUREFACTOR
Definition: wined3d.h:314
@ WINED3D_RS_COLORKEYENABLE
Definition: wined3d.h:300
@ WINED3D_RS_LIGHTING
Definition: wined3d.h:324
@ WINED3D_RS_COLORVERTEX
Definition: wined3d.h:328
@ WINED3D_RS_TWEENFACTOR
Definition: wined3d.h:354
@ WINED3D_RS_FOGCOLOR
Definition: wined3d.h:293
@ WINED3D_RS_SPECULARMATERIALSOURCE
Definition: wined3d.h:333
@ WINED3D_RS_SHADEMODE
Definition: wined3d.h:271
@ WINED3D_RS_VERTEXBLEND
Definition: wined3d.h:336
@ WINED3D_RS_FOGEND
Definition: wined3d.h:296
@ WINED3D_RS_POINTSCALE_A
Definition: wined3d.h:343
@ WINED3D_RS_SRGBWRITEENABLE
Definition: wined3d.h:377
@ WINED3D_RS_RANGEFOGENABLE
Definition: wined3d.h:302
@ WINED3D_RS_POINTSIZE_MIN
Definition: wined3d.h:340
@ WINED3D_RS_LOCALVIEWER
Definition: wined3d.h:329
@ WINED3D_RS_POINTSCALE_C
Definition: wined3d.h:345
@ WINED3D_RS_FOGSTART
Definition: wined3d.h:295
@ WINED3D_RS_FOGTABLEMODE
Definition: wined3d.h:294
@ WINED3D_RS_POINTSIZE
Definition: wined3d.h:339
@ WINED3D_RS_POINTSIZE_MAX
Definition: wined3d.h:351
@ WINED3D_RS_CLIPPLANEENABLE
Definition: wined3d.h:337
@ WINED3D_RS_AMBIENTMATERIALSOURCE
Definition: wined3d.h:334
@ WINED3D_RS_FOGENABLE
Definition: wined3d.h:287
@ WINED3D_RS_POINTSPRITEENABLE
Definition: wined3d.h:341
@ WINED3D_RS_DIFFUSEMATERIALSOURCE
Definition: wined3d.h:332
@ WINED3D_RS_ALPHAREF
Definition: wined3d.h:283
@ WINED3D_RS_NORMALIZENORMALS
Definition: wined3d.h:330
@ WINED3D_RS_EMISSIVEMATERIALSOURCE
Definition: wined3d.h:335
@ WINED3D_RS_SPECULARENABLE
Definition: wined3d.h:288
@ WINED3D_RS_CLIPPING
Definition: wined3d.h:323
@ WINED3D_RS_POINTSCALEENABLE
Definition: wined3d.h:342
@ WINED3D_RS_FOGVERTEXMODE
Definition: wined3d.h:327
@ WINED3D_RS_AMBIENT
Definition: wined3d.h:326
@ WINED3D_RS_FOGDENSITY
Definition: wined3d.h:297
@ WINED3D_RS_POINTSCALE_B
Definition: wined3d.h:344
@ WINED3D_RS_INDEXEDVERTEXBLENDENABLE
Definition: wined3d.h:352
@ WINED3D_RS_ALPHATESTENABLE
Definition: wined3d.h:277
@ WINED3D_RS_ALPHAFUNC
Definition: wined3d.h:284
wined3d_primitive_type
Definition: wined3d.h:70
@ WINED3D_PT_LINELIST
Definition: wined3d.h:73
@ WINED3D_PT_POINTLIST
Definition: wined3d.h:72
@ WINED3D_PT_TRIANGLELIST_ADJ
Definition: wined3d.h:80
@ WINED3D_PT_LINELIST_ADJ
Definition: wined3d.h:78
@ WINED3D_PT_TRIANGLESTRIP
Definition: wined3d.h:76
@ WINED3D_PT_LINESTRIP
Definition: wined3d.h:74
@ WINED3D_PT_TRIANGLELIST
Definition: wined3d.h:75
#define WINED3D_OK
Definition: wined3d.h:37
#define WINED3DVTXPCAPS_TEXGEN
Definition: wined3d.h:1277
#define WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
Definition: wined3d.h:1167
wined3d_material_color_source
Definition: wined3d.h:511
@ WINED3D_MCS_COLOR2
Definition: wined3d.h:514
@ WINED3D_MCS_MATERIAL
Definition: wined3d.h:512
@ WINED3D_MCS_COLOR1
Definition: wined3d.h:513
#define WINED3DVTXPCAPS_MATERIALSOURCE7
Definition: wined3d.h:1278
#define WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
Definition: wined3d.h:1157
#define WINED3DTEXOPCAPS_MODULATE2X
Definition: wined3d.h:1149
#define WINED3D_MAX_STREAM_OUTPUT_BUFFERS
Definition: wined3d.h:1569
#define WINED3DVTXPCAPS_VERTEXFOG
Definition: wined3d.h:1279
#define WINED3DTA_SELECTMASK
Definition: wined3d.h:866
#define WINED3DTEXOPCAPS_DISABLE
Definition: wined3d.h:1145
@ WINED3D_SV_INSTANCE_ID
Definition: wined3d.h:811
@ WINED3D_SV_CULL_DISTANCE
Definition: wined3d.h:806
@ WINED3D_SV_CLIP_DISTANCE
Definition: wined3d.h:805
@ WINED3D_SV_TESS_FACTOR_QUADINT
Definition: wined3d.h:815
@ WINED3D_SV_IS_FRONT_FACE
Definition: wined3d.h:812
@ WINED3D_SV_TESS_FACTOR_QUADEDGE
Definition: wined3d.h:814
@ WINED3D_SV_TESS_FACTOR_LINEDET
Definition: wined3d.h:818
@ WINED3D_SV_POSITION
Definition: wined3d.h:804
@ WINED3D_SV_RENDER_TARGET_ARRAY_INDEX
Definition: wined3d.h:807
@ WINED3D_SV_TESS_FACTOR_TRIINT
Definition: wined3d.h:817
@ WINED3D_SV_TESS_FACTOR_TRIEDGE
Definition: wined3d.h:816
@ WINED3D_SV_TESS_FACTOR_LINEDEN
Definition: wined3d.h:819
@ WINED3D_SV_VERTEX_ID
Definition: wined3d.h:809
@ WINED3D_LIGHT_SPOT
Definition: wined3d.h:63
@ WINED3D_LIGHT_PARALLELPOINT
Definition: wined3d.h:65
@ WINED3D_LIGHT_POINT
Definition: wined3d.h:62
@ WINED3D_LIGHT_DIRECTIONAL
Definition: wined3d.h:64
#define WINED3DTEXOPCAPS_SELECTARG1
Definition: wined3d.h:1146
#define WINED3D_VIEW_BUFFER_RAW
Definition: wined3d.h:1573
#define WINED3DTA_TFACTOR
Definition: wined3d.h:870
#define WINED3DTSS_TCI_PASSTHRU
Definition: wined3d.h:860
#define WINED3DTEXOPCAPS_SUBTRACT
Definition: wined3d.h:1154
@ WINED3D_TSS_COLOR_ARG2
Definition: wined3d.h:577
@ WINED3D_TSS_BUMPENV_LOFFSET
Definition: wined3d.h:587
@ WINED3D_TSS_ALPHA_OP
Definition: wined3d.h:578
@ WINED3D_TSS_COLOR_OP
Definition: wined3d.h:575
@ WINED3D_TSS_TEXCOORD_INDEX
Definition: wined3d.h:585
@ WINED3D_TSS_ALPHA_ARG2
Definition: wined3d.h:580
@ WINED3D_TSS_CONSTANT
Definition: wined3d.h:592
@ WINED3D_TSS_ALPHA_ARG0
Definition: wined3d.h:590
@ WINED3D_TSS_BUMPENV_LSCALE
Definition: wined3d.h:586
@ WINED3D_TSS_COLOR_ARG0
Definition: wined3d.h:589
@ WINED3D_TSS_COLOR_ARG1
Definition: wined3d.h:576
@ WINED3D_TSS_ALPHA_ARG1
Definition: wined3d.h:579
@ WINED3D_TSS_RESULT_ARG
Definition: wined3d.h:591
@ WINED3D_TSS_BUMPENV_MAT00
Definition: wined3d.h:581
@ WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
Definition: wined3d.h:588
#define WINED3DFVFCAPS_PSIZE
Definition: wined3d.h:1057
#define WINED3DTEXOPCAPS_BUMPENVMAP
Definition: wined3d.h:1166
#define WINED3DTA_CURRENT
Definition: wined3d.h:868
#define WINED3DTEXOPCAPS_ADDSIGNED2X
Definition: wined3d.h:1153
#define WINED3DTEXOPCAPS_MODULATE4X
Definition: wined3d.h:1150
#define WINED3DTSS_TCI_CAMERASPACENORMAL
Definition: wined3d.h:861
@ WINED3D_TOP_SELECT_ARG1
Definition: wined3d.h:610
@ WINED3D_TOP_DISABLE
Definition: wined3d.h:609
@ WINED3D_TOP_BLEND_DIFFUSE_ALPHA
Definition: wined3d.h:620
@ WINED3D_TOP_ADD
Definition: wined3d.h:615
@ WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM
Definition: wined3d.h:623
@ WINED3D_TOP_BLEND_CURRENT_ALPHA
Definition: wined3d.h:624
@ WINED3D_TOP_ADD_SIGNED_2X
Definition: wined3d.h:617
@ WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA
Definition: wined3d.h:629
@ WINED3D_TOP_MULTIPLY_ADD
Definition: wined3d.h:633
@ WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR
Definition: wined3d.h:628
@ WINED3D_TOP_SUBTRACT
Definition: wined3d.h:618
@ WINED3D_TOP_BUMPENVMAP_LUMINANCE
Definition: wined3d.h:631
@ WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA
Definition: wined3d.h:627
@ WINED3D_TOP_MODULATE
Definition: wined3d.h:612
@ WINED3D_TOP_BUMPENVMAP
Definition: wined3d.h:630
@ WINED3D_TOP_MODULATE_4X
Definition: wined3d.h:614
@ WINED3D_TOP_SELECT_ARG2
Definition: wined3d.h:611
@ WINED3D_TOP_LERP
Definition: wined3d.h:634
@ WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR
Definition: wined3d.h:626
@ WINED3D_TOP_BLEND_TEXTURE_ALPHA
Definition: wined3d.h:621
@ WINED3D_TOP_ADD_SIGNED
Definition: wined3d.h:616
@ WINED3D_TOP_DOTPRODUCT3
Definition: wined3d.h:632
@ WINED3D_TOP_ADD_SMOOTH
Definition: wined3d.h:619
@ WINED3D_TOP_MODULATE_2X
Definition: wined3d.h:613
@ WINED3D_TOP_BLEND_FACTOR_ALPHA
Definition: wined3d.h:622
#define WINED3DTEXOPCAPS_ADDSMOOTH
Definition: wined3d.h:1155
wined3d_cmp_func
Definition: wined3d.h:451
@ WINED3D_CMP_ALWAYS
Definition: wined3d.h:459
@ WINED3D_CMP_NEVER
Definition: wined3d.h:452
#define WINED3DTA_ALPHAREPLICATE
Definition: wined3d.h:875
#define WINED3D_STREAM_OUTPUT_GAP
Definition: wined3d.h:1570
#define WINED3DTSS_TCI_SPHEREMAP
Definition: wined3d.h:864
#define WINED3DVTXPCAPS_TEXGEN_SPHEREMAP
Definition: wined3d.h:1284
@ WINED3D_TTFF_COUNT2
Definition: wined3d.h:601
@ WINED3D_TTFF_COUNT4
Definition: wined3d.h:603
@ WINED3D_TTFF_DISABLE
Definition: wined3d.h:599
@ WINED3D_TTFF_COUNT3
Definition: wined3d.h:602
@ WINED3D_TTFF_COUNT1
Definition: wined3d.h:600
#define WINED3DPMISCCAPS_TSSARGTEMP
Definition: wined3d.h:1101
#define WINED3DTEXOPCAPS_MULTIPLYADD
Definition: wined3d.h:1169
#define WINED3D_LEGACY_FFP_LIGHTING
Definition: wined3d.h:1323
#define WINED3DTEXOPCAPS_BLENDFACTORALPHA
Definition: wined3d.h:1158
#define WINED3DTA_DIFFUSE
Definition: wined3d.h:867
@ WINED3D_TS_TEXTURE1
Definition: wined3d.h:651
@ WINED3D_TS_TEXTURE0
Definition: wined3d.h:650
@ WINED3D_TS_TEXTURE2
Definition: wined3d.h:652
@ WINED3D_TS_PROJECTION
Definition: wined3d.h:649
@ WINED3D_TS_VIEW
Definition: wined3d.h:648
@ WINED3D_TS_TEXTURE7
Definition: wined3d.h:657
@ WINED3D_TS_TEXTURE6
Definition: wined3d.h:656
@ WINED3D_TS_TEXTURE4
Definition: wined3d.h:654
@ WINED3D_TS_TEXTURE3
Definition: wined3d.h:653
@ WINED3D_TS_TEXTURE5
Definition: wined3d.h:655
#define WINED3DTEXOPCAPS_ADDSIGNED
Definition: wined3d.h:1152
#define WINED3D_PIXEL_CENTER_INTEGER
Definition: wined3d.h:1322
#define WINED3DTEXOPCAPS_DOTPRODUCT3
Definition: wined3d.h:1168
#define WINED3DTA_CONSTANT
Definition: wined3d.h:873
#define WINED3DTEXOPCAPS_LERP
Definition: wined3d.h:1170
#define WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM
Definition: wined3d.h:1159
#define WINED3DTEXOPCAPS_SELECTARG2
Definition: wined3d.h:1147
#define WINED3DTEXOPCAPS_MODULATE
Definition: wined3d.h:1148
#define WINED3DTA_TEXTURE
Definition: wined3d.h:869
#define WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
Definition: wined3d.h:1165
#define WINED3DTSS_TCI_CAMERASPACEPOSITION
Definition: wined3d.h:862
#define WINED3DVTXPCAPS_DIRECTIONALLIGHTS
Definition: wined3d.h:1280
#define WINED3DTEXOPCAPS_BLENDCURRENTALPHA
Definition: wined3d.h:1160
#define WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
Definition: wined3d.h:863
#define WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
Definition: wined3d.h:1164
@ ARB_GPU_SHADER5
Definition: wined3d_gl.h:76
@ ARB_EXPLICIT_ATTRIB_LOCATION
Definition: wined3d_gl.h:67
@ ARB_SHADING_LANGUAGE_PACKING
Definition: wined3d_gl.h:102
@ ARB_TEXTURE_QUERY_LEVELS
Definition: wined3d_gl.h:124
@ ARB_CULL_DISTANCE
Definition: wined3d_gl.h:55
@ ARB_DERIVATIVE_CONTROL
Definition: wined3d_gl.h:60
@ ARB_SHADER_BIT_ENCODING
Definition: wined3d_gl.h:95
@ WINED3D_GL_EXT_NONE
Definition: wined3d_gl.h:37
@ ARB_SHADER_IMAGE_SIZE
Definition: wined3d_gl.h:97
@ ARB_COMPUTE_SHADER
Definition: wined3d_gl.h:51
@ ARB_FRAGMENT_LAYER_VIEWPORT
Definition: wined3d_gl.h:69
@ ARB_CONSERVATIVE_DEPTH
Definition: wined3d_gl.h:52
@ ARB_SHADER_STORAGE_BUFFER_OBJECT
Definition: wined3d_gl.h:98
@ ARB_SAMPLER_OBJECTS
Definition: wined3d_gl.h:92
@ ARB_VERTEX_SHADER
Definition: wined3d_gl.h:140
@ WINED3D_GL_VERSION_3_2
Definition: wined3d_gl.h:217
@ ARB_DRAW_INDIRECT
Definition: wined3d_gl.h:63
@ EXT_GPU_SHADER4
Definition: wined3d_gl.h:162
@ ARB_FRAMEBUFFER_SRGB
Definition: wined3d_gl.h:74
@ ARB_FRAGMENT_COORD_CONVENTIONS
Definition: wined3d_gl.h:68
@ ARB_UNIFORM_BUFFER_OBJECT
Definition: wined3d_gl.h:135
@ WINED3D_GL_NORMALIZED_TEXRECT
Definition: wined3d_gl.h:214
@ WINED3D_GLSL_130
Definition: wined3d_gl.h:218
@ ARB_SHADER_TEXTURE_LOD
Definition: wined3d_gl.h:99
@ ARB_FRAGMENT_SHADER
Definition: wined3d_gl.h:71
@ ARB_SHADER_ATOMIC_COUNTERS
Definition: wined3d_gl.h:94
@ ARB_SHADING_LANGUAGE_420PACK
Definition: wined3d_gl.h:101
@ ARB_TESSELLATION_SHADER
Definition: wined3d_gl.h:106
@ ARB_COLOR_BUFFER_FLOAT
Definition: wined3d_gl.h:50
@ ARB_DRAW_INSTANCED
Definition: wined3d_gl.h:64
@ ARB_TRANSFORM_FEEDBACK3
Definition: wined3d_gl.h:134
@ ARB_TEXTURE_GATHER
Definition: wined3d_gl.h:119
@ ARB_TEXTURE_RECTANGLE
Definition: wined3d_gl.h:125
@ ARB_TEXTURE_NON_POWER_OF_TWO
Definition: wined3d_gl.h:123
@ WINED3D_GL_LEGACY_CONTEXT
Definition: wined3d_gl.h:213
@ WINED3D_GL_VERSION_2_0
Definition: wined3d_gl.h:216
@ ARB_CLIP_CONTROL
Definition: wined3d_gl.h:49
@ ARB_TEXTURE_SWIZZLE
Definition: wined3d_gl.h:130
@ ARB_SHADER_IMAGE_LOAD_STORE
Definition: wined3d_gl.h:96
@ ARB_POINT_SPRITE
Definition: wined3d_gl.h:90
@ EXT_TEXTURE_ARRAY
Definition: wined3d_gl.h:172
@ ARB_TEXTURE_CUBE_MAP_ARRAY
Definition: wined3d_gl.h:114
static void shader_get_position_fixup(const struct wined3d_context *context, const struct wined3d_state *state, float *position_fixup)
#define WINED3D_SHADER_CONST_PS_BUMP_ENV
static BOOL needs_interpolation_qualifiers_for_shader_outputs(const struct wined3d_gl_info *gl_info)
#define WINED3DSP_WRITEMASK_ALL
static void context_apply_state(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ proj_none
@ proj_count3
@ proj_count4
#define STATE_CLIPPLANE(a)
#define WINED3DSP_WRITEMASK_0
#define STATE_LIGHT_TYPE
wined3d_shader_rel_op
@ WINED3D_SHADER_REL_OP_GT
@ WINED3D_SHADER_REL_OP_LE
@ WINED3D_SHADER_REL_OP_GE
@ WINED3D_SHADER_REL_OP_EQ
@ WINED3D_SHADER_REL_OP_LT
@ WINED3D_SHADER_REL_OP_NE
#define MAX_FRAGMENT_SAMPLERS
wined3d_data_type
@ WINED3D_DATA_UINT
@ WINED3D_DATA_INT
@ WINED3D_DATA_SAMPLER
@ WINED3D_DATA_SNORM
@ WINED3D_DATA_UNORM
@ WINED3D_DATA_RESOURCE
@ WINED3D_DATA_FLOAT
wined3d_shader_interpolation_mode
@ WINED3DSIM_LINEAR
@ WINED3DSIM_NONE
@ WINED3DSIM_LINEAR_NOPERSPECTIVE
@ WINED3DSIM_CONSTANT
@ WINED3DSIH_DSX_COARSE
@ WINED3DSIH_MOVC
@ WINED3DSIH_ULT
@ WINED3DSIH_DP4
@ WINED3DSIH_GATHER4_PO_C
@ WINED3DSIH_ATOMIC_XOR
@ WINED3DSIH_MUL
@ WINED3DSIH_DSX_FINE
@ WINED3DSIH_M3x3
@ WINED3DSIH_IMM_ATOMIC_XOR
@ WINED3DSIH_IEQ
@ WINED3DSIH_CONTINUEP
@ WINED3DSIH_FIRSTBIT_HI
@ WINED3DSIH_IADD
@ WINED3DSIH_ABS
@ WINED3DSIH_SAMPLE_B
@ WINED3DSIH_ROUND_Z
@ WINED3DSIH_IMM_ATOMIC_IADD
@ WINED3DSIH_DSY_COARSE
@ WINED3DSIH_M3x4
@ WINED3DSIH_SAMPLE_LOD
@ WINED3DSIH_ISHL
@ WINED3DSIH_SUB
@ WINED3DSIH_RCP
@ WINED3DSIH_F16TOF32
@ WINED3DSIH_IMIN
@ WINED3DSIH_STORE_STRUCTURED
@ WINED3DSIH_IMM_ATOMIC_UMAX
@ WINED3DSIH_EXP
@ WINED3DSIH_ATOMIC_IMAX
@ WINED3DSIH_UMAX
@ WINED3DSIH_OR
@ WINED3DSIH_ROUND_PI
@ WINED3DSIH_SAMPLE_GRAD
@ WINED3DSIH_ATOMIC_AND
@ WINED3DSIH_ATOMIC_UMIN
@ WINED3DSIH_UMIN
@ WINED3DSIH_ATOMIC_OR
@ WINED3DSIH_LOG
@ WINED3DSIH_SAMPLE
@ WINED3DSIH_AND
@ WINED3DSIH_ATOMIC_CMP_STORE
@ WINED3DSIH_LD_STRUCTURED
@ WINED3DSIH_ATOMIC_IADD
@ WINED3DSIH_RSQ
@ WINED3DSIH_SQRT
@ WINED3DSIH_IMM_ATOMIC_AND
@ WINED3DSIH_EQ
@ WINED3DSIH_IMM_ATOMIC_UMIN
@ WINED3DSIH_ADD
@ WINED3DSIH_NOT
@ WINED3DSIH_XOR
@ WINED3DSIH_BFREV
@ WINED3DSIH_FRC
@ WINED3DSIH_DSX
@ WINED3DSIH_COUNTBITS
@ WINED3DSIH_IMM_ATOMIC_CMP_EXCH
@ WINED3DSIH_USHR
@ WINED3DSIH_ENDREP
@ WINED3DSIH_EMIT
@ WINED3DSIH_TEXBEML
@ WINED3DSIH_ILT
@ WINED3DSIH_UBFE
@ WINED3DSIH_ATOMIC_IMIN
@ WINED3DSIH_BREAKP
@ WINED3DSIH_BFI
@ WINED3DSIH_M3x2
@ WINED3DSIH_MIN
@ WINED3DSIH_TABLE_SIZE
@ WINED3DSIH_GE
@ WINED3DSIH_SLT
@ WINED3DSIH_DP3
@ WINED3DSIH_CUT
@ WINED3DSIH_IMAX
@ WINED3DSIH_IGE
@ WINED3DSIH_IMM_ATOMIC_IMAX
@ WINED3DSIH_SAMPLE_C_LZ
@ WINED3DSIH_ENDLOOP
@ WINED3DSIH_DSY
@ WINED3DSIH_MOVA
@ WINED3DSIH_GATHER4_C
@ WINED3DSIH_INEG
@ WINED3DSIH_GATHER4_PO
@ WINED3DSIH_CMP
@ WINED3DSIH_LT
@ WINED3DSIH_CND
@ WINED3DSIH_ROUND_NI
@ WINED3DSIH_M4x3
@ WINED3DSIH_INE
@ WINED3DSIH_IBFE
@ WINED3DSIH_IMM_ATOMIC_ALLOC
@ WINED3DSIH_IMM_ATOMIC_IMIN
@ WINED3DSIH_UGE
@ WINED3DSIH_EXPP
@ WINED3DSIH_IMM_ATOMIC_EXCH
@ WINED3DSIH_NE
@ WINED3DSIH_SGE
@ WINED3DSIH_FIRSTBIT_SHI
@ WINED3DSIH_FIRSTBIT_LO
@ WINED3DSIH_M4x4
@ WINED3DSIH_ROUND_NE
@ WINED3DSIH_LOGP
@ WINED3DSIH_IMM_ATOMIC_OR
@ WINED3DSIH_DIV
@ WINED3DSIH_ATOMIC_UMAX
@ WINED3DSIH_MAX
@ WINED3DSIH_RETP
@ WINED3DSIH_ISHR
@ WINED3DSIH_DSY_FINE
#define WINED3DSP_WRITEMASK_3
#define WINED3D_MAX_CBS
@ WINED3D_TESSELLATOR_OUTPUT_POINT
@ WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CW
@ WINED3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW
@ WINED3D_TESSELLATOR_OUTPUT_LINE
#define WINED3DSI_TEXLD_BIAS
#define WINED3D_PSARGS_PROJECTED
@ WINED3D_FFP_NORMAL
@ WINED3D_FFP_TEXCOORD0
@ WINED3D_FFP_ATTRIBS_COUNT
#define WINED3D_FRAGMENT_CAP_COLOR_KEY
@ WINED3DSSF_THREAD_GROUP
@ WINED3DSSF_GROUP_SHARED_MEMORY
wined3d_shader_src_modifier
@ WINED3DSPSM_ABSNEG
@ WINED3DSPSM_X2NEG
@ WINED3DSPSM_BIAS
@ WINED3DSPSM_BIASNEG
@ WINED3DSPSM_COMP
@ WINED3DSPSM_ABS
@ WINED3DSPSM_NOT
@ WINED3DSPSM_SIGNNEG
@ WINED3DSPSM_DW
@ WINED3DSPSM_X2
@ WINED3DSPSM_SIGN
@ WINED3DSPSM_NONE
@ WINED3DSPSM_NEG
@ WINED3DSPSM_DZ
#define WINED3D_PACKED_INTERPOLATION_BIT_COUNT
#define STATE_TRANSFORM(a)
#define MAKEDWORD_VERSION(maj, min)
#define ARG_UNUSED
static BOOL use_vs(const struct wined3d_state *state)
#define WINED3D_MAX_PS_CONSTS_F
#define WINED3D_SHADER_CONST_PS_F
#define STATE_POINT_ENABLE
#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND
#define WINED3D_PSARGS_TEXTRANSFORM_SHIFT
@ WINED3DSPDM_MSAMPCENTROID
@ WINED3DSPDM_PARTIALPRECISION
@ WINED3DSPDM_SATURATE
#define WINED3DSI_RESINFO_UINT
#define WINED3D_MAX_VS_CONSTS_F
#define WINED3D_TEXTURE_POW2_MAT_IDENT
#define WINED3D_SHADER_CONST_VS_B
#define WINED3D_PSARGS_TEXTRANSFORM_MASK
static enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup)
static BOOL wined3d_dualblend_enabled(const struct wined3d_state *state, const struct wined3d_gl_info *gl_info)
#define MAX_VERTEX_INDEX_BLENDS
#define STATE_SHADER(a)
static BOOL wined3d_shader_instruction_has_texel_offset(const struct wined3d_shader_instruction *ins)
#define STATE_ACTIVELIGHT(a)
#define MAX_UNORDERED_ACCESS_VIEWS
#define WINED3D_SHADER_CONST_VS_I
static BOOL is_complex_fixup(struct color_fixup_desc fixup)
#define WINED3D_SHADER_CONST_PS_I
#define GL_EXTCALL(f)
fixup_channel_source
@ CHANNEL_SOURCE_ONE
@ CHANNEL_SOURCE_W
@ CHANNEL_SOURCE_X
@ CHANNEL_SOURCE_ZERO
@ CHANNEL_SOURCE_Z
@ CHANNEL_SOURCE_Y
wined3d_shader_resource_type
@ WINED3D_SHADER_RESOURCE_BUFFER
@ WINED3D_SHADER_RESOURCE_TEXTURE_3D
@ WINED3D_SHADER_RESOURCE_TEXTURE_2D
@ WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY
@ WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY
@ WINED3D_SHADER_RESOURCE_NONE
@ WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY
@ WINED3D_SHADER_RESOURCE_TEXTURE_2DMS
@ WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY
@ WINED3D_SHADER_RESOURCE_TEXTURE_CUBE
@ WINED3D_SHADER_RESOURCE_TEXTURE_1D
@ tempreg
#define WINED3D_SAMPLER_DEFAULT
#define WINED3D_SHADER_CONST_FFP_COLOR_KEY
#define MAX_TEXTURES
#define WINED3D_FRAGMENT_CAP_SRGB_WRITE
@ VS_FOG_Z
#define WINED3D_SHADER_VERSION(major, minor)
#define WINED3D_SHADER_CAP_SRGB_WRITE
static const struct color_fixup_desc COLOR_FIXUP_IDENTITY
#define WINED3D_SHADER_CONST_PS_NP2_FIXUP
static BOOL is_rasterization_disabled(const struct wined3d_shader *geometry_shader)
#define MAX_ACTIVE_LIGHTS
#define GL_EXT_EMUL_ARB_MULTITEXTURE
@ WINED3D_TESSELLATOR_DOMAIN_TRIANGLE
@ WINED3D_TESSELLATOR_DOMAIN_QUAD
@ WINED3D_TESSELLATOR_DOMAIN_LINE
#define STATE_SAMPLER(num)
static void wined3d_color_from_d3dcolor(struct wined3d_color *wined3d_color, DWORD d3d_color)
fogsource
@ FOGSOURCE_VS
@ FOGSOURCE_COORD
@ FOGSOURCE_FFP
#define WINED3D_QUIRK_INFO_LOG_SPAM
static BOOL is_identity_fixup(struct color_fixup_desc fixup)
#define WINED3D_SHADER_CONST_VS_F
static BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
@ WINED3D_GL_RES_TYPE_TEX_3D
@ WINED3D_GL_RES_TYPE_TEX_CUBE
@ WINED3D_GL_RES_TYPE_TEX_2D
@ WINED3D_GL_RES_TYPE_TEX_RECT
@ WINED3D_GL_RES_TYPE_TEX_1D
wined3d_shader_register_type
@ WINED3DSPR_CONSTBOOL
@ WINED3DSPR_RESOURCE
@ WINED3DSPR_COLOROUT
@ WINED3DSPR_LOOP
@ WINED3DSPR_CONST
@ WINED3DSPR_PRIMID
@ WINED3DSPR_LOCALTHREADID
@ WINED3DSPR_IMMCONST
@ WINED3DSPR_OUTPOINTID
@ WINED3DSPR_OUTCONTROLPOINT
@ WINED3DSPR_INCONTROLPOINT
@ WINED3DSPR_TESSCOORD
@ WINED3DSPR_NULL
@ WINED3DSPR_CONSTINT
@ WINED3DSPR_GSINSTID
@ WINED3DSPR_ATTROUT
@ WINED3DSPR_THREADGROUPID
@ WINED3DSPR_ADDR
@ WINED3DSPR_JOININSTID
@ WINED3DSPR_DEPTHOUTGE
@ WINED3DSPR_UAV
@ WINED3DSPR_SAMPLER
@ WINED3DSPR_CONSTBUFFER
@ WINED3DSPR_IDXTEMP
@ WINED3DSPR_RASTOUT
@ WINED3DSPR_PATCHCONST
@ WINED3DSPR_INPUT
@ WINED3DSPR_GROUPSHAREDMEM
@ WINED3DSPR_TEMP
@ WINED3DSPR_DEPTHOUT
@ WINED3DSPR_TEXCRDOUT
@ WINED3DSPR_THREADID
@ WINED3DSPR_TEXTURE
@ WINED3DSPR_LOCALTHREADINDEX
@ WINED3DSPR_FORKINSTID
@ WINED3DSPR_DEPTHOUTLE
@ WINED3DSPR_MISCTYPE
@ WINED3DSPR_IMMCONSTBUFFER
#define WINED3D_SHADER_CONST_FFP_VERTEXBLEND_INDEX(i)
#define WINED3D_SHADER_CONST_PS_ALPHA_TEST
#define WINED3D_FRAGMENT_CAP_PROJ_CONTROL
#define WINED3DSP_NOSWIZZLE
#define WINED3DSI_TEXLD_PROJECT
#define WINED3D_SHADER_CONST_PS_B
@ WINED3D_IMMCONST_VEC4
@ WINED3D_IMMCONST_SCALAR
#define WINED3D_SHADER_CONST_PS_Y_CORR
static BOOL shader_constant_is_local(const struct wined3d_shader *shader, DWORD reg)
void(* SHADER_HANDLER)(const struct wined3d_shader_instruction *)
static DWORD wined3d_extract_bits(const DWORD *bitstream, unsigned int offset, unsigned int count)
#define WINED3D_MAX_CONSTS_B
#define WINED3D_SHADER_CONST_FFP_MODELVIEW
#define WINED3D_SHADER_CONST_FFP_PS
wined3d_shader_type
@ WINED3D_SHADER_TYPE_HULL
@ WINED3D_SHADER_TYPE_PIXEL
@ WINED3D_SHADER_TYPE_GEOMETRY
@ WINED3D_SHADER_TYPE_DOMAIN
@ WINED3D_SHADER_TYPE_COMPUTE
@ WINED3D_SHADER_TYPE_VERTEX
static BOOL use_ps(const struct wined3d_state *state)
#define WINED3D_QUIRK_GLSL_CLIP_VARYING
#define WINED3D_SHADER_CONST_FFP_LIGHTS
#define WINED3D_SHADER_CONST_FFP_PROJ
@ WINED3D_FFP_VS_FOG_FOGCOORD
@ WINED3D_FFP_VS_FOG_OFF
@ WINED3D_FFP_VS_FOG_DEPTH
@ WINED3D_FFP_VS_FOG_RANGE
complex_fixup
@ WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD
@ WINED3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN
@ WINED3D_TESSELLATOR_PARTITIONING_INTEGER
@ WINED3D_TESSELLATOR_PARTITIONING_POW2
#define STATE_TEXTURESTAGE(stage, num)
#define WINED3D_SHADER_CONST_PS_FOG
#define WINED3D_SHADER_CAP_VS_CLIPPING
#define WINED3D_MAX_CONSTS_I
#define MAX_VERTEX_BLENDS
wined3d_ffp_ps_fog_mode
@ WINED3D_FFP_PS_FOG_EXP
@ WINED3D_FFP_PS_FOG_OFF
@ WINED3D_FFP_PS_FOG_EXP2
@ WINED3D_FFP_PS_FOG_LINEAR
@ pretransformed
@ vertexshader
#define STATE_VDECL
#define STATE_VIEWPORT
#define WINED3D_SHADER_CONST_FFP_TEXMATRIX
#define WINED3D_SHADER_CONST_VS_POINTSIZE
#define WINED3D_SHADER_CONST_POS_FIXUP
static BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
#define WINED3D_SHADER_CONST_VS_CLIP_PLANES
#define WINED3D_UNMAPPED_STAGE
#define checkGLcall(A)
#define STATE_RENDER(a)
#define STATE_COLOR_KEY
static unsigned int wined3d_popcount(unsigned int x)
#define WINED3DSP_WRITEMASK_2
#define WINED3DSP_WRITEMASK_1
@ WINED3D_SHADER_CONDITIONAL_OP_NZ
#define STATE_MATERIAL
#define WINED3D_SHADER_CONST_FFP_MATERIAL
unsigned char BYTE
Definition: xxhash.c:193
#define const
Definition: zconf.h:233