ReactOS  0.4.13-dev-563-g0561610
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  default:
73  FIXME("Unhandled target %#x.\n", state->textures[stage]->target);
74  break;
75  }
76  }
77  else
78  {
79  gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
80  checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
81  }
82 }
83 
85 {
89 };
90 
91 static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
92  switch (d3dta) {
93  case WINED3DTA_DIFFUSE:
94  return GL_PRIMARY_COLOR_NV;
95 
96  case WINED3DTA_CURRENT:
97  if (stage) return GL_SPARE0_NV;
98  else return GL_PRIMARY_COLOR_NV;
99 
100  case WINED3DTA_TEXTURE:
101  if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
102  else return GL_PRIMARY_COLOR_NV;
103 
104  case WINED3DTA_TFACTOR:
105  return GL_CONSTANT_COLOR0_NV;
106 
107  case WINED3DTA_SPECULAR:
108  return GL_SECONDARY_COLOR_NV;
109 
110  case WINED3DTA_TEMP:
111  return GL_SPARE1_NV;
112 
113  case WINED3DTA_CONSTANT:
114  /* TODO: Support per stage constants (WINED3D_TSS_CONSTANT, NV_register_combiners2) */
115  FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
116  return GL_CONSTANT_COLOR1_NV;
117 
118  default:
119  FIXME("Unrecognized texture arg %#x\n", d3dta);
120  return GL_TEXTURE;
121  }
122 }
123 
127 
128  FIXME("Unhandled mapping %#x\n", mapping);
129  return mapping;
130 }
131 
132 static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
133  /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
134  * be used. */
136  else *mapping = GL_UNSIGNED_IDENTITY_NV; /* Clamp all values to positive ranges */
137 
138  /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
139  * should be used for all input components. */
140  if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
141  else *component_usage = GL_RGB;
142 
143  *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
144 }
145 
146 void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, BOOL is_alpha,
147  int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst)
148 {
149  struct tex_op_args tex_op_args = {{0}, {0}, {0}};
151  GLenum target = GL_COMBINER0_NV + stage;
152  GLenum output;
153 
154  TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
155  stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
156 
157  /* If a texture stage references an invalid texture unit the stage just
158  * passes through the result from the previous stage */
159  if (is_invalid_op(state, stage, op, arg1, arg2, arg3))
160  {
163  }
164 
166  &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
168  &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
170  &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
171 
172 
173  if(dst == WINED3DTA_TEMP) {
175  } else {
177  }
178 
179  switch (op)
180  {
181  case WINED3D_TOP_DISABLE:
182  /* Only for alpha */
183  if (!is_alpha)
184  ERR("Shouldn't be called for WINED3D_TSS_COLOR_OP (WINED3DTOP_DISABLE).\n");
185  /* Input, prev_alpha*1 */
186  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
188  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
190 
191  /* Output */
192  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
194  break;
195 
198  /* Input, arg*1 */
200  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
202  else
203  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
205  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
207 
208  /* Output */
209  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
211  break;
212 
216  /* Input, arg1*arg2 */
217  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
219  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
221 
222  /* Output */
223  if (op == WINED3D_TOP_MODULATE)
224  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
226  else if (op == WINED3D_TOP_MODULATE_2X)
227  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
229  else if (op == WINED3D_TOP_MODULATE_4X)
230  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
232  break;
233 
234  case WINED3D_TOP_ADD:
237  /* Input, arg1*1+arg2*1 */
238  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
240  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
242  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
244  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
246 
247  /* Output */
248  if (op == WINED3D_TOP_ADD)
249  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
251  else if (op == WINED3D_TOP_ADD_SIGNED)
252  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
254  else if (op == WINED3D_TOP_ADD_SIGNED_2X)
255  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
257  break;
258 
260  /* Input, arg1*1+-arg2*1 */
261  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
263  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
265  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
267  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
269 
270  /* Output */
271  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
273  break;
274 
276  /* Input, arg1*1+(1-arg1)*arg2 */
277  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
279  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
281  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
283  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
285 
286  /* Output */
287  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
289  break;
290 
296  {
297  GLenum alpha_src = GL_PRIMARY_COLOR_NV;
299  alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
301  alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
303  alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
305  alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
307  alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
308  else
309  FIXME("Unhandled texture op %s, shouldn't happen.\n", debug_d3dtop(op));
310 
311  /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
312  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
315  {
316  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
318  } else {
319  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
320  alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
321  }
322  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
324  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
325  alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
326 
327  /* Output */
328  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
330  break;
331  }
332 
334  /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
335  if (is_alpha)
336  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEALPHA_ADDCOLOR).\n");
337  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
339  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
341  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
343  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
345 
346  /* Output */
347  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
349  break;
350 
352  /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
353  if (is_alpha)
354  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATECOLOR_ADDALPHA).\n");
355  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
357  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
359  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
361  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
363 
364  /* Output */
365  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
367  break;
368 
370  /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
371  if (is_alpha)
372  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR).\n");
373  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
375  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
377  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
379  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
381 
382  /* Output */
383  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
385  break;
386 
388  /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
389  if (is_alpha)
390  ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA).\n");
391  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
393  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
395  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
397  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
399 
400  /* Output */
401  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
403  break;
404 
406  /* Input, arg1 . arg2 */
407  /* FIXME: DX7 uses a different calculation? */
408  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
410  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
412 
413  /* Output */
414  GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
416  break;
417 
419  /* Input, arg3*1+arg1*arg2 */
420  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
422  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
424  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
426  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
428 
429  /* Output */
430  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
432  break;
433 
434  case WINED3D_TOP_LERP:
435  /* Input, arg3*arg1+(1-arg3)*arg2 */
436  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
438  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
440  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
442  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
444 
445  /* Output */
446  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
448  break;
449 
452  if (!gl_info->supported[NV_TEXTURE_SHADER])
453  {
454  WARN("BUMPENVMAP requires GL_NV_texture_shader in this codepath\n");
455  break;
456  }
457 
458  /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
459  * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
460  * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
461  * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the
462  * next stage */
463  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
465  GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
467  /* Always pass through to CURRENT, ignore temp arg */
468  GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
470  break;
471 
472  default:
473  FIXME("Unhandled texture op: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d.\n",
474  stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
475  }
476 
477  checkGLcall("set_tex_op_nvrc()");
478 }
479 
480 
481 static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
482 {
483  DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
484  BOOL tex_used = context->fixed_function_usage_map & (1u << stage);
485  DWORD mapped_stage = context->tex_unit_map[stage];
486  const struct wined3d_gl_info *gl_info = context->gl_info;
487 
488  TRACE("Setting color op for stage %u.\n", stage);
489 
490  /* Using a pixel shader? Don't care for anything here, the shader applying does it */
491  if (use_ps(state)) return;
492 
493  if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
494 
495  if (mapped_stage != WINED3D_UNMAPPED_STAGE)
496  {
497  if (tex_used && mapped_stage >= gl_info->limits.textures)
498  {
499  FIXME("Attempt to enable unsupported stage!\n");
500  return;
501  }
502  context_active_texture(context, gl_info, mapped_stage);
503  }
504 
505  if (context->lowest_disabled_stage > 0)
506  {
507  gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV);
508  GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, context->lowest_disabled_stage));
509  }
510  else
511  {
512  gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV);
513  }
514  if (stage >= context->lowest_disabled_stage)
515  {
516  TRACE("Stage disabled\n");
517  if (mapped_stage != WINED3D_UNMAPPED_STAGE)
518  {
519  /* Disable everything here */
520  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
521  checkGLcall("glDisable(GL_TEXTURE_2D)");
522  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
523  checkGLcall("glDisable(GL_TEXTURE_3D)");
524  if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
525  {
526  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
527  checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
528  }
529  if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
530  {
531  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
532  checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
533  }
534  if (gl_info->supported[NV_TEXTURE_SHADER2] && mapped_stage < gl_info->limits.textures)
535  {
536  gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
537  }
538  }
539  /* All done */
540  return;
541  }
542 
543  /* The sampler will also activate the correct texture dimensions, so no need to do it here
544  * if the sampler for this stage is dirty
545  */
546  if (!isStateDirty(context, STATE_SAMPLER(stage)))
547  {
548  if (tex_used)
549  {
550  if (gl_info->supported[NV_TEXTURE_SHADER2])
551  {
553  }
554  else
555  {
556  texture_activate_dimensions(state->textures[stage], gl_info);
557  }
558  }
559  }
560 
561  /* Set the texture combiners */
562  set_tex_op_nvrc(gl_info, state, FALSE, stage,
563  state->texture_states[stage][WINED3D_TSS_COLOR_OP],
564  state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
565  state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
566  state->texture_states[stage][WINED3D_TSS_COLOR_ARG0],
567  mapped_stage,
568  state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
569 
570  /* In register combiners bump mapping is done in the stage AFTER the one that has the bump map operation set,
571  * thus the texture shader may have to be updated
572  */
573  if (gl_info->supported[NV_TEXTURE_SHADER2])
574  {
575  BOOL usesBump = (state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP_LUMINANCE
576  || state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP);
577  BOOL usedBump = !!(context->texShaderBumpMap & 1u << (stage + 1));
578  if (usesBump != usedBump)
579  {
580  context_active_texture(context, gl_info, mapped_stage + 1);
582  context_active_texture(context, gl_info, mapped_stage);
583  }
584  }
585 }
586 
587 static void nvrc_resultarg(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
588 {
589  DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
590 
591  TRACE("Setting result arg for stage %u.\n", stage);
592 
594  {
596  }
598  {
600  }
601 }
602 
603 static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
604 {
605  DWORD sampler = state_id - STATE_SAMPLER(0);
606  DWORD mapped_stage = context->tex_unit_map[sampler];
607 
608  /* No need to enable / disable anything here for unused samplers. The tex_colorop
609  * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
610  * will take care of this business. */
611  if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
612  return;
613  if (sampler >= context->lowest_disabled_stage)
614  return;
616  return;
617 
619 }
620 
621 static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
622 {
623  DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
624  DWORD mapped_stage = context->tex_unit_map[stage + 1];
625  const struct wined3d_gl_info *gl_info = context->gl_info;
626  float mat[2][2];
627 
628  /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to
629  * offset the destination stage(always stage + 1 in d3d). In GL_NV_texture_shader, the bump
630  * map offsetting is done in the stage reading the bump mapped texture, and the perturbation
631  * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix
632  * for stage + 1. Keep the nvrc tex unit mapping in mind too
633  */
634  if (mapped_stage < gl_info->limits.textures)
635  {
636  context_active_texture(context, gl_info, mapped_stage);
637 
638  /* We can't just pass a pointer to the state to GL due to the
639  * different matrix format (column major vs row major). */
640  mat[0][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT00]);
641  mat[1][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT01]);
642  mat[0][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT10]);
643  mat[1][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT11]);
644  gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float *)mat);
645  checkGLcall("glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat)");
646  }
647 }
648 
649 static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
650 {
651  const struct wined3d_gl_info *gl_info = context->gl_info;
652  struct wined3d_color color;
653 
655  GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &color.r));
656 }
657 
658 /* Context activation is done by the caller. */
659 static void nvrc_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
660 {
661  if (enable)
662  {
663  gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV);
664  checkGLcall("glEnable(GL_REGISTER_COMBINERS_NV)");
665  }
666  else
667  {
668  gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV);
669  checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)");
670  }
671 }
672 
673 /* Context activation is done by the caller. */
674 static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
675 {
676  nvrc_enable(gl_info, enable);
677  if (enable)
678  {
679  gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_SHADER_NV);
680  checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
681  }
682  else
683  {
684  gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_SHADER_NV);
685  checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
686  }
687 }
688 
689 static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
690 {
691  caps->wined3d_caps = 0;
693 
694  /* The caps below can be supported but aren't handled yet in utils.c
695  * 'd3dta_to_combiner_input', disable them until support is fixed */
696 #if 0
697  if (gl_info->supported[NV_REGISTER_COMBINERS2])
699 #endif
700 
724 
725  if (gl_info->supported[NV_TEXTURE_SHADER2])
726  {
727  /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
728  * not support 3D textures. This asks for trouble if an app uses both bump mapping
729  * and 3D textures. It also allows us to keep the code simpler by having texture
730  * shaders constantly enabled. */
732  /* TODO: Luminance bump map? */
733  }
734 
735 #if 0
736  /* FIXME: Add
737  caps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
738  WINED3DTEXOPCAPS_PREMODULATE */
739 #endif
740 
741  caps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners);
742  caps->MaxSimultaneousTextures = gl_info->limits.textures;
743 }
744 
745 static DWORD nvrc_fragment_get_emul_mask(const struct wined3d_gl_info *gl_info)
746 {
748 }
749 
750 static void *nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
751 {
752  return shader_priv;
753 }
754 
755 /* Context activation is done by the caller. */
756 static void nvrc_fragment_free(struct wined3d_device *device) {}
757 
758 /* Two fixed function pipeline implementations using GL_NV_register_combiners and
759  * GL_NV_texture_shader. The nvts_fragment_pipeline assumes that both extensions
760  * are available(geforce 3 and newer), while nvrc_fragment_pipeline uses only the
761  * register combiners extension(Pre-GF3).
762  */
763 
765 {
766  /* We only support identity conversions. */
767  return is_identity_fixup(fixup);
768 }
769 
771 {
908  {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
909 };
910 
912 {
913  return TRUE;
914 }
915 
917 {
918 }
919 
920 
922  nvts_enable,
931 };
932 
934  nvrc_enable,
943 };
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:289
#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:1111
struct opengl_funcs gl_ops
#define GL_VARIABLE_A_NV
Definition: glext.h:3401
#define WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
Definition: wined3d.h:1167
Definition: http.c:6587
#define WINED3DTA_CONSTANT
Definition: wined3d.h:882
void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit)
Definition: context.c:2486
#define WINED3DTEXOPCAPS_DISABLE
Definition: wined3d.h:1147
#define WINED3DTEXOPCAPS_BLENDCURRENTALPHA
Definition: wined3d.h:1162
#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:1154
#define GL_ALPHA
Definition: gl.h:483
#define WINED3DTEXOPCAPS_MODULATE
Definition: wined3d.h:1150
#define WARN(fmt,...)
Definition: debug.h:111
#define GL_TEXTURE0_ARB
Definition: gl.h:1966
#define WINED3DTEXOPCAPS_ADDSIGNED2X
Definition: wined3d.h:1155
#define WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
Definition: wined3d.h:1158
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:1157
static const MAT2 mat
Definition: font.c:66
#define WINED3DTA_COMPLEMENT
Definition: wined3d.h:883
#define WINED3DTEXOPCAPS_SELECTARG2
Definition: wined3d.h:1149
#define STATE_SHADER(a)
void state_alpha_test(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:649
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:6035
#define WINED3DTA_CURRENT
Definition: wined3d.h:877
int32_t INT
Definition: typedefs.h:56
#define WINED3DTEXOPCAPS_LERP
Definition: wined3d.h:1172
static GLenum invert_mapping(GLenum mapping)
#define WINED3DTEXOPCAPS_BLENDFACTORALPHA
Definition: wined3d.h:1160
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:1285
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:1107
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:1166
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:1103
#define WINED3DTA_TEXTURE
Definition: wined3d.h:878
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:4806
#define GL_NUM_GENERAL_COMBINERS_NV
Definition: glext.h:3441
#define WINED3DTEXOPCAPS_DOTPRODUCT3
Definition: wined3d.h:1170
void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: utils.c:6122
#define WINED3DTA_SELECTMASK
Definition: wined3d.h:875
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:1161
#define GL_PRIMARY_COLOR_NV
Definition: glext.h:3410
#define WINED3DTEXOPCAPS_MODULATE4X
Definition: wined3d.h:1152
#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:1148
#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:876
#define WINED3DTA_SPECULAR
Definition: wined3d.h:880
void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Definition: state.c:3663
#define WINED3DTEXOPCAPS_MULTIPLYADD
Definition: wined3d.h:1171
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:879
#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:3189
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:169
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:1151
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:604
#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:1295
#define checkGLcall(A)
#define min(a, b)
Definition: monoChain.cc:55
const char * debug_d3dtop(enum wined3d_texture_op d3dtop)
Definition: utils.c:4530
#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:1156
#define WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
Definition: wined3d.h:1165
static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
#define WINED3DTA_ALPHAREPLICATE
Definition: wined3d.h:884
#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:1127
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:1159
#define WINED3DTEXOPCAPS_BUMPENVMAP
Definition: wined3d.h:1168
#define WINED3DTA_TEMP
Definition: wined3d.h:881
static void wined3d_color_from_d3dcolor(struct wined3d_color *wined3d_color, DWORD d3d_color)
#define WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
Definition: wined3d.h:1164
wined3d_texture_op
Definition: wined3d.h:616
static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD stage, struct wined3d_context *context)
#define WINED3DTEXOPCAPS_ADD
Definition: wined3d.h:1153
GLuint sampler
Definition: glext.h:7283