wined3d: Put local constants into the shader code again.
This is essentially a revert of cd7825c893
,
with proper precision.
This commit is contained in:
parent
3f7c07f560
commit
667f4225b5
|
@ -1253,15 +1253,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
|
|||
shader_addline(buffer, "vec4 tmp0;\n");
|
||||
shader_addline(buffer, "vec4 tmp1;\n");
|
||||
|
||||
/* Local constants use a different name so they can be loaded once at shader link time
|
||||
* They can't be hardcoded into the shader text via LC = {x, y, z, w}; because the
|
||||
* float -> string conversion can cause precision loss.
|
||||
*/
|
||||
if (!shader->load_local_constsF)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
|
||||
{
|
||||
shader_addline(buffer, "uniform vec4 %s_lc%u;\n", prefix, lconst->idx);
|
||||
const float *value;
|
||||
value = (const float *)lconst->value;
|
||||
shader_addline(buffer, "const vec4 %s_lc%u = vec4(%.8e, %.8e, %.8e, %.8e);\n",
|
||||
prefix, lconst->idx, value[0], value[1], value[2], value[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4456,25 +4455,6 @@ static void shader_glsl_generate_fog_code(struct wined3d_shader_buffer *buffer,
|
|||
shader_addline(buffer, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, clamp(Fog, 0.0, 1.0));\n");
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void hardcode_local_constants(const struct wined3d_shader *shader,
|
||||
const struct wined3d_gl_info *gl_info, GLhandleARB programId, const char *prefix)
|
||||
{
|
||||
const struct wined3d_shader_lconst *lconst;
|
||||
GLint tmp_loc;
|
||||
const float *value;
|
||||
char glsl_name[10];
|
||||
|
||||
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
|
||||
{
|
||||
value = (const float *)lconst->value;
|
||||
snprintf(glsl_name, sizeof(glsl_name), "%s_lc%u", prefix, lconst->idx);
|
||||
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
|
||||
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, value));
|
||||
}
|
||||
checkGLcall("Hardcoding local constants");
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context,
|
||||
struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader,
|
||||
|
@ -5705,15 +5685,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, struc
|
|||
*/
|
||||
shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId);
|
||||
shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId);
|
||||
|
||||
/* If the local constants do not have to be loaded with the environment constants,
|
||||
* load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
|
||||
* later
|
||||
*/
|
||||
if (pshader && !pshader->load_local_constsF)
|
||||
hardcode_local_constants(pshader, gl_info, programId, "ps");
|
||||
if (vshader && !vshader->load_local_constsF)
|
||||
hardcode_local_constants(vshader, gl_info, programId, "vs");
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
|
|
|
@ -584,15 +584,16 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
|
|||
else if (ins.handler_idx == WINED3DSIH_DEF)
|
||||
{
|
||||
struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
|
||||
float *value;
|
||||
if (!lconst) return E_OUTOFMEMORY;
|
||||
|
||||
lconst->idx = ins.dst[0].reg.idx[0].offset;
|
||||
memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
|
||||
value = (float *)lconst->value;
|
||||
|
||||
/* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
|
||||
if (shader_version.major == 1 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
|
||||
{
|
||||
float *value = (float *)lconst->value;
|
||||
if (value[0] < -1.0f) value[0] = -1.0f;
|
||||
else if (value[0] > 1.0f) value[0] = 1.0f;
|
||||
if (value[1] < -1.0f) value[1] = -1.0f;
|
||||
|
@ -604,6 +605,12 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
|
|||
}
|
||||
|
||||
list_add_head(&shader->constantsF, &lconst->entry);
|
||||
|
||||
if (isinf(value[0]) || isnan(value[0]) || isinf(value[1]) || isnan(value[1])
|
||||
|| isinf(value[2]) || isnan(value[2]) || isinf(value[3]) || isnan(value[3]))
|
||||
{
|
||||
shader->lconst_inf_or_nan = TRUE;
|
||||
}
|
||||
}
|
||||
else if (ins.handler_idx == WINED3DSIH_DEFI)
|
||||
{
|
||||
|
@ -1629,6 +1636,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b
|
|||
list_init(&shader->constantsF);
|
||||
list_init(&shader->constantsB);
|
||||
list_init(&shader->constantsI);
|
||||
shader->lconst_inf_or_nan = FALSE;
|
||||
|
||||
/* Second pass: figure out which registers are used, what the semantics are, etc. */
|
||||
hr = shader_get_registers_used(shader, fe,
|
||||
|
@ -1752,12 +1760,20 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
|
|||
for (i = start_idx; i < end_idx; ++i)
|
||||
{
|
||||
struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
|
||||
float *value;
|
||||
if (!lconst)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
lconst->idx = i;
|
||||
memcpy(lconst->value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
|
||||
value = (float *)lconst->value;
|
||||
memcpy(value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
|
||||
list_add_head(&shader->constantsF, &lconst->entry);
|
||||
|
||||
if (isinf(value[0]) || isnan(value[0]) || isinf(value[1]) || isnan(value[1])
|
||||
|| isinf(value[2]) || isnan(value[2]) || isinf(value[3]) || isnan(value[3]))
|
||||
{
|
||||
shader->lconst_inf_or_nan = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
|
@ -1916,8 +1932,8 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
|
|||
|
||||
vertexshader_set_limits(shader);
|
||||
|
||||
shader->load_local_constsF = reg_maps->usesrelconstF
|
||||
&& !list_empty(&shader->constantsF);
|
||||
shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
|
||||
shader->lconst_inf_or_nan;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
@ -1964,7 +1980,7 @@ static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d
|
|||
|
||||
geometryshader_set_limits(shader);
|
||||
|
||||
shader->load_local_constsF = FALSE;
|
||||
shader->load_local_constsF = shader->lconst_inf_or_nan;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
@ -2253,7 +2269,7 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
|
|||
}
|
||||
}
|
||||
|
||||
shader->load_local_constsF = FALSE;
|
||||
shader->load_local_constsF = shader->lconst_inf_or_nan;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
|
|
@ -2618,6 +2618,7 @@ struct wined3d_shader
|
|||
struct list constantsF;
|
||||
struct list constantsI;
|
||||
struct wined3d_shader_reg_maps reg_maps;
|
||||
BOOL lconst_inf_or_nan;
|
||||
|
||||
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
|
||||
struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
|
||||
|
|
Loading…
Reference in New Issue