Commit 718716b7 authored by Jason Green's avatar Jason Green Committed by Alexandre Julliard

wined3d: Make the number of floating point shader constants dynamic.

parent b5c98f4d
...@@ -108,13 +108,13 @@ void shader_arb_load_constants( ...@@ -108,13 +108,13 @@ void shader_arb_load_constants(
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) { if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
/* Load DirectX 8 float constants for vertex shader */ /* Load DirectX 8 float constants for vertex shader */
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB, shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
WINED3D_VSHADER_MAX_CONSTANTS, GL_LIMITS(vshader_constantsF),
vertexDeclaration->constants, NULL); vertexDeclaration->constants, NULL);
} }
/* Load DirectX 9 float constants for vertex shader */ /* Load DirectX 9 float constants for vertex shader */
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB, shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
WINED3D_VSHADER_MAX_CONSTANTS, GL_LIMITS(vshader_constantsF),
stateBlock->vertexShaderConstantF, stateBlock->vertexShaderConstantF,
stateBlock->set.vertexShaderConstantsF); stateBlock->set.vertexShaderConstantsF);
} }
...@@ -124,7 +124,8 @@ void shader_arb_load_constants( ...@@ -124,7 +124,8 @@ void shader_arb_load_constants(
IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader; IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
/* Load DirectX 9 float constants for pixel shader */ /* Load DirectX 9 float constants for pixel shader */
shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS, shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
GL_LIMITS(pshader_constantsF),
stateBlock->pixelShaderConstantF, stateBlock->pixelShaderConstantF,
stateBlock->set.pixelShaderConstantsF); stateBlock->set.pixelShaderConstantsF);
} }
...@@ -134,10 +135,14 @@ void shader_arb_load_constants( ...@@ -134,10 +135,14 @@ void shader_arb_load_constants(
void shader_generate_arb_declarations( void shader_generate_arb_declarations(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) { SHADER_BUFFER* buffer,
WineD3D_GL_Info* gl_info) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
DWORD i; DWORD i;
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
unsigned max_constantsF = min(This->baseShader.limits.constant_float,
(pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
for(i = 0; i < This->baseShader.limits.temporary; i++) { for(i = 0; i < This->baseShader.limits.temporary; i++) {
if (reg_maps->temporary[i]) if (reg_maps->temporary[i])
...@@ -162,8 +167,7 @@ void shader_generate_arb_declarations( ...@@ -162,8 +167,7 @@ void shader_generate_arb_declarations(
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */ /* Need to PARAM the environment parameters (constants) so we can use relative addressing */
shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n", shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
This->baseShader.limits.constant_float, max_constantsF, max_constantsF - 1);
This->baseShader.limits.constant_float - 1);
} }
static const char* shift_tab[] = { static const char* shift_tab[] = {
......
...@@ -775,6 +775,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, ...@@ -775,6 +775,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DStateBlockImpl *object; IWineD3DStateBlockImpl *object;
int i, j; int i, j;
HRESULT temp_result;
D3DCREATEOBJECTINSTANCE(object, StateBlock) D3DCREATEOBJECTINSTANCE(object, StateBlock)
object->blockType = Type; object->blockType = Type;
...@@ -786,6 +787,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, ...@@ -786,6 +787,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
be freed due to circular dependencies */ be freed due to circular dependencies */
return WINED3D_OK; return WINED3D_OK;
} }
temp_result = allocate_shader_constants(object);
if (WINED3D_OK != temp_result)
return temp_result;
/* Otherwise, might as well set the whole state block to the appropriate values */ /* Otherwise, might as well set the whole state block to the appropriate values */
if ( This->stateBlock != NULL) { if ( This->stateBlock != NULL) {
...@@ -813,11 +818,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, ...@@ -813,11 +818,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
object->changed.pixelShader = TRUE; object->changed.pixelShader = TRUE;
/* Pixel Shader Constants */ /* Pixel Shader Constants */
for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) { for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i)
object->changed.pixelShaderConstantsF[i] = TRUE; object->changed.pixelShaderConstantsF[i] = TRUE;
for (i = 0; i < MAX_CONST_B; ++i)
object->changed.pixelShaderConstantsB[i] = TRUE; object->changed.pixelShaderConstantsB[i] = TRUE;
for (i = 0; i < MAX_CONST_I; ++i)
object->changed.pixelShaderConstantsI[i] = TRUE; object->changed.pixelShaderConstantsI[i] = TRUE;
}
for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) { for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
object->changed.renderState[SavedPixelStates_R[i]] = TRUE; object->changed.renderState[SavedPixelStates_R[i]] = TRUE;
} }
...@@ -841,11 +848,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, ...@@ -841,11 +848,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
object->changed.vertexShader = TRUE; object->changed.vertexShader = TRUE;
/* Vertex Shader Constants */ /* Vertex Shader Constants */
for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) { for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i)
object->changed.vertexShaderConstantsF[i] = TRUE; object->changed.vertexShaderConstantsF[i] = TRUE;
for (i = 0; i < MAX_CONST_B; ++i)
object->changed.vertexShaderConstantsB[i] = TRUE; object->changed.vertexShaderConstantsB[i] = TRUE;
for (i = 0; i < MAX_CONST_I; ++i)
object->changed.vertexShaderConstantsI[i] = TRUE; object->changed.vertexShaderConstantsI[i] = TRUE;
}
for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) { for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
object->changed.renderState[SavedVertexStates_R[i]] = TRUE; object->changed.renderState[SavedVertexStates_R[i]] = TRUE;
} }
...@@ -4606,7 +4615,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB( ...@@ -4606,7 +4615,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i, cnt = min(count, MAX_VSHADER_CONSTANTS - start); int i, cnt = min(count, MAX_CONST_B - start);
TRACE("(iface %p, srcData %p, start %d, count %d)\n", TRACE("(iface %p, srcData %p, start %d, count %d)\n",
iface, srcData, start, count); iface, srcData, start, count);
...@@ -4633,7 +4642,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantB( ...@@ -4633,7 +4642,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantB(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int cnt = min(count, MAX_VSHADER_CONSTANTS - start); int cnt = min(count, MAX_CONST_B - start);
TRACE("(iface %p, dstData %p, start %d, count %d)\n", TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count); iface, dstData, start, count);
...@@ -4652,7 +4661,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI( ...@@ -4652,7 +4661,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i, cnt = min(count, MAX_VSHADER_CONSTANTS - start); int i, cnt = min(count, MAX_CONST_I - start);
TRACE("(iface %p, srcData %p, start %d, count %d)\n", TRACE("(iface %p, srcData %p, start %d, count %d)\n",
iface, srcData, start, count); iface, srcData, start, count);
...@@ -4680,7 +4689,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI( ...@@ -4680,7 +4689,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int cnt = min(count, MAX_VSHADER_CONSTANTS - start); int cnt = min(count, MAX_CONST_I - start);
TRACE("(iface %p, dstData %p, start %d, count %d)\n", TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count); iface, dstData, start, count);
...@@ -4699,7 +4708,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF( ...@@ -4699,7 +4708,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i, cnt = min(count, MAX_VSHADER_CONSTANTS - start); int i, cnt = min(count, GL_LIMITS(vshader_constantsF) - start);
TRACE("(iface %p, srcData %p, start %d, count %d)\n", TRACE("(iface %p, srcData %p, start %d, count %d)\n",
iface, srcData, start, count); iface, srcData, start, count);
...@@ -4727,7 +4736,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF( ...@@ -4727,7 +4736,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int cnt = min(count, MAX_VSHADER_CONSTANTS - start); int cnt = min(count, GL_LIMITS(vshader_constantsF) - start);
TRACE("(iface %p, dstData %p, start %d, count %d)\n", TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count); iface, dstData, start, count);
...@@ -4788,7 +4797,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB( ...@@ -4788,7 +4797,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i, cnt = min(count, MAX_PSHADER_CONSTANTS - start); int i, cnt = min(count, MAX_CONST_B - start);
TRACE("(iface %p, srcData %p, start %d, count %d)\n", TRACE("(iface %p, srcData %p, start %d, count %d)\n",
iface, srcData, start, count); iface, srcData, start, count);
...@@ -4798,7 +4807,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB( ...@@ -4798,7 +4807,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB(
memcpy(&This->updateStateBlock->pixelShaderConstantB[start], srcData, cnt * sizeof(BOOL)); memcpy(&This->updateStateBlock->pixelShaderConstantB[start], srcData, cnt * sizeof(BOOL));
for (i = 0; i < cnt; i++) for (i = 0; i < cnt; i++)
TRACE("Set BOOL constant %u to %s\n", i, srcData[i]? "true":"false"); TRACE("Set BOOL constant %u to %s\n", start + i, srcData[i]? "true":"false");
for (i = start; i < cnt + start; ++i) { for (i = start; i < cnt + start; ++i) {
This->updateStateBlock->changed.pixelShaderConstantsB[i] = TRUE; This->updateStateBlock->changed.pixelShaderConstantsB[i] = TRUE;
...@@ -4815,7 +4824,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantB( ...@@ -4815,7 +4824,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantB(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int cnt = min(count, MAX_PSHADER_CONSTANTS - start); int cnt = min(count, MAX_CONST_B - start);
TRACE("(iface %p, dstData %p, start %d, count %d)\n", TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count); iface, dstData, start, count);
...@@ -4834,7 +4843,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI( ...@@ -4834,7 +4843,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i, cnt = min(count, MAX_PSHADER_CONSTANTS - start); int i, cnt = min(count, MAX_CONST_I - start);
TRACE("(iface %p, srcData %p, start %d, count %d)\n", TRACE("(iface %p, srcData %p, start %d, count %d)\n",
iface, srcData, start, count); iface, srcData, start, count);
...@@ -4844,7 +4853,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI( ...@@ -4844,7 +4853,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI(
memcpy(&This->updateStateBlock->pixelShaderConstantI[start * 4], srcData, cnt * sizeof(int) * 4); memcpy(&This->updateStateBlock->pixelShaderConstantI[start * 4], srcData, cnt * sizeof(int) * 4);
for (i = 0; i < cnt; i++) for (i = 0; i < cnt; i++)
TRACE("Set INT constant %u to { %d, %d, %d, %d }\n", i, TRACE("Set INT constant %u to { %d, %d, %d, %d }\n", start + i,
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) {
...@@ -4862,7 +4871,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantI( ...@@ -4862,7 +4871,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantI(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int cnt = min(count, MAX_PSHADER_CONSTANTS - start); int cnt = min(count, MAX_CONST_I - start);
TRACE("(iface %p, dstData %p, start %d, count %d)\n", TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count); iface, dstData, start, count);
...@@ -4881,7 +4890,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF( ...@@ -4881,7 +4890,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i, cnt = min(count, MAX_PSHADER_CONSTANTS - start); int i, cnt = min(count, GL_LIMITS(pshader_constantsF) - start);
TRACE("(iface %p, srcData %p, start %d, count %d)\n", TRACE("(iface %p, srcData %p, start %d, count %d)\n",
iface, srcData, start, count); iface, srcData, start, count);
...@@ -4891,7 +4900,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF( ...@@ -4891,7 +4900,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(
memcpy(&This->updateStateBlock->pixelShaderConstantF[start * 4], srcData, cnt * sizeof(float) * 4); memcpy(&This->updateStateBlock->pixelShaderConstantF[start * 4], srcData, cnt * sizeof(float) * 4);
for (i = 0; i < cnt; i++) for (i = 0; i < cnt; i++)
TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", i, TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i,
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) {
...@@ -4909,7 +4918,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF( ...@@ -4909,7 +4918,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(
UINT count) { UINT count) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int cnt = min(count, MAX_PSHADER_CONSTANTS - start); int cnt = min(count, GL_LIMITS(pshader_constantsF) - start);
TRACE("(iface %p, dstData %p, start %d, count %d)\n", TRACE("(iface %p, dstData %p, start %d, count %d)\n",
iface, dstData, start, count); iface, dstData, start, count);
...@@ -5746,6 +5755,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetHWND(IWineD3DDevice *iface, HWND *hW ...@@ -5746,6 +5755,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetHWND(IWineD3DDevice *iface, HWND *hW
static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface) { static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DStateBlockImpl *object; IWineD3DStateBlockImpl *object;
HRESULT temp_result;
TRACE("(%p)", This); TRACE("(%p)", This);
if (This->isRecordingState) { if (This->isRecordingState) {
...@@ -5757,13 +5768,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface) ...@@ -5757,13 +5768,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface)
FIXME("(%p)Error allocating memory for stateblock\n", This); FIXME("(%p)Error allocating memory for stateblock\n", This);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
TRACE("(%p) creted object %p\n", This, object); TRACE("(%p) created object %p\n", This, object);
object->wineD3DDevice= This; object->wineD3DDevice= This;
/** FIXME: object->parent = parent; **/ /** FIXME: object->parent = parent; **/
object->parent = NULL; object->parent = NULL;
object->blockType = WINED3DSBT_ALL; object->blockType = WINED3DSBT_ALL;
object->ref = 1; object->ref = 1;
object->lpVtbl = &IWineD3DStateBlock_Vtbl; object->lpVtbl = &IWineD3DStateBlock_Vtbl;
temp_result = allocate_shader_constants(object);
if (WINED3D_OK != temp_result)
return temp_result;
IWineD3DStateBlock_Release((IWineD3DStateBlock*)This->updateStateBlock); IWineD3DStateBlock_Release((IWineD3DStateBlock*)This->updateStateBlock);
This->updateStateBlock = object; This->updateStateBlock = object;
......
...@@ -208,32 +208,45 @@ static void select_shader_mode( ...@@ -208,32 +208,45 @@ static void select_shader_mode(
int* ps_selected, int* ps_selected,
int* vs_selected) { int* vs_selected) {
/* Default # of constants to 0 */
gl_info->max_vshader_constantsF = 0;
gl_info->max_pshader_constantsF = 0;
/* Give priority to user disable/emulation request. /* Give priority to user disable/emulation request.
* Then respect REF device for software. * Then respect REF device for software.
* Then check capabilities for hardware, and fallback to software */ * Then check capabilities for hardware, and fallback to software */
if (wined3d_settings.vs_mode == VS_NONE) if (wined3d_settings.vs_mode == VS_NONE) {
*vs_selected = SHADER_NONE; *vs_selected = SHADER_NONE;
else if (DeviceType == WINED3DDEVTYPE_REF || wined3d_settings.vs_mode == VS_SW) } else if (DeviceType == WINED3DDEVTYPE_REF || wined3d_settings.vs_mode == VS_SW) {
*vs_selected = SHADER_SW; *vs_selected = SHADER_SW;
else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested) } else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested) {
*vs_selected = SHADER_GLSL; *vs_selected = SHADER_GLSL;
else if (gl_info->supported[ARB_VERTEX_PROGRAM]) /* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
} else if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
*vs_selected = SHADER_ARB; *vs_selected = SHADER_ARB;
else /* ARB shaders seem to have an implicit PARAM when fog is used, so we need to subtract 1 from the total available */
gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 1;
} else {
*vs_selected = SHADER_SW; *vs_selected = SHADER_SW;
}
/* Fallback to SHADER_NONE where software pixel shaders should be used */ /* Fallback to SHADER_NONE where software pixel shaders should be used */
if (wined3d_settings.ps_mode == PS_NONE) if (wined3d_settings.ps_mode == PS_NONE) {
*ps_selected = SHADER_NONE; *ps_selected = SHADER_NONE;
else if (DeviceType == WINED3DDEVTYPE_REF) } else if (DeviceType == WINED3DDEVTYPE_REF) {
*ps_selected = SHADER_NONE; *ps_selected = SHADER_NONE;
else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested) } else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested) {
*ps_selected = SHADER_GLSL; *ps_selected = SHADER_GLSL;
else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) /* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
} else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
*ps_selected = SHADER_ARB; *ps_selected = SHADER_ARB;
else gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF;
} else {
*ps_selected = SHADER_NONE; *ps_selected = SHADER_NONE;
}
} }
/********************************************************** /**********************************************************
...@@ -528,12 +541,21 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) { ...@@ -528,12 +541,21 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) {
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &gl_max); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &gl_max);
TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - GL_MAX_TEXTURE_IMAGE_UNITS_ARB=%u\n", gl_max); TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - GL_MAX_TEXTURE_IMAGE_UNITS_ARB=%u\n", gl_max);
gl_info->max_samplers = min(MAX_SAMPLERS, gl_max); gl_info->max_samplers = min(MAX_SAMPLERS, gl_max);
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max);
TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max float constants=%u\n", gl_max);
gl_info->ps_arb_constantsF = gl_max;
} else if (strcmp(ThisExtn, "GL_ARB_imaging") == 0) { } else if (strcmp(ThisExtn, "GL_ARB_imaging") == 0) {
TRACE_(d3d_caps)(" FOUND: ARB imaging support\n"); TRACE_(d3d_caps)(" FOUND: ARB imaging support\n");
gl_info->supported[ARB_IMAGING] = TRUE; gl_info->supported[ARB_IMAGING] = TRUE;
} else if (strcmp(ThisExtn, "GL_ARB_shading_language_100") == 0) { } else if (strcmp(ThisExtn, "GL_ARB_shading_language_100") == 0) {
TRACE_(d3d_caps)(" FOUND: GL Shading Language v100 support\n"); TRACE_(d3d_caps)(" FOUND: GL Shading Language v100 support\n");
gl_info->supported[ARB_SHADING_LANGUAGE_100] = TRUE; gl_info->supported[ARB_SHADING_LANGUAGE_100] = TRUE;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
TRACE_(d3d_caps)(" FOUND: GL Shading Language support - max float vs constants=%u\n", gl_max);
gl_info->vs_glsl_constantsF = gl_max;
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
TRACE_(d3d_caps)(" FOUND: GL Shading Language support - max float ps constants=%u\n", gl_max);
gl_info->ps_glsl_constantsF = gl_max;
} else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) { } else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
TRACE_(d3d_caps)(" FOUND: ARB Multisample support\n"); TRACE_(d3d_caps)(" FOUND: ARB Multisample support\n");
gl_info->supported[ARB_MULTISAMPLE] = TRUE; gl_info->supported[ARB_MULTISAMPLE] = TRUE;
...@@ -580,6 +602,9 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) { ...@@ -580,6 +602,9 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) {
gl_info->vs_arb_version = VS_VERSION_11; gl_info->vs_arb_version = VS_VERSION_11;
TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - version=%02x\n", gl_info->vs_arb_version); TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - version=%02x\n", gl_info->vs_arb_version);
gl_info->supported[ARB_VERTEX_PROGRAM] = TRUE; gl_info->supported[ARB_VERTEX_PROGRAM] = TRUE;
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max);
TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max float constants=%u\n", gl_max);
gl_info->vs_arb_constantsF = gl_max;
} else if (strcmp(ThisExtn, "GL_ARB_vertex_blend") == 0) { } else if (strcmp(ThisExtn, "GL_ARB_vertex_blend") == 0) {
glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max); glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
TRACE_(d3d_caps)(" FOUND: ARB Vertex Blend support GL_MAX_VERTEX_UNITS_ARB %d\n", gl_max); TRACE_(d3d_caps)(" FOUND: ARB Vertex Blend support GL_MAX_VERTEX_UNITS_ARB %d\n", gl_max);
...@@ -1765,11 +1790,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, ...@@ -1765,11 +1790,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
TRACE_(d3d_caps)("Vertex shader functionality not available\n"); TRACE_(d3d_caps)("Vertex shader functionality not available\n");
} }
if (This->gl_info.gl_vendor == VENDOR_MESA || This->gl_info.gl_vendor == VENDOR_WINE) { *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
*pCaps->MaxVertexShaderConst = 95;
} else {
*pCaps->MaxVertexShaderConst = WINED3D_VSHADER_MAX_CONSTANTS;
}
/* FIXME: the shader ode should be per adapter */ /* FIXME: the shader ode should be per adapter */
if (wined3d_settings.ps_selected_mode == SHADER_GLSL) { if (wined3d_settings.ps_selected_mode == SHADER_GLSL) {
...@@ -1839,6 +1860,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, ...@@ -1839,6 +1860,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
IWineD3DDeviceImpl *object = NULL; IWineD3DDeviceImpl *object = NULL;
IWineD3DImpl *This = (IWineD3DImpl *)iface; IWineD3DImpl *This = (IWineD3DImpl *)iface;
HDC hDC; HDC hDC;
HRESULT temp_result;
/* Validate the adapter number */ /* Validate the adapter number */
if (Adapter >= IWineD3D_GetAdapterCount(iface)) { if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
...@@ -1898,6 +1920,10 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, ...@@ -1898,6 +1920,10 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
select_shader_mode(&This->gl_info, DeviceType, select_shader_mode(&This->gl_info, DeviceType,
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode); &wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
temp_result = allocate_shader_constants(object->updateStateBlock);
if (WINED3D_OK != temp_result)
return temp_result;
/* set the state of the device to valid */ /* set the state of the device to valid */
object->state = WINED3D_OK; object->state = WINED3D_OK;
......
...@@ -274,12 +274,12 @@ void shader_glsl_load_constants( ...@@ -274,12 +274,12 @@ void shader_glsl_load_constants(
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 */
shader_glsl_load_constantsF(vshader, gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS, shader_glsl_load_constantsF(vshader, gl_info, programId, GL_LIMITS(vshader_constantsF),
vertexDeclaration->constants, NULL); vertexDeclaration->constants, NULL);
} }
/* 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, programId, WINED3D_VSHADER_MAX_CONSTANTS, shader_glsl_load_constantsF(vshader, gl_info, programId, GL_LIMITS(vshader_constantsF),
stateBlock->vertexShaderConstantF, stateBlock->vertexShaderConstantF,
stateBlock->set.vertexShaderConstantsF); stateBlock->set.vertexShaderConstantsF);
...@@ -302,7 +302,7 @@ void shader_glsl_load_constants( ...@@ -302,7 +302,7 @@ void shader_glsl_load_constants(
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, programId, WINED3D_PSHADER_MAX_CONSTANTS, shader_glsl_load_constantsF(pshader, gl_info, programId, GL_LIMITS(pshader_constantsF),
stateBlock->pixelShaderConstantF, stateBlock->pixelShaderConstantF,
stateBlock->set.pixelShaderConstantsF); stateBlock->set.pixelShaderConstantsF);
...@@ -322,7 +322,8 @@ void shader_glsl_load_constants( ...@@ -322,7 +322,8 @@ void shader_glsl_load_constants(
void shader_generate_glsl_declarations( void shader_generate_glsl_declarations(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) { SHADER_BUFFER* buffer,
WineD3D_GL_Info* gl_info) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
int i; int i;
...@@ -338,8 +339,11 @@ void shader_generate_glsl_declarations( ...@@ -338,8 +339,11 @@ void shader_generate_glsl_declarations(
} }
/* Declare the constants (aka uniforms) */ /* Declare the constants (aka uniforms) */
if (This->baseShader.limits.constant_float > 0) if (This->baseShader.limits.constant_float > 0) {
shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, This->baseShader.limits.constant_float); unsigned max_constantsF = min(This->baseShader.limits.constant_float,
(pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
}
if (This->baseShader.limits.constant_int > 0) if (This->baseShader.limits.constant_int > 0)
shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int); shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int);
......
...@@ -843,7 +843,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -843,7 +843,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
/* Base Declarations */ /* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer); shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
/* Pack 3.0 inputs */ /* Pack 3.0 inputs */
if (This->baseShader.hex_version >= D3DPS_VERSION(3,0)) if (This->baseShader.hex_version >= D3DPS_VERSION(3,0))
...@@ -879,7 +879,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -879,7 +879,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n"); shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
/* Base Declarations */ /* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer); shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
......
...@@ -26,6 +26,38 @@ ...@@ -26,6 +26,38 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info
/***************************************
* Stateblock helper functions follow
**************************************/
/** Allocates the correct amount of space for pixel and vertex shader constants,
* along with their set/changed flags on the given stateblock object
*/
HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) {
IWineD3DStateBlockImpl *This = object;
#define WINED3D_MEMCHECK(_object) if (NULL == _object) { FIXME("Out of memory!\n"); return E_OUTOFMEMORY; }
/* Allocate space for floating point constants */
object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
WINED3D_MEMCHECK(object->pixelShaderConstantF);
object->set.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(pshader_constantsF) );
WINED3D_MEMCHECK(object->set.pixelShaderConstantsF);
object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(pshader_constantsF));
WINED3D_MEMCHECK(object->changed.pixelShaderConstantsF);
object->vertexShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
WINED3D_MEMCHECK(object->vertexShaderConstantF);
object->set.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
WINED3D_MEMCHECK(object->set.vertexShaderConstantsF);
object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
WINED3D_MEMCHECK(object->changed.vertexShaderConstantsF);
#undef WINED3D_MEMCHECK
return WINED3D_OK;
}
/********************************************************** /**********************************************************
* IWineD3DStateBlockImpl IUnknown parts follows * IWineD3DStateBlockImpl IUnknown parts follows
**********************************************************/ **********************************************************/
...@@ -88,7 +120,14 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { ...@@ -88,7 +120,14 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
if (NULL != This->vertexDecl) { if (NULL != This->vertexDecl) {
IWineD3DVertexDeclaration_Release(This->vertexDecl); IWineD3DVertexDeclaration_Release(This->vertexDecl);
} }
HeapFree(GetProcessHeap(), 0, This->vertexShaderConstantF);
HeapFree(GetProcessHeap(), 0, This->set.vertexShaderConstantsF);
HeapFree(GetProcessHeap(), 0, This->changed.vertexShaderConstantsF);
HeapFree(GetProcessHeap(), 0, This->pixelShaderConstantF);
HeapFree(GetProcessHeap(), 0, This->set.pixelShaderConstantsF);
HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF);
/* NOTE: according to MSDN: The application is responsible for making sure the texture references are cleared down */ /* NOTE: according to MSDN: The application is responsible for making sure the texture references are cleared down */
for (counter = 0; counter < GL_LIMITS(sampler_stages); counter++) { for (counter = 0; counter < GL_LIMITS(sampler_stages); counter++) {
if (This->textures[counter]) { if (This->textures[counter]) {
...@@ -166,9 +205,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -166,9 +205,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->vertexShader = targetStateBlock->vertexShader; This->vertexShader = targetStateBlock->vertexShader;
} }
/* Vertex Shader Constants */ /* Vertex Shader Float Constants */
for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) { for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
if (This->set.vertexShaderConstantsF[i]) { if (This->set.vertexShaderConstantsF[i]) {
TRACE("Setting %p from %p %d to { %f, %f, %f, %f }\n", This, targetStateBlock, i, TRACE("Setting %p from %p %d to { %f, %f, %f, %f }\n", This, targetStateBlock, i,
targetStateBlock->vertexShaderConstantF[i * 4], targetStateBlock->vertexShaderConstantF[i * 4],
...@@ -181,7 +219,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -181,7 +219,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->vertexShaderConstantF[i * 4 + 2] = targetStateBlock->vertexShaderConstantF[i * 4 + 2]; This->vertexShaderConstantF[i * 4 + 2] = targetStateBlock->vertexShaderConstantF[i * 4 + 2];
This->vertexShaderConstantF[i * 4 + 3] = targetStateBlock->vertexShaderConstantF[i * 4 + 3]; This->vertexShaderConstantF[i * 4 + 3] = targetStateBlock->vertexShaderConstantF[i * 4 + 3];
} }
}
/* Vertex Shader Integer Constants */
for (i = 0; i < MAX_CONST_I; ++i) {
if (This->set.vertexShaderConstantsI[i]) { if (This->set.vertexShaderConstantsI[i]) {
TRACE("Setting %p from %p %d to { %d, %d, %d, %d }\n", This, targetStateBlock, i, TRACE("Setting %p from %p %d to { %d, %d, %d, %d }\n", This, targetStateBlock, i,
targetStateBlock->vertexShaderConstantI[i * 4], targetStateBlock->vertexShaderConstantI[i * 4],
...@@ -194,7 +235,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -194,7 +235,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->vertexShaderConstantI[i * 4 + 2] = targetStateBlock->vertexShaderConstantI[i * 4 + 2]; This->vertexShaderConstantI[i * 4 + 2] = targetStateBlock->vertexShaderConstantI[i * 4 + 2];
This->vertexShaderConstantI[i * 4 + 3] = targetStateBlock->vertexShaderConstantI[i * 4 + 3]; This->vertexShaderConstantI[i * 4 + 3] = targetStateBlock->vertexShaderConstantI[i * 4 + 3];
} }
}
/* Vertex Shader Boolean Constants */
for (i = 0; i < MAX_CONST_B; ++i) {
if (This->set.vertexShaderConstantsB[i]) { if (This->set.vertexShaderConstantsB[i]) {
TRACE("Setting %p from %p %d to %s\n", This, targetStateBlock, i, TRACE("Setting %p from %p %d to %s\n", This, targetStateBlock, i,
targetStateBlock->vertexShaderConstantB[i]? "TRUE":"FALSE"); targetStateBlock->vertexShaderConstantB[i]? "TRUE":"FALSE");
...@@ -202,7 +246,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -202,7 +246,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->vertexShaderConstantB[i] = targetStateBlock->vertexShaderConstantB[i]; This->vertexShaderConstantB[i] = targetStateBlock->vertexShaderConstantB[i];
} }
} }
/* Lights... For a recorded state block, we just had a chain of actions to perform, /* Lights... For a recorded state block, we just had a chain of actions to perform,
so we need to walk that chain and update any actions which differ */ so we need to walk that chain and update any actions which differ */
src = This->lights; src = This->lights;
...@@ -249,8 +293,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -249,8 +293,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->pixelShader = targetStateBlock->pixelShader; This->pixelShader = targetStateBlock->pixelShader;
} }
for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) { /* Pixel Shader Float Constants */
for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
if (This->set.pixelShaderConstantsF[i]) { if (This->set.pixelShaderConstantsF[i]) {
TRACE("Setting %p from %p %d to { %f, %f, %f, %f }\n", This, targetStateBlock, i, TRACE("Setting %p from %p %d to { %f, %f, %f, %f }\n", This, targetStateBlock, i,
targetStateBlock->pixelShaderConstantF[i * 4], targetStateBlock->pixelShaderConstantF[i * 4],
...@@ -263,7 +307,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -263,7 +307,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->pixelShaderConstantF[i * 4 + 2] = targetStateBlock->pixelShaderConstantF[i * 4 + 2]; This->pixelShaderConstantF[i * 4 + 2] = targetStateBlock->pixelShaderConstantF[i * 4 + 2];
This->pixelShaderConstantF[i * 4 + 3] = targetStateBlock->pixelShaderConstantF[i * 4 + 3]; This->pixelShaderConstantF[i * 4 + 3] = targetStateBlock->pixelShaderConstantF[i * 4 + 3];
} }
}
/* Pixel Shader Integer Constants */
for (i = 0; i < MAX_CONST_I; ++i) {
if (This->set.pixelShaderConstantsI[i]) { if (This->set.pixelShaderConstantsI[i]) {
TRACE("Setting %p from %p %d to { %d, %d, %d, %d }\n", This, targetStateBlock, i, TRACE("Setting %p from %p %d to { %d, %d, %d, %d }\n", This, targetStateBlock, i,
targetStateBlock->pixelShaderConstantI[i * 4], targetStateBlock->pixelShaderConstantI[i * 4],
...@@ -276,7 +323,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) ...@@ -276,7 +323,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
This->pixelShaderConstantI[i * 4 + 2] = targetStateBlock->pixelShaderConstantI[i * 4 + 2]; This->pixelShaderConstantI[i * 4 + 2] = targetStateBlock->pixelShaderConstantI[i * 4 + 2];
This->pixelShaderConstantI[i * 4 + 3] = targetStateBlock->pixelShaderConstantI[i * 4 + 3]; This->pixelShaderConstantI[i * 4 + 3] = targetStateBlock->pixelShaderConstantI[i * 4 + 3];
} }
}
/* Pixel Shader Boolean Constants */
for (i = 0; i < MAX_CONST_B; ++i) {
if (This->set.pixelShaderConstantsB[i]) { if (This->set.pixelShaderConstantsB[i]) {
TRACE("Setting %p from %p %d to %s\n", This, targetStateBlock, i, TRACE("Setting %p from %p %d to %s\n", This, targetStateBlock, i,
targetStateBlock->pixelShaderConstantB[i]? "TRUE":"FALSE"); targetStateBlock->pixelShaderConstantB[i]? "TRUE":"FALSE");
...@@ -442,13 +492,17 @@ should really perform a delta so that only the changes get updated*/ ...@@ -442,13 +492,17 @@ should really perform a delta so that only the changes get updated*/
} }
/* Vertex Shader Constants */ /* Vertex Shader Constants */
for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) { for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) {
if (This->set.vertexShaderConstantsF[i] && This->changed.vertexShaderConstantsF[i]) if (This->set.vertexShaderConstantsF[i] && This->changed.vertexShaderConstantsF[i])
IWineD3DDevice_SetVertexShaderConstantF(pDevice, i, This->vertexShaderConstantF + i * 4, 1); IWineD3DDevice_SetVertexShaderConstantF(pDevice, i, This->vertexShaderConstantF + i * 4, 1);
}
for (i = 0; i < MAX_CONST_I; i++) {
if (This->set.vertexShaderConstantsI[i] && This->changed.vertexShaderConstantsI[i]) if (This->set.vertexShaderConstantsI[i] && This->changed.vertexShaderConstantsI[i])
IWineD3DDevice_SetVertexShaderConstantI(pDevice, i, This->vertexShaderConstantI + i * 4, 1); IWineD3DDevice_SetVertexShaderConstantI(pDevice, i, This->vertexShaderConstantI + i * 4, 1);
}
for (i = 0; i < MAX_CONST_B; i++) {
if (This->set.vertexShaderConstantsB[i] && This->changed.vertexShaderConstantsB[i]) if (This->set.vertexShaderConstantsB[i] && This->changed.vertexShaderConstantsB[i])
IWineD3DDevice_SetVertexShaderConstantB(pDevice, i, This->vertexShaderConstantB + i, 1); IWineD3DDevice_SetVertexShaderConstantB(pDevice, i, This->vertexShaderConstantB + i, 1);
} }
...@@ -462,13 +516,17 @@ should really perform a delta so that only the changes get updated*/ ...@@ -462,13 +516,17 @@ should really perform a delta so that only the changes get updated*/
} }
/* Pixel Shader Constants */ /* Pixel Shader Constants */
for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) { for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) {
if (This->set.pixelShaderConstantsF[i] && This->changed.pixelShaderConstantsF[i]) if (This->set.pixelShaderConstantsF[i] && This->changed.pixelShaderConstantsF[i])
IWineD3DDevice_SetPixelShaderConstantF(pDevice, i, This->pixelShaderConstantF + i * 4, 1); IWineD3DDevice_SetPixelShaderConstantF(pDevice, i, This->pixelShaderConstantF + i * 4, 1);
}
for (i = 0; i < MAX_CONST_I; ++i) {
if (This->set.pixelShaderConstantsI[i] && This->changed.pixelShaderConstantsI[i]) if (This->set.pixelShaderConstantsI[i] && This->changed.pixelShaderConstantsI[i])
IWineD3DDevice_SetPixelShaderConstantI(pDevice, i, This->pixelShaderConstantI + i * 4, 1); IWineD3DDevice_SetPixelShaderConstantI(pDevice, i, This->pixelShaderConstantI + i * 4, 1);
}
for (i = 0; i < MAX_CONST_B; ++i) {
if (This->set.pixelShaderConstantsB[i] && This->changed.pixelShaderConstantsB[i]) if (This->set.pixelShaderConstantsB[i] && This->changed.pixelShaderConstantsB[i])
IWineD3DDevice_SetPixelShaderConstantB(pDevice, i, This->pixelShaderConstantB + i, 1); IWineD3DDevice_SetPixelShaderConstantB(pDevice, i, This->pixelShaderConstantB + i, 1);
} }
......
...@@ -308,7 +308,8 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; ...@@ -308,7 +308,8 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT); DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
if (This->constants == NULL ) { if (This->constants == NULL ) {
This->constants = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_VSHADER_CONSTANTS * 4 * sizeof(float)); This->constants = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
((IWineD3DImpl*)This->wineD3DDevice->wineD3D)->gl_info.max_vshader_constantsF * 4 * sizeof(float));
} }
TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count); TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count);
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
......
...@@ -567,7 +567,7 @@ static void vshader_set_limits( ...@@ -567,7 +567,7 @@ static void vshader_set_limits(
This->baseShader.limits.packed_input = 0; This->baseShader.limits.packed_input = 0;
/* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */ /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
This->baseShader.limits.constant_float = WINED3D_VSHADER_MAX_CONSTANTS; This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
switch (This->baseShader.hex_version) { switch (This->baseShader.hex_version) {
case D3DVS_VERSION(1,0): case D3DVS_VERSION(1,0):
...@@ -704,7 +704,7 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( ...@@ -704,7 +704,7 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
/* Base Declarations */ /* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer); shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
...@@ -740,7 +740,7 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( ...@@ -740,7 +740,7 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
min(95, This->baseShader.limits.constant_float); min(95, This->baseShader.limits.constant_float);
/* Base Declarations */ /* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer); shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
if (reg_maps->fog) { if (reg_maps->fog) {
This->usesFog = 1; This->usesFog = 1;
......
...@@ -53,8 +53,8 @@ ...@@ -53,8 +53,8 @@
#define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES #define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES
#define MAX_LEVELS 256 #define MAX_LEVELS 256
#define MAX_VSHADER_CONSTANTS 96 #define MAX_CONST_I 16
#define MAX_PSHADER_CONSTANTS 32 #define MAX_CONST_B 16
/* Used for CreateStateBlock */ /* Used for CreateStateBlock */
#define NUM_SAVEDPIXELSTATES_R 35 #define NUM_SAVEDPIXELSTATES_R 35
...@@ -1021,13 +1021,13 @@ typedef struct SAVEDSTATES { ...@@ -1021,13 +1021,13 @@ typedef struct SAVEDSTATES {
BOOL clipplane[MAX_CLIPPLANES]; BOOL clipplane[MAX_CLIPPLANES];
BOOL vertexDecl; BOOL vertexDecl;
BOOL pixelShader; BOOL pixelShader;
BOOL pixelShaderConstantsB[MAX_PSHADER_CONSTANTS]; BOOL pixelShaderConstantsB[MAX_CONST_B];
BOOL pixelShaderConstantsI[MAX_PSHADER_CONSTANTS]; BOOL pixelShaderConstantsI[MAX_CONST_I];
BOOL pixelShaderConstantsF[MAX_PSHADER_CONSTANTS]; BOOL *pixelShaderConstantsF;
BOOL vertexShader; BOOL vertexShader;
BOOL vertexShaderConstantsB[MAX_VSHADER_CONSTANTS]; BOOL vertexShaderConstantsB[MAX_CONST_B];
BOOL vertexShaderConstantsI[MAX_VSHADER_CONSTANTS]; BOOL vertexShaderConstantsI[MAX_CONST_I];
BOOL vertexShaderConstantsF[MAX_VSHADER_CONSTANTS]; BOOL *vertexShaderConstantsF;
} SAVEDSTATES; } SAVEDSTATES;
struct IWineD3DStateBlockImpl struct IWineD3DStateBlockImpl
...@@ -1053,9 +1053,9 @@ struct IWineD3DStateBlockImpl ...@@ -1053,9 +1053,9 @@ struct IWineD3DStateBlockImpl
IWineD3DVertexShader *vertexShader; IWineD3DVertexShader *vertexShader;
/* Vertex Shader Constants */ /* Vertex Shader Constants */
BOOL vertexShaderConstantB[MAX_VSHADER_CONSTANTS]; BOOL vertexShaderConstantB[MAX_CONST_B];
INT vertexShaderConstantI[MAX_VSHADER_CONSTANTS * 4]; INT vertexShaderConstantI[MAX_CONST_I * 4];
float vertexShaderConstantF[MAX_VSHADER_CONSTANTS * 4]; float *vertexShaderConstantF;
/* Stream Source */ /* Stream Source */
BOOL streamIsUP; BOOL streamIsUP;
...@@ -1089,9 +1089,9 @@ struct IWineD3DStateBlockImpl ...@@ -1089,9 +1089,9 @@ struct IWineD3DStateBlockImpl
IWineD3DPixelShader *pixelShader; IWineD3DPixelShader *pixelShader;
/* Pixel Shader Constants */ /* Pixel Shader Constants */
BOOL pixelShaderConstantB[MAX_PSHADER_CONSTANTS]; BOOL pixelShaderConstantB[MAX_CONST_B];
INT pixelShaderConstantI[MAX_PSHADER_CONSTANTS * 4]; INT pixelShaderConstantI[MAX_CONST_I * 4];
float pixelShaderConstantF[MAX_PSHADER_CONSTANTS * 4]; float *pixelShaderConstantF;
/* Indexed Vertex Blending */ /* Indexed Vertex Blending */
D3DVERTEXBLENDFLAGS vertex_blend; D3DVERTEXBLENDFLAGS vertex_blend;
...@@ -1417,6 +1417,8 @@ extern BOOL vshader_input_is_color( ...@@ -1417,6 +1417,8 @@ extern BOOL vshader_input_is_color(
IWineD3DVertexShader* iface, IWineD3DVertexShader* iface,
unsigned int regnum); unsigned int regnum);
extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);
/* ARB_[vertex/fragment]_program helper functions */ /* ARB_[vertex/fragment]_program helper functions */
extern void shader_arb_load_constants( extern void shader_arb_load_constants(
IWineD3DStateBlock* iface, IWineD3DStateBlock* iface,
...@@ -1545,12 +1547,14 @@ extern HRESULT shader_get_registers_used( ...@@ -1545,12 +1547,14 @@ extern HRESULT shader_get_registers_used(
extern void shader_generate_glsl_declarations( extern void shader_generate_glsl_declarations(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer); SHADER_BUFFER* buffer,
WineD3D_GL_Info* gl_info);
extern void shader_generate_arb_declarations( extern void shader_generate_arb_declarations(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer); SHADER_BUFFER* buffer,
WineD3D_GL_Info* gl_info);
extern void shader_generate_main( extern void shader_generate_main(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
......
...@@ -1680,6 +1680,14 @@ typedef struct _WineD3D_GL_Info { ...@@ -1680,6 +1680,14 @@ typedef struct _WineD3D_GL_Info {
UINT max_blends; UINT max_blends;
UINT max_anisotropy; UINT max_anisotropy;
unsigned max_vshader_constantsF;
unsigned max_pshader_constantsF;
unsigned vs_arb_constantsF;
unsigned ps_arb_constantsF;
unsigned vs_glsl_constantsF;
unsigned ps_glsl_constantsF;
GL_PSVersion ps_arb_version; GL_PSVersion ps_arb_version;
GL_PSVersion ps_nv_version; GL_PSVersion ps_nv_version;
......
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