Commit 09eb0c40 authored by H. Verbeet's avatar H. Verbeet Committed by Alexandre Julliard

wined3d: Improve float constant loading a bit.

- Use a list to keep track of what constants are set. - Move TRACEs and checkGLcall calls out of the main constant loading loop.
parent 49f4c68e
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright 2005 Oliver Stieber * Copyright 2005 Oliver Stieber
* Copyright 2006 Ivan Gyurdiev * Copyright 2006 Ivan Gyurdiev
* Copyright 2006 Jason Green * Copyright 2006 Jason Green
* Copyright 2006 Henri Verbeet
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -41,48 +42,57 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); ...@@ -41,48 +42,57 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
/** /**
* Loads floating point constants into the currently set ARB_vertex/fragment_program. * Loads floating point constants into the currently set ARB_vertex/fragment_program.
* When @constants_set == NULL, it will load all the constants. * When constant_list == NULL, it will load all the constants.
* *
* @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders) * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
* or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders) * or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
*/ */
void shader_arb_load_constantsF( static void shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info, GLuint target_type,
IWineD3DBaseShaderImpl* This, unsigned int max_constants, float* constants, struct list *constant_list) {
WineD3D_GL_Info *gl_info, constant_entry *constant;
GLuint target_type, local_constant* lconst;
unsigned max_constants,
float* constants,
BOOL* constants_set) {
int i; int i;
struct list* ptr;
if (!constant_list) {
for (i=0; i<max_constants; ++i) { if (TRACE_ON(d3d_shader)) {
if (NULL == constants_set || constants_set[i]) { for (i = 0; i < max_constants; ++i) {
TRACE("Loading constants %i: %f, %f, %f, %f\n", i, TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
constants[i * 4 + 0], constants[i * 4 + 1], constants[i * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]); constants[i * 4 + 2], constants[i * 4 + 3]);
}
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i * 4])); }
checkGLcall("glProgramEnvParameter4fvARB"); for (i = 0; i < max_constants; ++i) {
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
}
checkGLcall("glProgramEnvParameter4fvARB()");
} else {
if (TRACE_ON(d3d_shader)) {
LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
i = constant->idx;
TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
constants[i * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
}
} }
LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
i = constant->idx;
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
}
checkGLcall("glProgramEnvParameter4fvARB()");
} }
/* Load immediate constants */ /* Load immediate constants */
ptr = list_head(&This->baseShader.constantsF); if (TRACE_ON(d3d_shader)) {
while (ptr) { LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
GLfloat* values = (GLfloat*)lconst->value;
local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry); TRACE("Loading local constants %i: %f, %f, %f, %f\n", lconst->idx,
unsigned int idx = lconst->idx; values[0], values[1], values[2], values[3]);
GLfloat* values = (GLfloat*) lconst->value; }
}
TRACE("Loading local constants %i: %f, %f, %f, %f\n", idx, LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
values[0], values[1], values[2], values[3]); GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, lconst->idx, (GLfloat*)lconst->value));
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, idx, values));
checkGLcall("glProgramEnvParameter4fvARB");
ptr = list_next(&This->baseShader.constantsF, ptr);
} }
checkGLcall("glProgramEnvParameter4fvARB()");
} }
/** /**
...@@ -116,7 +126,7 @@ void shader_arb_load_constants( ...@@ -116,7 +126,7 @@ void shader_arb_load_constants(
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB, shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
GL_LIMITS(vshader_constantsF), GL_LIMITS(vshader_constantsF),
stateBlock->vertexShaderConstantF, stateBlock->vertexShaderConstantF,
stateBlock->set.vertexShaderConstantsF); &stateBlock->set_vconstantsF);
} }
if (usePixelShader) { if (usePixelShader) {
...@@ -127,7 +137,7 @@ void shader_arb_load_constants( ...@@ -127,7 +137,7 @@ void shader_arb_load_constants(
shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
GL_LIMITS(pshader_constantsF), GL_LIMITS(pshader_constantsF),
stateBlock->pixelShaderConstantF, stateBlock->pixelShaderConstantF,
stateBlock->set.pixelShaderConstantsF); &stateBlock->set_pconstantsF);
} }
} }
......
...@@ -4882,8 +4882,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF( ...@@ -4882,8 +4882,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(
srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]); srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
for (i = start; i < cnt + start; ++i) { for (i = start; i < cnt + start; ++i) {
if (!This->updateStateBlock->set.vertexShaderConstantsF[i]) {
constant_entry *ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(constant_entry));
ptr->idx = i;
list_add_head(&This->updateStateBlock->set_vconstantsF, &ptr->entry);
This->updateStateBlock->set.vertexShaderConstantsF[i] = TRUE;
}
This->updateStateBlock->changed.vertexShaderConstantsF[i] = TRUE; This->updateStateBlock->changed.vertexShaderConstantsF[i] = TRUE;
This->updateStateBlock->set.vertexShaderConstantsF[i] = TRUE;
} }
return WINED3D_OK; return WINED3D_OK;
...@@ -5064,8 +5069,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF( ...@@ -5064,8 +5069,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(
srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]); srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
for (i = start; i < cnt + start; ++i) { for (i = start; i < cnt + start; ++i) {
if (!This->updateStateBlock->set.pixelShaderConstantsF[i]) {
constant_entry *ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(constant_entry));
ptr->idx = i;
list_add_head(&This->updateStateBlock->set_pconstantsF, &ptr->entry);
This->updateStateBlock->set.pixelShaderConstantsF[i] = TRUE;
}
This->updateStateBlock->changed.pixelShaderConstantsF[i] = TRUE; This->updateStateBlock->changed.pixelShaderConstantsF[i] = TRUE;
This->updateStateBlock->set.pixelShaderConstantsF[i] = TRUE;
} }
return WINED3D_OK; return WINED3D_OK;
......
...@@ -76,49 +76,77 @@ void shader_glsl_load_psamplers( ...@@ -76,49 +76,77 @@ void shader_glsl_load_psamplers(
/** /**
* Loads floating point constants (aka uniforms) into the currently set GLSL program. * Loads floating point constants (aka uniforms) into the currently set GLSL program.
* When @constants_set == NULL, it will load all the constants. * When constant_list == NULL, it will load all the constants.
*/ */
void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info, static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info,
unsigned int max_constants, float* constants, GLhandleARB *constant_locations, unsigned int max_constants, float* constants, GLhandleARB *constant_locations,
BOOL* constants_set) { struct list *constant_list) {
local_constant* lconst;
GLhandleARB tmp_loc; GLhandleARB tmp_loc;
int i; int i;
struct list* ptr;
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 * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
if (!constant_list) {
if (TRACE_ON(d3d_shader)) {
for (i = 0; i < max_constants; ++i) {
tmp_loc = constant_locations[i];
if (tmp_loc != -1) {
TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
constants[i * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
}
}
}
for (i = 0; i < max_constants; ++i) {
tmp_loc = constant_locations[i];
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()");
} else {
constant_entry *constant;
if (TRACE_ON(d3d_shader)) {
LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
i = constant->idx;
tmp_loc = constant_locations[i];
if (tmp_loc != -1) {
TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
constants[i * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
}
}
}
LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
i = constant->idx;
tmp_loc = constant_locations[i]; tmp_loc = constant_locations[i];
if (tmp_loc != -1) { if (tmp_loc != -1) {
/* We found this uniform name in the program - go ahead and send the data */ /* We found this uniform name in the program - go ahead and send the data */
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i * 4])); GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, constants + (i * 4)));
checkGLcall("glUniform4fvARB");
} }
} }
checkGLcall("glUniform4fvARB()");
} }
/* Load immediate constants */ /* Load immediate constants */
ptr = list_head(&This->baseShader.constantsF); if (TRACE_ON(d3d_shader)) {
while (ptr) { LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry); tmp_loc = constant_locations[lconst->idx];
unsigned int idx = lconst->idx; if (tmp_loc != -1) {
GLfloat* values = (GLfloat*) lconst->value; GLfloat* values = (GLfloat*)lconst->value;
TRACE("Loading local constants %i: %f, %f, %f, %f\n", lconst->idx,
TRACE("Loading local constants %i: %f, %f, %f, %f\n", idx, values[0], values[1], values[2], values[3]);
values[0], values[1], values[2], values[3]); }
}
tmp_loc = constant_locations[idx]; }
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
tmp_loc = constant_locations[lconst->idx];
if (tmp_loc != -1) { if (tmp_loc != -1) {
/* We found this uniform name in the program - go ahead and send the data */ /* We found this uniform name in the program - go ahead and send the data */
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, values)); GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, (GLfloat*)lconst->value));
checkGLcall("glUniform4fvARB");
} }
ptr = list_next(&This->baseShader.constantsF, ptr);
} }
checkGLcall("glUniform4fvARB()");
} }
/** /**
...@@ -248,6 +276,7 @@ void shader_glsl_load_constants( ...@@ -248,6 +276,7 @@ void shader_glsl_load_constants(
IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface; IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info; WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
GLhandleARB *constant_locations; GLhandleARB *constant_locations;
struct list *constant_list;
GLhandleARB programId; GLhandleARB programId;
if (!stateBlock->glsl_program) { if (!stateBlock->glsl_program) {
...@@ -264,6 +293,7 @@ void shader_glsl_load_constants( ...@@ -264,6 +293,7 @@ void shader_glsl_load_constants(
(IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration; (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
constant_locations = stateBlock->glsl_program->vuniformF_locations; constant_locations = stateBlock->glsl_program->vuniformF_locations;
constant_list = &stateBlock->set_vconstantsF;
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) { if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
/* Load DirectX 8 float constants/uniforms for vertex shader */ /* Load DirectX 8 float constants/uniforms for vertex shader */
...@@ -273,7 +303,7 @@ void shader_glsl_load_constants( ...@@ -273,7 +303,7 @@ void shader_glsl_load_constants(
/* Load DirectX 9 float constants/uniforms for vertex shader */ /* Load DirectX 9 float constants/uniforms for vertex shader */
shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF), shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
stateBlock->vertexShaderConstantF, constant_locations, stateBlock->set.vertexShaderConstantsF); stateBlock->vertexShaderConstantF, constant_locations, constant_list);
/* Load DirectX 9 integer constants/uniforms for vertex shader */ /* Load DirectX 9 integer constants/uniforms for vertex shader */
shader_glsl_load_constantsI(vshader, gl_info, programId, MAX_CONST_I, shader_glsl_load_constantsI(vshader, gl_info, programId, MAX_CONST_I,
...@@ -291,13 +321,14 @@ void shader_glsl_load_constants( ...@@ -291,13 +321,14 @@ void shader_glsl_load_constants(
IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader; IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
constant_locations = stateBlock->glsl_program->puniformF_locations; constant_locations = stateBlock->glsl_program->puniformF_locations;
constant_list = &stateBlock->set_pconstantsF;
/* Load pixel shader samplers */ /* Load pixel shader samplers */
shader_glsl_load_psamplers(gl_info, iface); shader_glsl_load_psamplers(gl_info, iface);
/* Load DirectX 9 float constants/uniforms for pixel shader */ /* Load DirectX 9 float constants/uniforms for pixel shader */
shader_glsl_load_constantsF(pshader, gl_info, GL_LIMITS(pshader_constantsF), shader_glsl_load_constantsF(pshader, gl_info, GL_LIMITS(pshader_constantsF),
stateBlock->pixelShaderConstantF, constant_locations, stateBlock->set.pixelShaderConstantsF); stateBlock->pixelShaderConstantF, constant_locations, constant_list);
/* Load DirectX 9 integer constants/uniforms for pixel shader */ /* Load DirectX 9 integer constants/uniforms for pixel shader */
shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I, shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I,
......
...@@ -53,6 +53,9 @@ HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) { ...@@ -53,6 +53,9 @@ HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) {
object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF)); object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
WINED3D_MEMCHECK(object->changed.vertexShaderConstantsF); WINED3D_MEMCHECK(object->changed.vertexShaderConstantsF);
list_init(&object->set_vconstantsF);
list_init(&object->set_pconstantsF);
#undef WINED3D_MEMCHECK #undef WINED3D_MEMCHECK
return WINED3D_OK; return WINED3D_OK;
...@@ -225,6 +228,8 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { ...@@ -225,6 +228,8 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
TRACE("(%p) : Releasing from %ld\n", This, refCount + 1); TRACE("(%p) : Releasing from %ld\n", This, refCount + 1);
if (!refCount) { if (!refCount) {
constant_entry *constant, *constant2;
/* type 0 represents the primary stateblock, so free all the resources */ /* type 0 represents the primary stateblock, so free all the resources */
if (This->blockType == WINED3DSBT_INIT) { if (This->blockType == WINED3DSBT_INIT) {
int counter; int counter;
...@@ -274,6 +279,14 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { ...@@ -274,6 +279,14 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
HeapFree(GetProcessHeap(), 0, This->set.pixelShaderConstantsF); HeapFree(GetProcessHeap(), 0, This->set.pixelShaderConstantsF);
HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF); HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF);
LIST_FOR_EACH_ENTRY_SAFE(constant, constant2, &This->set_vconstantsF, constant_entry, entry) {
HeapFree(GetProcessHeap(), 0, constant);
}
LIST_FOR_EACH_ENTRY_SAFE(constant, constant2, &This->set_pconstantsF, constant_entry, entry) {
HeapFree(GetProcessHeap(), 0, constant);
}
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
return refCount; return refCount;
......
...@@ -1040,6 +1040,11 @@ typedef struct SAVEDSTATES { ...@@ -1040,6 +1040,11 @@ typedef struct SAVEDSTATES {
BOOL *vertexShaderConstantsF; BOOL *vertexShaderConstantsF;
} SAVEDSTATES; } SAVEDSTATES;
typedef struct {
struct list entry;
int idx;
} constant_entry;
struct IWineD3DStateBlockImpl struct IWineD3DStateBlockImpl
{ {
/* IUnknown fields */ /* IUnknown fields */
...@@ -1054,6 +1059,8 @@ struct IWineD3DStateBlockImpl ...@@ -1054,6 +1059,8 @@ struct IWineD3DStateBlockImpl
/* Array indicating whether things have been set or changed */ /* Array indicating whether things have been set or changed */
SAVEDSTATES changed; SAVEDSTATES changed;
SAVEDSTATES set; SAVEDSTATES set;
struct list set_vconstantsF;
struct list set_pconstantsF;
/* Drawing - Vertex Shader or FVF related */ /* Drawing - Vertex Shader or FVF related */
DWORD fvf; DWORD fvf;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment