[wined3d] enable constant packing for NP2 texcoord fixup
Tobias Jakobi
tjakobi at xdf79.math.uni-bielefeld.de
Tue Jun 16 06:16:29 CDT 2009
Previously every texture that was flagged for NP2 fixup
used a vec2 uniform in the shader to store texture dimensions.
Turns out that the GLSL compilers just maps vec2 to vec4, so
essentially wasting 2 floats. The new code only uses vec4
uniforms but packs dimensions info of 2 textures into a
single uniform.
---
dlls/wined3d/glsl_shader.c | 105 +++++++++++++++++++++++++++++---------------
1 files changed, 69 insertions(+), 36 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 03f3a99..9ade681 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -103,7 +103,7 @@ struct glsl_shader_prog_link {
GLint vuniformI_locations[MAX_CONST_I];
GLint puniformI_locations[MAX_CONST_I];
GLint posFixup_location;
- GLint np2Fixup_location[MAX_FRAGMENT_SAMPLERS];
+ GLint np2Fixup_location;
GLint bumpenvmat_location[MAX_TEXTURES];
GLint luminancescale_location[MAX_TEXTURES];
GLint luminanceoffset_location[MAX_TEXTURES];
@@ -574,24 +574,31 @@ static void shader_glsl_load_np2fixup_constants(
return;
}
- if (prog->ps_args.np2_fixup) {
- UINT i;
- UINT fixup = prog->ps_args.np2_fixup;
+ if (prog->ps_args.np2_fixup && -1 != prog->np2Fixup_location) {
const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
const IWineD3DStateBlockImpl* stateBlock = (const IWineD3DStateBlockImpl*) deviceImpl->stateBlock;
+ UINT i;
+ UINT fixup = prog->ps_args.np2_fixup;
+ GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
for (i = 0; fixup; fixup >>= 1, ++i) {
- if (-1 != prog->np2Fixup_location[i]) {
- const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
- if (!tex) {
- FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
- continue;
- } else {
- const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
- GL_EXTCALL(glUniform2fvARB(prog->np2Fixup_location[i], 1, tex_dim));
- }
+ const unsigned char idx = prog->np2Fixup_info->idx[i];
+ const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
+ GLfloat* tex_dim = &np2fixup_constants[(idx >> 1) * 4];
+
+ if (!tex) {
+ FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
+ continue;
+ }
+
+ if (idx % 2) {
+ tex_dim[2] = tex->baseTexture.pow2Matrix[0]; tex_dim[3] = tex->baseTexture.pow2Matrix[5];
+ } else {
+ tex_dim[0] = tex->baseTexture.pow2Matrix[0]; tex_dim[1] = tex->baseTexture.pow2Matrix[5];
}
}
+
+ GL_EXTCALL(glUniform4fvARB(prog->np2Fixup_location, prog->np2Fixup_info->num_consts, np2fixup_constants));
}
}
@@ -778,10 +785,11 @@ static int vec4_varyings(DWORD shader_major, const WineD3D_GL_Info *gl_info)
/** Generate the variable & register declarations for the GLSL output target */
static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info,
- const struct ps_compile_args *ps_args)
+ struct shader_glsl_ctx_priv *ctx_priv)
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
+ const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
unsigned int i, extra_constants_needed = 0;
const local_constant *lconst;
@@ -924,15 +932,6 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
} else {
shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
}
-
- if (pshader && ps_args->np2_fixup & (1 << i))
- {
- /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
- * while D3D has them in the (normalized) [0,1]x[0,1] range.
- * samplerNP2Fixup stores texture dimensions and is updated through
- * shader_glsl_load_np2fixup_constants when the sampler changes. */
- shader_addline(buffer, "uniform vec2 %csamplerNP2Fixup%u;\n", prefix, i);
- }
break;
case WINED3DSTT_CUBE:
shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i);
@@ -947,7 +946,39 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
}
}
}
-
+
+ /* Declare uniforms for NP2 texcoord fixup */
+ if (pshader && ps_args->np2_fixup) {
+
+ struct ps_np2fixup_info* const fixup = ctx_priv->cur_np2fixup_info;
+ UINT cur = 0;
+
+ /* FIXME: is initialization necessary? */
+ memset(fixup->idx, 0, sizeof(WORD) * MAX_FRAGMENT_SAMPLERS);
+
+ /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
+ * while D3D has them in the (normalized) [0,1]x[0,1] range.
+ * samplerNP2Fixup stores texture dimensions and is updated through
+ * shader_glsl_load_np2fixup_constants when the sampler changes. */
+
+ for (i = 0; i < This->baseShader.limits.sampler; ++i) {
+ if (reg_maps->sampler_type[i]) {
+ if (!(ps_args->np2_fixup & (1 << i))) continue;
+
+ if (WINED3DSTT_2D != reg_maps->sampler_type[i]) {
+ FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
+ continue;
+ }
+
+ fixup->idx[i] = cur;
+ ++cur;
+ }
+ }
+
+ fixup->num_consts = (cur + 1) >> 1;
+ shader_addline(buffer, "uniform vec4 %csamplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
+ }
+
/* Declare address variables */
for (i = 0; i < This->baseShader.limits.address; i++) {
if (reg_maps->address[i])
@@ -1683,7 +1714,7 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s
if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
- struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
fixup = priv->cur_ps_args->color_fixup[sampler];
sampler_base = "Psampler";
@@ -1711,7 +1742,11 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s
shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle);
} else {
if (np2_fixup) {
- shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle);
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ const unsigned char idx = priv->cur_np2fixup_info->idx[sampler];
+
+ shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup[%u].%s)%s);\n", idx >> 1,
+ (idx % 2) ? "zw" : "xy", dst_swizzle);
} else if(dx && dy) {
shader_addline(ins->ctx->buffer, ", %s, %s)%s);\n", dx, dy, dst_swizzle);
} else {
@@ -3664,7 +3699,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShaderImpl *This,
}
/* Base Declarations */
- shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, args);
+ shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, &priv_ctx);
/* Pack 3.0 inputs */
if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
@@ -3760,7 +3795,7 @@ static GLuint shader_glsl_generate_vshader(IWineD3DVertexShaderImpl *This,
priv_ctx.cur_vs_args = args;
/* Base Declarations */
- shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
+ shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, &priv_ctx);
/* Base Shader Body */
shader_generate_main((IWineD3DBaseShader*)This, buffer, reg_maps, function, &priv_ctx);
@@ -4066,7 +4101,6 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
if(pshader) {
char name[32];
- WORD map;
for(i = 0; i < MAX_TEXTURES; i++) {
sprintf(name, "bumpenvmat%u", i);
@@ -4077,13 +4111,12 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
entry->luminanceoffset_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
}
- map = ps_compile_args.np2_fixup;
- for (i = 0; map; map >>= 1, ++i)
- {
- if (!(map & 1)) continue;
-
- sprintf(name, "PsamplerNP2Fixup%u", i);
- entry->np2Fixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
+ if (ps_compile_args.np2_fixup) {
+ if (entry->np2Fixup_info) {
+ entry->np2Fixup_location = GL_EXTCALL(glGetUniformLocationARB(programId, "PsamplerNP2Fixup"));
+ } else {
+ FIXME("NP2 texcoord fixup needed for this pixelshader, but no fixup uniform found.");
+ }
}
}
--
1.5.4.3
--========GMX164631245152241105068--
More information about the wine-patches
mailing list