浏览代码

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.
legacy
Sam Hocevar sam 12 年前
父节点
当前提交
458378003c
共有 5 个文件被更改,包括 129 次插入71 次删除
  1. +84
    -34
      src/gpu/shader.cpp
  2. +21
    -6
      src/gpu/shader.h
  3. +1
    -1
      test/tutorial/tut01.cpp
  4. +1
    -1
      test/tutorial/tut02.cpp
  5. +22
    -29
      test/tutorial/tut03.cpp

+ 84
- 34
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
}



+ 21
- 6
src/gpu/shader.h 查看文件

@@ -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;



+ 1
- 1
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


+ 1
- 1
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;
};



+ 22
- 29
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;



正在加载...
取消
保存