From 458378003c168aa981762171a5efaf7562bfb0c7 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Tue, 10 Apr 2012 23:14:16 +0000 Subject: [PATCH] win32: the uniform handling code was completely broken; we now properly retrieve the constant's register index in the description table. This also allows us to use a single uniform handle for both the vertex and pixel shaders in a PS3 Cg program. --- src/gpu/shader.cpp | 118 ++++++++++++++++++++++++++++------------ src/gpu/shader.h | 27 +++++++-- test/tutorial/tut01.cpp | 2 +- test/tutorial/tut02.cpp | 2 +- test/tutorial/tut03.cpp | 51 ++++++++--------- 5 files changed, 129 insertions(+), 71 deletions(-) diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index 1e0954d6..0c9ec162 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -201,7 +201,26 @@ Shader::Shader(char const *vert, char const *frag) } #endif -#if !defined USE_D3D9 && !defined _XBOX && !defined __CELLOS_LV2__ +#if defined USE_D3D9 || defined _XBOX + /* FIXME: this is only debug code, we don't need it. */ + D3DXCONSTANTTABLE_DESC desc; + data->frag_table->GetDesc(&desc); + for (int i = 0; i < desc.Constants; i++) + { + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + D3DXHANDLE h = data->frag_table->GetConstant(NULL, i); + data->frag_table->GetConstantDesc(h, &cdesc, &count); + } + data->vert_table->GetDesc(&desc); + for (int i = 0; i < desc.Constants; i++) + { + D3DXCONSTANT_DESC cdesc; + UINT count = 1; + D3DXHANDLE h = data->vert_table->GetConstant(NULL, i); + data->frag_table->GetConstantDesc(h, &cdesc, &count); + } +#elif !defined __CELLOS_LV2__ /* Create program */ data->prog_id = glCreateProgram(); glAttachShader(data->prog_id, data->vert_id); @@ -215,7 +234,7 @@ Shader::Shader(char const *vert, char const *frag) int Shader::GetAttribLocation(char const *attr) const { #if defined USE_D3D9 || defined _XBOX - /* FIXME: do we have attribs? */ + /* FIXME: do we have attribs on these platforms? */ return 0; #elif !defined __CELLOS_LV2__ return glGetAttribLocation(data->prog_id, attr); @@ -225,83 +244,114 @@ int Shader::GetAttribLocation(char const *attr) const #endif } -int Shader::GetUniformLocation(char const *uni) const +ShaderUniform Shader::GetUniformLocation(char const *uni) const { + ShaderUniform ret; #if defined USE_D3D9 || defined _XBOX - UINT hr1 = (uintptr_t)data->frag_table->GetConstantByName(NULL, uni); - UINT hr2 = (uintptr_t)data->vert_table->GetConstantByName(NULL, uni); - return (int)(((uint32_t)hr1 << 16) | (uint32_t)hr2); + /* Global variables are prefixed with "$" */ + char tmpname[128]; + sprintf(tmpname, "$%s", uni); + D3DXCONSTANT_DESC cdesc; + D3DXHANDLE hr; + UINT count; + + count = 0; + hr = data->frag_table->GetConstantByName(NULL, tmpname); + if (hr) + data->frag_table->GetConstantDesc(hr, &cdesc, &count); + if (count) + { + ret.frag = cdesc.RegisterIndex; + ret.flags |= 1; + } + + count = 0; + hr = data->vert_table->GetConstantByName(NULL, tmpname); + if (hr) + data->vert_table->GetConstantDesc(hr, &cdesc, &count); + if (count) + { + ret.vert = cdesc.RegisterIndex; + ret.flags |= 2; + } #elif !defined __CELLOS_LV2__ - return glGetUniformLocation(data->prog_id, uni); + ret.frag = (uintptr_t)glGetUniformLocation(data->prog_id, uni); + ret.vert = 0; #else - /* FIXME: need to differentiate between vertex and fragment program, - * and replace the ugly cast. */ - CGparameter tmp = cgGetNamedParameter(data->vert_id, uni); - if (tmp == NULL) - tmp = cgGetNamedParameter(data->frag_id, uni); - return (int)(intptr_t)tmp; + ret.frag = (uintptr_t)cgGetNamedParameter(data->frag_id, uni); + ret.vert = (uintptr_t)cgGetNamedParameter(data->vert_id, uni); #endif + return ret; } -void Shader::SetUniform(int uni, float f) +void Shader::SetUniform(ShaderUniform const &uni, float f) { #if defined USE_D3D9 || defined _XBOX SetUniform(uni, vec4(f, 0, 0, 0)); #elif !defined __CELLOS_LV2__ - glUniform1f(uni, f); + glUniform1f(uni.frag, f); #else - cgGLSetParameter1f((CGparameter)(intptr_t)uni, f); + if (uni.frag) + cgGLSetParameter1f((CGparameter)uni.frag, f); + if (uni.vert) + cgGLSetParameter1f((CGparameter)uni.vert, f); #endif } -void Shader::SetUniform(int uni, vec2 const &v) +void Shader::SetUniform(ShaderUniform const &uni, vec2 const &v) { #if defined USE_D3D9 || defined _XBOX SetUniform(uni, vec4(v, 0, 0)); #elif !defined __CELLOS_LV2__ - glUniform2f(uni, v.x, v.y); + glUniform2f(uni.frag, v.x, v.y); #else - cgGLSetParameter2f((CGparameter)(intptr_t)uni, v.x, v.y); + if (uni.frag) + cgGLSetParameter2f((CGparameter)uni.frag, v.x, v.y); + if (uni.vert) + cgGLSetParameter2f((CGparameter)uni.vert, v.x, v.y); #endif } -void Shader::SetUniform(int uni, vec3 const &v) +void Shader::SetUniform(ShaderUniform const &uni, vec3 const &v) { #if defined USE_D3D9 || defined _XBOX SetUniform(uni, vec4(v, 0)); #elif !defined __CELLOS_LV2__ - glUniform3f(uni, v.x, v.y, v.z); + glUniform3f(uni.frag, v.x, v.y, v.z); #else - cgGLSetParameter3f((CGparameter)(intptr_t)uni, v.x, v.y, v.z); + if (uni.frag) + cgGLSetParameter3f((CGparameter)uni.frag, v.x, v.y, v.z); + if (uni.vert) + cgGLSetParameter3f((CGparameter)uni.vert, v.x, v.y, v.z); #endif } -void Shader::SetUniform(int uni, vec4 const &v) +void Shader::SetUniform(ShaderUniform const &uni, vec4 const &v) { /* FIXME: use the array versions of these functions */ #if defined USE_D3D9 || defined _XBOX - UINT hr1 = (uint32_t)uni >> 16; - UINT hr2 = (uint32_t)(uint16_t)uni; - g_d3ddevice->SetPixelShaderConstantF(hr1, &v[0], 1); - g_d3ddevice->SetVertexShaderConstantF(hr2, &v[0], 1); + if (uni.flags & 1) + g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &v[0], 1); + if (uni.flags & 2) + g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, &v[0], 1); #elif !defined __CELLOS_LV2__ glUniform4f(uni, v.x, v.y, v.z, v.w); #else - cgGLSetParameter4f((CGparameter)(intptr_t)uni, v.x, v.y, v.z, v.w); + cgGLSetParameter4f((CGparameter)uni, v.x, v.y, v.z, v.w); #endif } -void Shader::SetUniform(int uni, mat4 const &m) +void Shader::SetUniform(ShaderUniform const &uni, mat4 const &m) { #if defined USE_D3D9 || defined _XBOX - UINT hr1 = (uint32_t)uni >> 16; - UINT hr2 = (uint32_t)(uint16_t)uni; - g_d3ddevice->SetPixelShaderConstantF(hr1, &m[0][0], 4); - g_d3ddevice->SetVertexShaderConstantF(hr2, &m[0][0], 4); + if (uni.flags & 1) + g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &m[0][0], 4); + if (uni.flags & 2) + g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 4); #elif !defined __CELLOS_LV2__ glUniformMatrix4fv(uni, 1, GL_FALSE, &m[0][0]); #else - cgGLSetMatrixParameterfc((CGparameter)(intptr_t)uni, &m[0][0]); + cgGLSetMatrixParameterfc((CGparameter)uni, &m[0][0]); #endif } diff --git a/src/gpu/shader.h b/src/gpu/shader.h index 5e1b39ed..f67b10ca 100644 --- a/src/gpu/shader.h +++ b/src/gpu/shader.h @@ -16,9 +16,24 @@ #if !defined __LOL_SHADER_H__ #define __LOL_SHADER_H__ +#include + namespace lol { +struct ShaderUniform +{ + friend class Shader; + +public: + ShaderUniform() : flags(0) {} + +private: + uintptr_t frag, vert; + /* FIXME: do we really need this to indicate which locations are valid? */ + uint32_t flags; +}; + class ShaderData; class Shader @@ -29,12 +44,12 @@ public: int GetAttribLocation(char const *attr) const; - int GetUniformLocation(char const *uni) const; - void SetUniform(int uni, float f); - void SetUniform(int uni, vec2 const &v); - void SetUniform(int uni, vec3 const &v); - void SetUniform(int uni, vec4 const &v); - void SetUniform(int uni, mat4 const &m); + ShaderUniform GetUniformLocation(char const *uni) const; + void SetUniform(ShaderUniform const &uni, float f); + void SetUniform(ShaderUniform const &uni, vec2 const &v); + void SetUniform(ShaderUniform const &uni, vec3 const &v); + void SetUniform(ShaderUniform const &uni, vec4 const &v); + void SetUniform(ShaderUniform const &uni, mat4 const &m); void Bind() const; diff --git a/test/tutorial/tut01.cpp b/test/tutorial/tut01.cpp index 84e0015a..0158ed8a 100644 --- a/test/tutorial/tut01.cpp +++ b/test/tutorial/tut01.cpp @@ -137,7 +137,7 @@ public: #endif #if defined _XBOX || defined USE_D3D9 - g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 3); + g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); #else glDrawArrays(GL_TRIANGLES, 0, 3); #endif diff --git a/test/tutorial/tut02.cpp b/test/tutorial/tut02.cpp index dba6a3c4..dc34bf8f 100644 --- a/test/tutorial/tut02.cpp +++ b/test/tutorial/tut02.cpp @@ -256,7 +256,7 @@ private: GLuint m_vbo, m_cbo, m_ibo; #endif #endif - int m_mvp; + ShaderUniform m_mvp; bool m_ready; }; diff --git a/test/tutorial/tut03.cpp b/test/tutorial/tut03.cpp index 224fd470..2d1abec9 100644 --- a/test/tutorial/tut03.cpp +++ b/test/tutorial/tut03.cpp @@ -572,7 +572,7 @@ public: /* t2 <-- dd.x > dd.z */ " float t2 = step(dd.x, dd.y);" /* ret.x <-- max(ret.x, ret.y); */ - /* ret.y <-- max(ret.z, ret.yw; */ + /* ret.y <-- max(ret.z, ret.w); */ " ret.xy = mix(ret.xz, ret.yw, t2);" "\n#else\n" /* Fallback for i915 cards -- the trick to reduce the @@ -608,11 +608,11 @@ public: " uniform float4x4 u_ZoomSettings," " uniform float4 u_TexelSize," " uniform float4 u_ScreenSize," - " out float4 out_Position : POSITION," - " out float4 v_CenterX," - " out float4 v_CenterY," - " out float4 v_IndexX," - " out float4 v_IndexY)" + " out float4 out_Position : POSITION0," + " out float4 v_CenterX : TEXCOORD0," + " out float4 v_CenterY : TEXCOORD1," + " out float4 v_IndexX : TEXCOORD2," + " out float4 v_IndexY : TEXCOORD3)" "{" " out_Position = a_Vertex;" " float4 offsets = float4(0.5, -0.5, 0.015625, -0.015625);" @@ -636,18 +636,18 @@ public: " v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;" "}", - "void main(in float4 v_CenterX," - " in float4 v_CenterY," - " in float4 v_IndexX," - " in float4 v_IndexY," - " uniform float4 u_TexelSize2," + "void main(in float4 v_CenterX : TEXCOORD0," + " in float4 v_CenterY : TEXCOORD1," + " in float4 v_IndexX : TEXCOORD2," + " in float4 v_IndexY : TEXCOORD3," + " uniform float4 u_TexelSize," " uniform sampler2D u_Texture," " out float4 out_FragColor : COLOR)" "{" " float4 v05 = float4(0.5, 0.5, 0.5, 0.5);" " float4 rx, ry, t0, dx, dy, dd;" - " rx = u_TexelSize2.x + u_TexelSize2.z * floor(v_IndexX);" - " ry = u_TexelSize2.y + u_TexelSize2.w * floor(v_IndexY);" + " rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);" + " ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);" " t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);" " dx = rx - v_CenterX;" " dy = ry - v_CenterY;" @@ -668,9 +668,6 @@ public: m_texattrib = m_shader->GetAttribLocation("a_TexCoord"); #endif m_texeluni = m_shader->GetUniformLocation("u_TexelSize"); -#if defined __CELLOS_LV2__ - m_texeluni2 = m_shader->GetUniformLocation("u_TexelSize2"); -#endif m_screenuni = m_shader->GetUniformLocation("u_ScreenSize"); m_zoomuni = m_shader->GetUniformLocation("u_ZoomSettings"); m_ready = true; @@ -691,14 +688,13 @@ public: D3DVERTEXELEMENT9 const elements[] = { { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + { 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; g_d3ddevice->CreateVertexDeclaration(elements, &m_vdecl); if (FAILED(g_d3ddevice->CreateVertexBuffer(sizeof(vertices), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &m_vbo, NULL))) exit(0); - vec2 *tmp1; if (FAILED(m_vbo->Lock(0, 0, (void **)&tmp1, 0))) exit(0); @@ -707,7 +703,6 @@ public: if (FAILED(g_d3ddevice->CreateVertexBuffer(sizeof(texcoords), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &m_tbo, NULL))) exit(0); - vec2 *tmp2; if (FAILED(m_tbo->Lock(0, 0, (void **)&tmp2, 0))) exit(0); @@ -742,7 +737,7 @@ public: for (int j = 0; j < m_size.y * 2; j++) { u8vec4 *line = (u8vec4 *)rect.pBits + j * rect.Pitch / 4; - for (int i = 0; i < m_size.x / 2; j++) + for (int i = 0; i < m_size.x / 2; i++) line[i] = m_pixels[m_size.x / 2 * j + i]; } m_tex->UnlockRect(0); @@ -762,13 +757,12 @@ public: m_shader->Bind(); m_shader->SetUniform(m_texeluni, m_texel_settings); -#if defined __CELLOS_LV2__ - m_shader->SetUniform(m_texeluni2, m_texel_settings); -#endif m_shader->SetUniform(m_screenuni, m_screen_settings); m_shader->SetUniform(m_zoomuni, m_zoom_settings); #if defined _XBOX || defined USE_D3D9 - g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + g_d3ddevice->SetTexture(0, m_tex); + //g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); g_d3ddevice->SetVertexDeclaration(m_vdecl); g_d3ddevice->SetStreamSource(0, m_vbo, 0, sizeof(*vertices)); g_d3ddevice->SetStreamSource(1, m_tbo, 0, sizeof(*texcoords)); @@ -792,7 +786,8 @@ public: #endif #if defined _XBOX || defined USE_D3D9 - g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 6); + /* FIXME: what the fuck? Why does "2" not work here instead of 3? */ + g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 3); #else glDrawArrays(GL_TRIANGLES, 0, 6); #endif @@ -839,10 +834,8 @@ private: GLuint m_tco; # endif #endif - int m_vertexattrib, m_texattrib, m_texeluni, m_screenuni, m_zoomuni; -#if defined __CELLOS_LV2__ - int m_texeluni2; -#endif + int m_vertexattrib, m_texattrib; + ShaderUniform m_texeluni, m_screenuni, m_zoomuni; int m_frame, m_slices, m_dirty[4]; bool m_ready, m_drag;