wined3d: Move constant loading into target-specific files.
- Moves GLSL constant loading code into glsl_shader.c and out of the
over-populated drawprim.c.
- Creates a new file named arb_program_shader.c which will hold code
specific to ARB_vertex_program & ARB_fragment_program.
- Remove the constant loading calls from drawprim.c
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in
index 0df6792..e5982dc 100644
--- a/dlls/wined3d/Makefile.in
+++ b/dlls/wined3d/Makefile.in
@@ -9,6 +9,7 @@
EXTRALIBS = -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
C_SRCS = \
+ arb_program_shader.c \
baseshader.c \
basetexture.c \
cubetexture.c \
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
new file mode 100644
index 0000000..b44ad63
--- /dev/null
+++ b/dlls/wined3d/arb_program_shader.c
@@ -0,0 +1,111 @@
+/*
+ * Pixel and vertex shaders implementation using ARB_vertex_program
+ * and ARB_fragment_program GL extensions.
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2006 Jason Green
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+#define GLINFO_LOCATION (*gl_info)
+
+/********************************************************
+ * ARB_[vertex/fragment]_program helper functions follow
+ ********************************************************/
+
+/**
+ * Loads floating point constants into the currently set ARB_vertex/fragment_program.
+ * When @constants_set == NULL, it will load all the constants.
+ *
+ * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
+ * or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
+ */
+void shader_arb_load_constantsF(
+ WineD3D_GL_Info *gl_info,
+ GLuint target_type,
+ unsigned max_constants,
+ float* constants,
+ BOOL* constants_set) {
+
+ int i;
+
+ for (i=0; i<max_constants; ++i) {
+ if (NULL == constants_set || constants_set[i]) {
+ TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
+ constants[i * sizeof(float) + 0], constants[i * sizeof(float) + 1],
+ constants[i * sizeof(float) + 2], constants[i * sizeof(float) + 3]);
+
+ GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i * sizeof(float)]));
+ checkGLcall("glProgramEnvParameter4fvARB");
+ }
+ }
+}
+
+/**
+ * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
+ *
+ * We only support float constants in ARB at the moment, so don't
+ * worry about the Integers or Booleans
+ */
+void shader_arb_load_constants(
+ IWineD3DStateBlock* iface,
+ char usePixelShader,
+ char useVertexShader) {
+
+ IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+ WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
+
+ if (useVertexShader) {
+ IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
+ IWineD3DVertexDeclarationImpl* vertexDeclaration =
+ (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
+
+ if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
+ /* Load DirectX 8 float constants for vertex shader */
+ shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
+ WINED3D_VSHADER_MAX_CONSTANTS,
+ vertexDeclaration->constants, NULL);
+ }
+
+ /* Load DirectX 9 float constants for vertex shader */
+ shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
+ WINED3D_VSHADER_MAX_CONSTANTS,
+ stateBlock->vertexShaderConstantF,
+ stateBlock->set.vertexShaderConstantsF);
+ }
+
+ if (usePixelShader) {
+
+ /* Load DirectX 9 float constants for pixel shader */
+ shader_arb_load_constantsF(gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
+ stateBlock->pixelShaderConstantF,
+ stateBlock->set.pixelShaderConstantsF);
+ }
+}
+
+/* TODO: Add more ARB_[vertex/fragment]_program specific code here */
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index a042199..65a3df1 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1742,174 +1742,6 @@
#endif
-/**
- * Loads (pixel shader) samplers
- */
-void drawPrimLoadPSamplersGLSL(
- IWineD3DDevice* iface) {
-
- IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
- GLhandleARB programId = This->stateBlock->shaderPrgId;
- GLhandleARB name_loc;
- int i;
- char sampler_name[20];
-
- if (programId == 0) {
- /* No GLSL program set - nothing to do. */
- return;
- }
-
- for (i=0; i< GL_LIMITS(textures); ++i) {
- if (This->stateBlock->textures[i] != NULL) {
- snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
- name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
- if (name_loc != -1) {
- TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
- GL_EXTCALL(glUniform1iARB(name_loc, i));
- checkGLcall("glUniform1iARB");
- }
- }
- }
-}
-
-/**
- * Loads floating point constants (aka uniforms) into the currently set GLSL program.
- * When @constants_set == NULL, it will load all the constants.
- */
-void drawPrimLoadConstantsGLSL_F(IWineD3DDevice* iface,
- unsigned max_constants,
- float* constants,
- BOOL* constants_set,
- char is_pshader) {
-
- IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
- GLhandleARB programId = This->stateBlock->shaderPrgId;
- GLhandleARB tmp_loc;
- int i;
- char tmp_name[7];
-
- if (programId == 0) {
- /* No GLSL program set - nothing to do. */
- return;
- }
-
- for (i=0; i<max_constants; ++i) {
- if (NULL == constants_set || constants_set[i]) {
-
- const char* prefix = is_pshader? "PC":"VC";
-
- TRACE_(d3d_shader)("Loading constants %i: %f, %f, %f, %f\n",
- i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
-
- /* TODO: Benchmark and see if it would be beneficial to store the
- * locations of the constants to avoid looking up each time */
- snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
- tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
- if (tmp_loc != -1) {
- /* We found this uniform name in the program - go ahead and send the data */
- GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i*4]));
- checkGLcall("glUniform4fvARB");
- }
- }
- }
-}
-
-/**
- * Loads floating point constants into the currently set ARB_vertex/fragment_program.
- * When @constants_set == NULL, it will load all the constants.
- *
- * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
- * or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
- */
-void drawPrimLoadConstantsARB_F(IWineD3DDevice* iface,
- GLuint target_type,
- unsigned max_constants,
- float* constants,
- BOOL* constants_set) {
-
- IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
- int i;
-
- for (i=0; i<max_constants; ++i) {
- if (NULL == constants_set || constants_set[i]) {
- TRACE_(d3d_shader)("Loading constants %i: %f, %f, %f, %f\n",
- i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
-
- GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i*4]));
- checkGLcall("glProgramEnvParameter4fvARB");
- }
- }
-}
-
-/* Load the constants/uniforms which were passed by the application into either GLSL or ARB shader programs. */
-void drawPrimLoadConstants(IWineD3DDevice *iface,
- BOOL useVertexShader,
- BOOL usePixelShader) {
-
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) This->stateBlock->vertexShader;
-
- if (wined3d_settings.shader_mode == SHADER_GLSL) {
-
- if (useVertexShader) {
- IWineD3DVertexDeclarationImpl* vertexDeclaration =
- (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
-
- if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
- /* Load DirectX 8 float constants/uniforms for vertex shader */
- drawPrimLoadConstantsGLSL_F(iface, WINED3D_VSHADER_MAX_CONSTANTS,
- vertexDeclaration->constants, NULL, 0);
- }
-
- /* Load DirectX 9 float constants/uniforms for vertex shader */
- drawPrimLoadConstantsGLSL_F(iface, WINED3D_VSHADER_MAX_CONSTANTS,
- This->stateBlock->vertexShaderConstantF,
- This->stateBlock->set.vertexShaderConstantsF, 0);
-
- /* TODO: Load boolean & integer constants for vertex shader */
- }
- if (usePixelShader) {
-
- /* Load pixel shader samplers */
- drawPrimLoadPSamplersGLSL(iface);
-
- /* Load DirectX 9 float constants/uniforms for pixel shader */
- drawPrimLoadConstantsGLSL_F(iface, WINED3D_PSHADER_MAX_CONSTANTS,
- This->stateBlock->pixelShaderConstantF,
- This->stateBlock->set.pixelShaderConstantsF, 1);
-
- /* TODO: Load boolean & integer constants for pixel shader */
- }
- } else if (wined3d_settings.shader_mode == SHADER_ARB) {
-
- /* We only support float constants in ARB at the moment, so don't
- * worry about the Integers or Booleans */
-
- if (useVertexShader) {
- IWineD3DVertexDeclarationImpl* vertexDeclaration =
- (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
-
- if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
- /* Load DirectX 8 float constants for vertex shader */
- drawPrimLoadConstantsARB_F(iface, GL_VERTEX_PROGRAM_ARB, WINED3D_VSHADER_MAX_CONSTANTS,
- vertexDeclaration->constants, NULL);
- }
-
- /* Load DirectX 9 float constants for vertex shader */
- drawPrimLoadConstantsARB_F(iface, GL_VERTEX_PROGRAM_ARB, WINED3D_VSHADER_MAX_CONSTANTS,
- This->stateBlock->vertexShaderConstantF,
- This->stateBlock->set.vertexShaderConstantsF);
- }
- if (usePixelShader) {
-
- /* Load DirectX 9 float constants for pixel shader */
- drawPrimLoadConstantsARB_F(iface, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
- This->stateBlock->pixelShaderConstantF,
- This->stateBlock->set.pixelShaderConstantsF);
- }
- }
-}
-
void inline drawPrimitiveDrawStrided(IWineD3DDevice *iface, BOOL useVertexShaderFunction, BOOL usePixelShaderFunction, int useHW, WineDirect3DVertexStridedData *dataLocations,
UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idxData, short idxSize, int minIndex, long StartIdx) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@@ -2055,7 +1887,11 @@
}
/* Load any global constants/uniforms that may have been set by the application */
- drawPrimLoadConstants(iface, useVertexShaderFunction, usePixelShaderFunction);
+ if (wined3d_settings.shader_mode == SHADER_GLSL)
+ shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
+ else if (wined3d_settings.shader_mode == SHADER_ARB)
+ shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
+
/* DirectX colours are in a different format to opengl colours
* so if diffuse or specular are used then we need to use drawStridedSlow
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 54e311d..f409393 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -47,6 +47,119 @@
}
}
+/**
+ * Loads (pixel shader) samplers
+ */
+void shader_glsl_load_psamplers(
+ WineD3D_GL_Info *gl_info,
+ IWineD3DStateBlock* iface) {
+
+ IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+ GLhandleARB programId = stateBlock->shaderPrgId;
+ GLhandleARB name_loc;
+ int i;
+ char sampler_name[20];
+
+ for (i=0; i< GL_LIMITS(textures); ++i) {
+ if (stateBlock->textures[i] != NULL) {
+ snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
+ name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
+ if (name_loc != -1) {
+ TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
+ GL_EXTCALL(glUniform1iARB(name_loc, i));
+ checkGLcall("glUniform1iARB");
+ }
+ }
+ }
+}
+
+/**
+ * Loads floating point constants (aka uniforms) into the currently set GLSL program.
+ * When @constants_set == NULL, it will load all the constants.
+ */
+void shader_glsl_load_constantsF(
+ WineD3D_GL_Info *gl_info,
+ GLhandleARB programId,
+ unsigned max_constants,
+ float* constants,
+ BOOL* constants_set,
+ char is_pshader) {
+
+ GLhandleARB tmp_loc;
+ int i;
+ char tmp_name[7];
+ const char* prefix = is_pshader? "PC":"VC";
+
+ for (i=0; i<max_constants; ++i) {
+ if (NULL == constants_set || constants_set[i]) {
+
+ TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
+ constants[i * sizeof(float) + 0], constants[i * sizeof(float) + 1],
+ constants[i * sizeof(float) + 2], constants[i * sizeof(float) + 3]);
+
+ /* TODO: Benchmark and see if it would be beneficial to store the
+ * locations of the constants to avoid looking up each time */
+ snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
+ tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+ if (tmp_loc != -1) {
+ /* We found this uniform name in the program - go ahead and send the data */
+ GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i * sizeof(float)]));
+ checkGLcall("glUniform4fvARB");
+ }
+ }
+ }
+}
+
+/**
+ * Loads the app-supplied constants into the currently set GLSL program.
+ */
+void shader_glsl_load_constants(
+ IWineD3DStateBlock* iface,
+ char usePixelShader,
+ char useVertexShader) {
+
+ IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
+ WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
+ GLhandleARB programId = stateBlock->shaderPrgId;
+
+ if (programId == 0) {
+ /* No GLSL program set - nothing to do. */
+ return;
+ }
+
+ if (useVertexShader) {
+ IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
+ IWineD3DVertexDeclarationImpl* vertexDeclaration =
+ (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
+
+ if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
+ /* Load DirectX 8 float constants/uniforms for vertex shader */
+ shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
+ vertexDeclaration->constants, NULL, 0);
+ }
+
+ /* Load DirectX 9 float constants/uniforms for vertex shader */
+ shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
+ stateBlock->vertexShaderConstantF,
+ stateBlock->set.vertexShaderConstantsF, 0);
+
+ /* TODO: Load boolean & integer constants for vertex shader */
+ }
+
+ if (usePixelShader) {
+
+ /* Load pixel shader samplers */
+ shader_glsl_load_psamplers(gl_info, iface);
+
+ /* Load DirectX 9 float constants/uniforms for pixel shader */
+ shader_glsl_load_constantsF(gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
+ stateBlock->pixelShaderConstantF,
+ stateBlock->set.pixelShaderConstantsF, 1);
+
+ /* TODO: Load boolean & integer constants for pixel shader */
+ }
+}
+
/*****************************************************************************
* Functions to generate GLSL strings from DirectX Shader bytecode begin here.
*
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index cd7cfa0..10accc6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1344,12 +1344,22 @@
IWineD3DBaseShader *iface,
const DWORD code);
+/* ARB_[vertex/fragment]_program helper functions */
+extern void shader_arb_load_constants(
+ IWineD3DStateBlock* iface,
+ char usePixelShader,
+ char useVertexShader);
+
/* ARB shader program Prototypes */
extern void shader_hw_def(SHADER_OPCODE_ARG *arg);
/* GLSL helper functions */
extern void set_glsl_shader_program(IWineD3DDevice *iface);
extern void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG *arg);
+extern void shader_glsl_load_constants(
+ IWineD3DStateBlock* iface,
+ char usePixelShader,
+ char useVertexShader);
/** The following translate DirectX pixel/vertex shader opcodes to GLSL lines */
extern void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg);