ReactOS  0.4.14-dev-98-gb0d4763
nvidia_texture_shader.c
Go to the documentation of this file.
1 /*
2  * Fixed function pipeline replacement using GL_NV_register_combiners
3  * and GL_NV_texture_shader
4  *
5  * Copyright 2006 Henri Verbeet
6  * Copyright 2008 Stefan Dösinger(for CodeWeavers)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 #include "config.h"
23 #include "wine/port.h"
24 
25 #include <stdio.h>
26 
27 #include "wined3d_private.h"
28 
30 
31 /* Context activation for state handlers is done by the caller. */
32 
33 static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD stage, struct wined3d_context *context)
34 {
35  const struct wined3d_gl_info *gl_info = context->gl_info;
36  BOOL bumpmap = FALSE;
37 
38  if (stage > 0
39  && (state->texture_states[stage - 1][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP_LUMINANCE
40  || state->texture_states[stage - 1][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP))
41  {
42  bumpmap = TRUE;
43  context->texShaderBumpMap |= (1u << stage);
44  }
45  else
46  {
47  context->texShaderBumpMap &= ~(1u << stage);
48  }
49 
50  if (state->textures[stage])
51  {
52  switch (state->textures[stage]->target)
53  {
54  case GL_TEXTURE_2D:
55  gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
57  checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
58  break;
60  gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
62  checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
63  break;
64  case GL_TEXTURE_3D:
66  checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
67  break;
70  checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
71  break;
72  }
73  }
74  else
75  {
76  gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
77  checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
78  }
79 }
80 
82 {
86 };
87 
88 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
89  switch (d3dta) {
90  case WINED3DTA_DIFFUSE:
91  return GL_PRIMARY_COLOR_NV;
92 
93  case WINED3DTA_CURRENT:
94  if (stage) return GL_SPARE0_NV;
95  else return GL_PRIMARY_COLOR_NV;
96 
97  case WINED3DTA_TEXTURE:
98  if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
99  else return GL_PRIMARY_COLOR_NV;
100 
101  case WINED3DTA_TFACTOR:
102  return GL_CONSTANT_COLOR0_NV;
103 
104  case WINED3DTA_SPECULAR:
105  return GL_SECONDARY_COLOR_NV;
106 
107  case WINED3DTA_TEMP:
108  return GL_SPARE1_NV;
109 
110  case WINED3DTA_CONSTANT:
111  /* TODO: Support per stage constants (WINED3D_TSS_CONSTANT, NV_register_combiners2) */
112  FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
113  return GL_CONSTANT_COLOR1_NV;
114 
115  default:
116  FIXME("Unrecognized texture arg %#x\n", d3dta);
117  return GL_TEXTURE;
118  }
119 }
120 
124 
125  FIXME("Unhandled mapping %#x\n", mapping);
126  return mapping;
127 }
128 
129 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
130  /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
131  * be used. */
133  else *mapping = GL_UNSIGNED_IDENTITY_NV; /* Clamp all values to positive ranges */
134 
135  /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
136  * should be used for all input components. */
137  if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
138  else *component_usage = GL_RGB;
139 
140  *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
141 }
142 
143 void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, BOOL is_alpha,
144  int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst)
145 {
146  struct tex_op_args tex_op_args = {{0}, {0}, {0}};
148  GLenum target = GL_COMBINER0_NV + stage;
149  GLenum output;
150 
151  TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
152  stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
153 
154  /* If a texture stage references an invalid texture unit the stage just
155  * passes through the result from the previous stage */
156  if (is_invalid_op(state, stage, op, arg1, arg2, arg3))
157  {
160  }
161 
163  &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
165  &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
167  &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
168 
169 
170  if(dst == WINED3DTA_TEMP) {
172  } else {
174  }
175 
176  switch (op)
177  {
178  case WINED3D_TOP_DISABLE:
179  /* Only for alpha */
180  if (!is_alpha)
181  ERR("Shouldn't be called for WINED3D_TSS_COLOR_OP (WINED3DTOP_DISABLE).\n");
182  /* Input, prev_alpha*1 */
183  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
185  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
187 
188  /* Output */
189  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
191  break;
192 
195  /* Input, arg*1 */
197  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
199  else
200  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
202  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
204 
205  /* Output */
206  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
208  break;
209 
213  /* Input, arg1*arg2 */
214  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
216  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
218 
219  /* Output */
220  if (op == WINED3D_TOP_MODULATE)
221  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
223  else if (op == WINED3D_TOP_MODULATE_2X)
224  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
226  else if (op == WINED3D_TOP_MODULATE_4X)
227  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
229  break;
230 
231  case WINED3D_TOP_ADD:
234  /* Input, arg1*1+arg2*1 */
235  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
237  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
239  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
241  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
243 
244  /* Output */
245  if (op == WINED3D_TOP_ADD)
246  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
248  else if (op == WINED3D_TOP_ADD_SIGNED)
249  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
251  else if (op == WINED3D_TOP_ADD_SIGNED_2X)
252  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
254  break;
255 
257  /* Input, arg1*1+-arg2*1 */
258  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
260  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
262  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
264  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
266 
267  /* Output */
268  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
270  break;
271 
273  /* Input, arg1*1+(1-arg1)*arg2 */
274  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
276  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
278  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
280  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
282 
283  /* Output */
284  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
286  break;
287 
293  {
294  GLenum alpha_src = GL_PRIMARY_COLOR_NV;
296  alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
298  alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
300  alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
302  alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
304  alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
305  else
306  FIXME("Unhandled texture op %s, shouldn't happen.\n", debug_d3dtop(op));
307 
308  /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
309  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
312  {
313  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
315  } else {
316  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
317  alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
318  }
319  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
321  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
322  alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
323 
324  /* Output */
325  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
327  break;
328  }
329 
331  /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
332  if (is_alpha)
333  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEALPHA_ADDCOLOR).\n");
334  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
336  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
338  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
340  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
342 
343  /* Output */
344  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
346  break;
347 
349  /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
350  if (is_alpha)
351  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATECOLOR_ADDALPHA).\n");
352  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
354  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
356  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
358  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
360 
361  /* Output */
362  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
364  break;
365 
367  /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
368  if (is_alpha)
369  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR).\n");
370  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
372  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
374  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
376  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
378 
379  /* Output */
380  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
382  break;
383 
385  /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
386  if (is_alpha)
387  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA).\n");
388  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
390  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
392  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
394  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
396 
397  /* Output */
398  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
400  break;
401 
403  /* Input, arg1 . arg2 */
404  /* FIXME: DX7 uses a different calculation? */
405  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
407  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
409 
410  /* Output */
411  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
413  break;
414 
416  /* Input, arg3*1+arg1*arg2 */
417  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
419  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
421  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
423  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
425 
426  /* Output */
427  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
429  break;
430 
431  case WINED3D_TOP_LERP:
432  /* Input, arg3*arg1+(1-arg3)*arg2 */
433  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
435  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
437  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
439  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
441 
442  /* Output */
443  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
445  break;
446 
449  if (!gl_info->supported[NV_TEXTURE_SHADER])
450  {
451  WARN("BUMPENVMAP requires GL_NV_texture_shader in this codepath\n");
452  break;
453  }
454 
455  /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
456  * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
457  * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
458  * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the
459  * next stage */
460  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
462  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
464  /* Always pass through to CURRENT, ignore temp arg */
465  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
467  break;
468 
469  default:
470  FIXME("Unhandled texture op: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d.\n",
471  stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
472  }
473 
474  checkGLcall("set_tex_op_nvrc()");
475 }
476 
477 
478 static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
479 {
480  DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
481  BOOL tex_used = context->fixed_function_usage_map & (1u << stage);
482  DWORD mapped_stage = context->tex_unit_map[stage];
483  const struct wined3d_gl_info *gl_info = context->gl_info;
484 
485  TRACE("Setting color op for stage %u.\n", stage);
486 
487  /* Using a pixel shader? Don't care for anything here, the shader applying does it */
488  if (use_ps(state)) return;
489 
490  if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
491 
492  if (mapped_stage != WINED3D_UNMAPPED_STAGE)
493  {
494  if (tex_used && mapped_stage >= gl_info->limits.textures)
495  {
496  FIXME("Attempt to enable unsupported stage!\n");
497  return;
498  }
499  context_active_texture(context, gl_info, mapped_stage);
500  }
501 
502  if (context->lowest_disabled_stage > 0)
503  {
504  gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV);
505  GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, context->lowest_disabled_stage));
506  }
507  else
508  {
509  gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV);
510  }
511  if (stage >= context->lowest_disabled_stage)
512  {
513  TRACE("Stage disabled\n");
514  if (mapped_stage != WINED3D_UNMAPPED_STAGE)
515  {
516  /* Disable everything here */
517  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
518  checkGLcall("glDisable(GL_TEXTURE_2D)");
519  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
520  checkGLcall("glDisable(GL_TEXTURE_3D)");
521  if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
522  {
523  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
524  checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
525  }
526  if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
527  {
528  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
529  checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
530  }
531  if (gl_info->supported[NV_TEXTURE_SHADER2] && mapped_stage < gl_info->limits.textures)
532  {
533  gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
534  }
535  }
536  /* All done */
537  return;
538  }
539 
540  /* The sampler will also activate the correct texture dimensions, so no need to do it here
541  * if the sampler for this stage is dirty
542  */
543  if (!isStateDirty(context, STATE_SAMPLER(stage)))
544  {
545  if (tex_used)
546  {
547  if (gl_info->supported[NV_TEXTURE_SHADER2])
548  {
550  }
551  else
552  {
553  texture_activate_dimensions(state->textures[stage], gl_info);
554  }
555  }
556  }
557 
558  /* Set the texture combiners */
559  set_tex_op_nvrc(gl_info, state, FALSE, stage,
560  state->texture_states[stage][WINED3D_TSS_COLOR_OP],
561  state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
562  state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
563  state->texture_states[stage][WINED3D_TSS_COLOR_ARG0],
564  mapped_stage,
565  state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
566 
567  /* In register combiners bump mapping is done in the stage AFTER the one that has the bump map operation set,
568  * thus the texture shader may have to be updated
569  */
570  if (gl_info->supported[NV_TEXTURE_SHADER2])
571  {
572  BOOL usesBump = (state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP_LUMINANCE
573  || state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP);
574  BOOL usedBump = !!(context->texShaderBumpMap & 1u << (stage + 1));
575  if (usesBump != usedBump)
576  {
577  context_active_texture(context, gl_info, mapped_stage + 1);
579  context_active_texture(context, gl_info, mapped_stage);
580  }
581  }
582 }
583 
584 static void nvrc_resultarg(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
585 {
586  DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
587 
588  TRACE("Setting result arg for stage %u.\n", stage);
589 
591  {
593  }
595  {
597  }
598 }
599 
600 static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
601 {
602  DWORD sampler = state_id - STATE_SAMPLER(0);
603  DWORD mapped_stage = context->tex_unit_map[sampler];
604 
605  /* No need to enable / disable anything here for unused samplers. The tex_colorop
606  * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
607  * will take care of this business. */
608  if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
609  return;
610  if (sampler >= context->lowest_disabled_stage)
611  return;
613  return;
614 
616 }
617 
618 static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
619 {
620  DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
621  DWORD mapped_stage = context->tex_unit_map[stage + 1];
622  const struct wined3d_gl_info *gl_info = context->gl_info;
623  float mat[2][2];
624 
625  /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to
626  * offset the destination stage(always stage + 1 in d3d). In GL_NV_texture_shader, the bump
627  * map offsetting is done in the stage reading the bump mapped texture, and the perturbation
628  * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix
629  * for stage + 1. Keep the nvrc tex unit mapping in mind too
630  */
631  if (mapped_stage < gl_info->limits.textures)
632  {
633  context_active_texture(context, gl_info, mapped_stage);
634 
635  /* We can't just pass a pointer to the state to GL due to the
636  * different matrix format (column major vs row major). */
637  mat[0][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT00]);
638  mat[1][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT01]);
639  mat[0][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT10]);
640  mat[1][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT11]);
641  gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float *)mat);
642  checkGLcall("glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat)");
643  }
644 }
645 
646 static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
647 {
648  const struct wined3d_gl_info *gl_info = context->gl_info;
649  struct wined3d_color color;
650 
652  GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &color.r));
653 }
654 
655 /* Context activation is done by the caller. */
656 static void nvrc_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
657 {
658  if (enable)
659  {
660  gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV);
661  checkGLcall("glEnable(GL_REGISTER_COMBINERS_NV)");
662  }
663  else
664  {
665  gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV);
666  checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)");
667  }
668 }
669 
670 /* Context activation is done by the caller. */
671 static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
672 {
673  nvrc_enable(gl_info, enable);
674  if (enable)
675  {
676  gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_SHADER_NV);
677  checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
678  }
679  else
680  {
681  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_SHADER_NV);
682  checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
683  }
684 }
685 
686 static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
687 {
688  caps->wined3d_caps = 0;
690 
691  /* The caps below can be supported but aren't handled yet in utils.c
692  * 'd3dta_to_combiner_input', disable them until support is fixed */
693 #if 0
694  if (gl_info->supported[NV_REGISTER_COMBINERS2])
696 #endif
697 
721 
722  if (gl_info->supported[NV_TEXTURE_SHADER2])
723  {
724  /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
725  * not support 3D textures. This asks for trouble if an app uses both bump mapping
726  * and 3D textures. It also allows us to keep the code simpler by having texture
727  * shaders constantly enabled. */
729  /* TODO: Luminance bump map? */
730  }
731 
732 #if 0
733  /* FIXME: Add
734  caps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
735  WINED3DTEXOPCAPS_PREMODULATE */
736 #endif
737 
738  caps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners);
739  caps->MaxSimultaneousTextures = gl_info->limits.textures;
740 }
741 
742 static DWORD nvrc_fragment_get_emul_mask(const struct wined3d_gl_info *gl_info)
743 {
745 }
746 
747 static void *nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
748 {
749  return shader_priv;
750 }
751 
752 /* Context activation is done by the caller. */
753 static void nvrc_fragment_free(struct wined3d_device *device) {}
754 
755 /* Two fixed function pipeline implementations using GL_NV_register_combiners and
756  * GL_NV_texture_shader. The nvts_fragment_pipeline assumes that both extensions
757  * are available(geforce 3 and newer), while nvrc_fragment_pipeline uses only the
758  * register combiners extension(Pre-GF3).
759  */
760 
762 {
763  /* We only support identity conversions. */
764  return is_identity_fixup(fixup);
765 }
766 
768 {
905  {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
906 };
907 
909 {
910  return TRUE;
911 }
912 
914 {
915 }
916 
917 
919  nvts_enable,
928 };
929 
931  nvrc_enable,
940 };
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
DWORD MaxTextureBlendStages
#define STATE_TEXTURESTAGE(stage, num)
#define MAX_TEXTURES
void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:290
#define TRUE
Definition: types.h:120
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:1112
struct opengl_funcs gl_ops
#define GL_VARIABLE_A_NV
Definition: glext.h:3401
#define WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
Definition: wined3d.h:1165
Definition: http.c:6587
#define WINED3DTA_CONSTANT
Definition: wined3d.h:873
void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit)
Definition: context.c:2717
#define WINED3DTEXOPCAPS_DISABLE
Definition: wined3d.h:1145
#define WINED3DTEXOPCAPS_BLENDCURRENTALPHA
Definition: wined3d.h:1160
#define GL_UNSIGNED_INVERT_NV
Definition: glext.h:3418
#define GL_DISCARD_NV
Definition: glext.h:3414
static void nvrc_fragment_free(struct wined3d_device *device)
#define GL_FALSE
Definition: gl.h:173
#define WINED3DTEXOPCAPS_ADDSIGNED
Definition: wined3d.h:1152
#define GL_ALPHA
Definition: gl.h:483
#define WINED3DTEXOPCAPS_MODULATE
Definition: wined3d.h:1148
#define WARN(fmt,...)
Definition: debug.h:111
#define GL_TEXTURE0_ARB
Definition: gl.h:1966
#define WINED3DTEXOPCAPS_ADDSIGNED2X
Definition: wined3d.h:1153
#define WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
Definition: wined3d.h:1156
static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx)
const struct fragment_pipeline nvrc_fragment_pipeline
#define WINED3DTEXOPCAPS_ADDSMOOTH
Definition: wined3d.h:1155
static const MAT2 mat
Definition: font.c:66
#define WINED3DTA_COMPLEMENT
Definition: wined3d.h:874
#define WINED3DTEXOPCAPS_SELECTARG2
Definition: wined3d.h:1147
#define STATE_SHADER(a)
void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:650
static void nvrc_context_free(struct wined3d_context *context)
void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
Definition: utils.c:6090
#define WINED3DTA_CURRENT
Definition: wined3d.h:868
int32_t INT
Definition: typedefs.h:56
#define WINED3DTEXOPCAPS_LERP
Definition: wined3d.h:1170
static GLenum invert_mapping(GLenum mapping)
#define WINED3DTEXOPCAPS_BLENDFACTORALPHA
Definition: wined3d.h:1158
static void nvrc_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
WINE_DEFAULT_DEBUG_CHANNEL(d3d)
static BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
static DWORD nvrc_fragment_get_emul_mask(const struct wined3d_gl_info *gl_info)
void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:1286
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
#define STATE_COLOR_KEY
GLenum component_usage[3]
#define GL_SCALE_BY_FOUR_NV
Definition: glext.h:3426
#define GL_SPARE0_NV
Definition: glext.h:3412
#define GL_TEXTURE_CUBE_MAP_ARB
Definition: glext.h:1230
#define GL_TEXTURE_RECTANGLE_ARB
Definition: glext.h:1614
#define WINED3DPMISCCAPS_PERSTAGECONSTANT
Definition: wined3d.h:1105
unsigned int BOOL
Definition: ntddk_ex.h:94
static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
GLuint color
Definition: glext.h:6243
#define GL_VARIABLE_D_NV
Definition: glext.h:3404
Definition: devices.h:37
static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
#define WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
Definition: wined3d.h:1164
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
#define GL_ZERO
Definition: gl.h:374
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL supported[WINED3D_GL_EXT_COUNT]
static void context_apply_state(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
#define GL_TEXTURE_3D
Definition: gl.h:1515
smooth NULL
Definition: ftsmooth.c:416
#define WINED3DPMISCCAPS_TSSARGTEMP
Definition: wined3d.h:1101
#define WINED3DTA_TEXTURE
Definition: wined3d.h:869
static const struct StateEntryTemplate nvrc_fragmentstate_template[]
static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
BOOL is_invalid_op(const struct wined3d_state *state, int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
Definition: utils.c:4858
#define GL_NUM_GENERAL_COMBINERS_NV
Definition: glext.h:3441
#define WINED3DTEXOPCAPS_DOTPRODUCT3
Definition: wined3d.h:1168
void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: utils.c:6205
#define WINED3DTA_SELECTMASK
Definition: wined3d.h:866
GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg3
Definition: glext.h:9515
#define GL_OFFSET_TEXTURE_2D_NV
Definition: glext.h:3698
#define GL_EXTCALL(f)
#define WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM
Definition: wined3d.h:1159
#define GL_PRIMARY_COLOR_NV
Definition: glext.h:3410
#define WINED3DTEXOPCAPS_MODULATE4X
Definition: wined3d.h:1150
#define GL_TEXTURE_SHADER_NV
Definition: glext.h:3685
#define TRACE(s)
Definition: solgame.cpp:4
#define GL_SHADER_OPERATION_NV
Definition: glext.h:3686
#define WINED3DTEXOPCAPS_SELECTARG1
Definition: wined3d.h:1146
#define GL_CONSTANT_COLOR0_NV
Definition: glext.h:3408
#define GL_CONSTANT_COLOR1_NV
Definition: glext.h:3409
static void nvrc_resultarg(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
#define WINED3DTA_DIFFUSE
Definition: wined3d.h:867
#define WINED3DTA_SPECULAR
Definition: wined3d.h:871
void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:3756
#define WINED3DTEXOPCAPS_MULTIPLYADD
Definition: wined3d.h:1169
static BOOL is_identity_fixup(struct color_fixup_desc fixup)
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
#define WINED3DTA_TFACTOR
Definition: wined3d.h:870
#define GL_SECONDARY_COLOR_NV
Definition: glext.h:3411
DWORD MaxSimultaneousTextures
#define GL_RGB
Definition: gl.h:502
#define GL_NONE
Definition: gl.h:465
static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum *input, GLenum *mapping, GLenum *component_usage, INT texture_idx)
#define GL_REGISTER_COMBINERS_NV
Definition: glext.h:3400
const struct fragment_pipeline nvts_fragment_pipeline
#define GL_SCALE_BY_TWO_NV
Definition: glext.h:3425
static void * nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
static int state
Definition: maze.c:121
void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:3212
unsigned int GLenum
Definition: gl.h:150
#define WINED3D_UNMAPPED_STAGE
void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:170
GLenum portion
Definition: glext.h:9031
#define GL_SPARE1_NV
Definition: glext.h:3413
static BOOL use_ps(const struct wined3d_state *state)
#define STATE_RENDER(a)
#define STATE_SAMPLER(num)
#define ERR(fmt,...)
Definition: debug.h:109
GLboolean enable
Definition: glext.h:11120
GLenum GLenum GLenum input
Definition: glext.h:9031
#define WINED3DTEXOPCAPS_MODULATE2X
Definition: wined3d.h:1149
static BOOL is_alpha(WCHAR val)
Definition: uri.c:262
#define GL_VARIABLE_C_NV
Definition: glext.h:3403
static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
#define GL_TRUE
Definition: gl.h:174
GLenum GLenum dst
Definition: glext.h:6340
static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup)
#define WINED3D_HIGHEST_TEXTURE_STATE
Definition: wined3d.h:595
#define GL_EXT_EMUL_EXT_FOG_COORD
void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:1296
#define checkGLcall(A)
#define min(a, b)
Definition: monoChain.cc:55
const char * debug_d3dtop(enum wined3d_texture_op d3dtop)
Definition: utils.c:4582
#define GL_COMBINER0_NV
Definition: glext.h:3443
#define GL_OFFSET_TEXTURE_MATRIX_NV
Definition: glext.h:3688
#define GL_EXPAND_NORMAL_NV
Definition: glext.h:3419
#define GL_TEXTURE_2D
Definition: gl.h:645
#define GL_VARIABLE_B_NV
Definition: glext.h:3402
void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, BOOL is_alpha, int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst)
#define WINED3DTEXOPCAPS_SUBTRACT
Definition: wined3d.h:1154
#define WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
Definition: wined3d.h:1163
static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
#define WINED3DTA_ALPHAREPLICATE
Definition: wined3d.h:875
#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV
Definition: glext.h:3428
GLenum target
Definition: glext.h:7315
static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:1128
UINT op
Definition: effect.c:223
#define GL_TEXTURE
Definition: gl.h:247
#define GL_UNSIGNED_IDENTITY_NV
Definition: glext.h:3417
static BOOL nvrc_context_alloc(struct wined3d_context *context)
#define GL_EXT_EMUL_ARB_MULTITEXTURE
struct wined3d_gl_limits limits
#define GL_SIGNED_NEGATE_NV
Definition: glext.h:3424
#define WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
Definition: wined3d.h:1157
#define WINED3DTEXOPCAPS_BUMPENVMAP
Definition: wined3d.h:1166
#define WINED3DTA_TEMP
Definition: wined3d.h:872
static void wined3d_color_from_d3dcolor(struct wined3d_color *wined3d_color, DWORD d3d_color)
#define WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
Definition: wined3d.h:1162
wined3d_texture_op
Definition: wined3d.h:607
static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD stage, struct wined3d_context *context)
#define WINED3DTEXOPCAPS_ADD
Definition: wined3d.h:1151
GLuint sampler
Definition: glext.h:7283