[2/4] wined3d: Move set_glsl_shader_program() to glsl_shader.c
H. Verbeet
hverbeet at gmail.com
Wed Dec 27 20:13:24 CST 2006
This is quite specific to the GLSL shader backend.
Changelog:
- Move set_glsl_shader_program() to glsl_shader.c
-------------- next part --------------
---
dlls/wined3d/device.c | 117 ----------------------------------------
dlls/wined3d/glsl_shader.c | 117 ++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 1
3 files changed, 117 insertions(+), 118 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 14d6d9e..4ebca23 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -251,123 +251,6 @@ static void setup_light(IWineD3DDevice *
* GLSL helper functions follow
**********************************************************/
-/** Attach a GLSL pixel or vertex shader object to the shader program */
-static void attach_glsl_shader(IWineD3DDevice *iface, IWineD3DBaseShader* shader) {
-
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- GLhandleARB shaderObj = ((IWineD3DBaseShaderImpl*)shader)->baseShader.prgId;
- if (This->stateBlock->glsl_program && shaderObj != 0) {
- TRACE_(d3d_shader)("Attaching GLSL shader object %u to program %u\n", shaderObj, This->stateBlock->glsl_program->programId);
- GL_EXTCALL(glAttachObjectARB(This->stateBlock->glsl_program->programId, shaderObj));
- checkGLcall("glAttachObjectARB");
- }
-}
-
-/** Sets the GLSL program ID for the given pixel and vertex shader combination.
- * It sets the programId on the current StateBlock (because it should be called
- * inside of the DrawPrimitive() part of the render loop).
- *
- * If a program for the given combination does not exist, create one, and store
- * the program in the list. If it creates a program, it will link the given
- * objects, too.
- *
- * We keep the shader programs around on a list because linking
- * shader objects together is an expensive operation. It's much
- * faster to loop through a list of pre-compiled & linked programs
- * each time that the application sets a new pixel or vertex shader
- * than it is to re-link them together at that time.
- *
- * The list will be deleted in IWineD3DDevice::Release().
- */
-void set_glsl_shader_program(IWineD3DDevice *iface) {
-
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IWineD3DPixelShader *pshader = This->stateBlock->pixelShader;
- IWineD3DVertexShader *vshader = This->stateBlock->vertexShader;
- struct glsl_shader_prog_link *curLink = NULL;
- struct glsl_shader_prog_link *newLink = NULL;
- struct list *ptr = NULL;
- GLhandleARB programId = 0;
- int i;
- char glsl_name[8];
-
- ptr = list_head( &This->glsl_shader_progs );
- while (ptr) {
- /* At least one program exists - see if it matches our ps/vs combination */
- curLink = LIST_ENTRY( ptr, struct glsl_shader_prog_link, entry );
- if (vshader == curLink->vertexShader && pshader == curLink->pixelShader) {
- /* Existing Program found, use it */
- TRACE_(d3d_shader)("Found existing program (%u) for this vertex/pixel shader combination\n",
- curLink->programId);
- This->stateBlock->glsl_program = curLink;
- return;
- }
- /* This isn't the entry we need - try the next one */
- ptr = list_next( &This->glsl_shader_progs, ptr );
- }
-
- /* If we get to this point, then no matching program exists, so we create one */
- programId = GL_EXTCALL(glCreateProgramObjectARB());
- TRACE_(d3d_shader)("Created new GLSL shader program %u\n", programId);
-
- /* Allocate a new link for the list of programs */
- newLink = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
- newLink->programId = programId;
- This->stateBlock->glsl_program = newLink;
-
- /* Attach GLSL vshader */
- if (NULL != vshader && This->vs_selected_mode == SHADER_GLSL) {
- int i;
- int max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */
- char tmp_name[10];
-
- TRACE("Attaching vertex shader to GLSL program\n");
- attach_glsl_shader(iface, (IWineD3DBaseShader*)vshader);
-
- /* Bind vertex attributes to a corresponding index number to match
- * the same index numbers as ARB_vertex_programs (makes loading
- * vertex attributes simpler). With this method, we can use the
- * exact same code to load the attributes later for both ARB and
- * GLSL shaders.
- *
- * We have to do this here because we need to know the Program ID
- * in order to make the bindings work, and it has to be done prior
- * to linking the GLSL program. */
- for (i = 0; i < max_attribs; ++i) {
- snprintf(tmp_name, sizeof(tmp_name), "attrib%i", i);
- GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
- }
- checkGLcall("glBindAttribLocationARB");
- newLink->vertexShader = vshader;
- }
-
- /* Attach GLSL pshader */
- if (NULL != pshader && This->ps_selected_mode == SHADER_GLSL) {
- TRACE("Attaching pixel shader to GLSL program\n");
- attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader);
- newLink->pixelShader = pshader;
- }
-
- /* Link the program */
- TRACE_(d3d_shader)("Linking GLSL shader program %u\n", programId);
- GL_EXTCALL(glLinkProgramARB(programId));
- print_glsl_info_log(&GLINFO_LOCATION, programId);
- list_add_head( &This->glsl_shader_progs, &newLink->entry);
-
- newLink->vuniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(vshader_constantsF));
- for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
- snprintf(glsl_name, sizeof(glsl_name), "VC[%i]", i);
- newLink->vuniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
- }
- newLink->puniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(pshader_constantsF));
- for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
- snprintf(glsl_name, sizeof(glsl_name), "PC[%i]", i);
- newLink->puniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
- }
-
- return;
-}
-
/** Detach the GLSL pixel or vertex shader object from the shader program */
static void detach_glsl_shader(IWineD3DDevice *iface, GLhandleARB shaderObj, GLhandleARB programId) {
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 17b6a47..fe0bb65 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1879,6 +1879,123 @@ void vshader_glsl_output_unpack(
}
}
+/** Attach a GLSL pixel or vertex shader object to the shader program */
+static void attach_glsl_shader(IWineD3DDevice *iface, IWineD3DBaseShader* shader) {
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(This->wineD3D))->gl_info;
+ GLhandleARB shaderObj = ((IWineD3DBaseShaderImpl*)shader)->baseShader.prgId;
+ if (This->stateBlock->glsl_program && shaderObj != 0) {
+ TRACE("Attaching GLSL shader object %u to program %u\n", shaderObj, This->stateBlock->glsl_program->programId);
+ GL_EXTCALL(glAttachObjectARB(This->stateBlock->glsl_program->programId, shaderObj));
+ checkGLcall("glAttachObjectARB");
+ }
+}
+
+/** Sets the GLSL program ID for the given pixel and vertex shader combination.
+ * It sets the programId on the current StateBlock (because it should be called
+ * inside of the DrawPrimitive() part of the render loop).
+ *
+ * If a program for the given combination does not exist, create one, and store
+ * the program in the list. If it creates a program, it will link the given
+ * objects, too.
+ *
+ * We keep the shader programs around on a list because linking
+ * shader objects together is an expensive operation. It's much
+ * faster to loop through a list of pre-compiled & linked programs
+ * each time that the application sets a new pixel or vertex shader
+ * than it is to re-link them together at that time.
+ *
+ * The list will be deleted in IWineD3DDevice::Release().
+ */
+static void set_glsl_shader_program(IWineD3DDevice *iface) {
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(This->wineD3D))->gl_info;
+ IWineD3DPixelShader *pshader = This->stateBlock->pixelShader;
+ IWineD3DVertexShader *vshader = This->stateBlock->vertexShader;
+ struct glsl_shader_prog_link *curLink = NULL;
+ struct glsl_shader_prog_link *newLink = NULL;
+ struct list *ptr = NULL;
+ GLhandleARB programId = 0;
+ int i;
+ char glsl_name[8];
+
+ ptr = list_head( &This->glsl_shader_progs );
+ while (ptr) {
+ /* At least one program exists - see if it matches our ps/vs combination */
+ curLink = LIST_ENTRY( ptr, struct glsl_shader_prog_link, entry );
+ if (vshader == curLink->vertexShader && pshader == curLink->pixelShader) {
+ /* Existing Program found, use it */
+ TRACE("Found existing program (%u) for this vertex/pixel shader combination\n",
+ curLink->programId);
+ This->stateBlock->glsl_program = curLink;
+ return;
+ }
+ /* This isn't the entry we need - try the next one */
+ ptr = list_next( &This->glsl_shader_progs, ptr );
+ }
+
+ /* If we get to this point, then no matching program exists, so we create one */
+ programId = GL_EXTCALL(glCreateProgramObjectARB());
+ TRACE("Created new GLSL shader program %u\n", programId);
+
+ /* Allocate a new link for the list of programs */
+ newLink = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
+ newLink->programId = programId;
+ This->stateBlock->glsl_program = newLink;
+
+ /* Attach GLSL vshader */
+ if (NULL != vshader && This->vs_selected_mode == SHADER_GLSL) {
+ int i;
+ int max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */
+ char tmp_name[10];
+
+ TRACE("Attaching vertex shader to GLSL program\n");
+ attach_glsl_shader(iface, (IWineD3DBaseShader*)vshader);
+
+ /* Bind vertex attributes to a corresponding index number to match
+ * the same index numbers as ARB_vertex_programs (makes loading
+ * vertex attributes simpler). With this method, we can use the
+ * exact same code to load the attributes later for both ARB and
+ * GLSL shaders.
+ *
+ * We have to do this here because we need to know the Program ID
+ * in order to make the bindings work, and it has to be done prior
+ * to linking the GLSL program. */
+ for (i = 0; i < max_attribs; ++i) {
+ snprintf(tmp_name, sizeof(tmp_name), "attrib%i", i);
+ GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
+ }
+ checkGLcall("glBindAttribLocationARB");
+ newLink->vertexShader = vshader;
+ }
+
+ /* Attach GLSL pshader */
+ if (NULL != pshader && This->ps_selected_mode == SHADER_GLSL) {
+ TRACE("Attaching pixel shader to GLSL program\n");
+ attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader);
+ newLink->pixelShader = pshader;
+ }
+
+ /* Link the program */
+ TRACE("Linking GLSL shader program %u\n", programId);
+ GL_EXTCALL(glLinkProgramARB(programId));
+ print_glsl_info_log(&GLINFO_LOCATION, programId);
+ list_add_head( &This->glsl_shader_progs, &newLink->entry);
+
+ newLink->vuniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(vshader_constantsF));
+ for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
+ snprintf(glsl_name, sizeof(glsl_name), "VC[%i]", i);
+ newLink->vuniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
+ }
+ newLink->puniformF_locations = HeapAlloc(GetProcessHeap(), 0, sizeof(GLhandleARB) * GL_LIMITS(pshader_constantsF));
+ for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
+ snprintf(glsl_name, sizeof(glsl_name), "PC[%i]", i);
+ newLink->puniformF_locations[i] = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
+ }
+
+ return;
+}
+
static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info) {
GLhandleARB program_id;
GLhandleARB vshader_id, pshader_id;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e3af89b..14d1b0e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1587,7 +1587,6 @@ extern void vshader_hw_map2gl(SHADER_OPC
extern void vshader_hw_mnxn(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(
IWineD3DDevice* device,
More information about the wine-patches
mailing list