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.legacy
@@ -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 | |||
} | |||
@@ -16,9 +16,24 @@ | |||
#if !defined __LOL_SHADER_H__ | |||
#define __LOL_SHADER_H__ | |||
#include <stdint.h> | |||
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; | |||
@@ -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 | |||
@@ -256,7 +256,7 @@ private: | |||
GLuint m_vbo, m_cbo, m_ibo; | |||
#endif | |||
#endif | |||
int m_mvp; | |||
ShaderUniform m_mvp; | |||
bool m_ready; | |||
}; | |||
@@ -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; | |||