[PATCH 1/1] wined3d: Introduce a helper function for printing floats in GLSL shaders.
Henri Verbeet
hverbeet at codeweavers.com
Tue Jun 11 02:27:10 CDT 2013
We always want to use '.' as decimal separator in GLSL, instead of the locale
specific one. Reported on IRC.
---
dlls/wined3d/arb_program_shader.c | 7 +++
dlls/wined3d/glsl_shader.c | 117 +++++++++++++++++++++++++++++++-------
dlls/wined3d/wined3d_private.h | 7 ---
3 files changed, 102 insertions(+), 29 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index ef75a2f..fd2df68 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -39,6 +39,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
WINE_DECLARE_DEBUG_CHANNEL(d3d_constants);
WINE_DECLARE_DEBUG_CHANNEL(d3d);
+/* sRGB correction constants */
+static const float srgb_cmp = 0.0031308f;
+static const float srgb_mul_low = 12.92f;
+static const float srgb_pow = 0.41666f;
+static const float srgb_mul_high = 1.055f;
+static const float srgb_sub_high = 0.055f;
+
static BOOL shader_is_pshader_version(enum wined3d_shader_type type)
{
return type == WINED3D_SHADER_TYPE_PIXEL;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 0379729..a49ef95 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -47,6 +47,9 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
#define WINED3D_GLSL_SAMPLE_LOD 0x4
#define WINED3D_GLSL_SAMPLE_GRAD 0x8
+static const float srgb_const0[] = {0.41666f, 1.055f, 0.055f, 12.92f}; /* pow, mul_high, sub_high, mul_low */
+static const float srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f}; /* cmp */
+
struct glsl_dst_param
{
char reg_name[150];
@@ -242,6 +245,61 @@ static const char *shader_glsl_get_prefix(enum wined3d_shader_type type)
}
}
+static void shader_glsl_ftoa(float value, char *s)
+{
+ int x, frac, exponent;
+ const char *sign = "";
+ double d;
+
+ d = value;
+ if (copysignf(1.0f, value) < 0.0f)
+ {
+ d = -d;
+ sign = "-";
+ }
+
+ if (d == 0.0f)
+ {
+ x = 0;
+ frac = 0;
+ exponent = 0;
+ }
+ else
+ {
+ double t, diff;
+
+ exponent = floorf(log10f(d));
+ d /= pow(10.0, exponent);
+
+ x = d;
+ t = (d - x) * 100000000;
+ frac = t;
+ diff = t - frac;
+
+ if ((diff > 0.5) || (diff == 0.5 && (frac & 1)))
+ {
+ if (++frac >= 100000000)
+ {
+ frac = 0;
+ ++x;
+ }
+ }
+ }
+
+ sprintf(s, "%s%d.%08de%+03d", sign, x, frac, exponent);
+}
+
+static void shader_glsl_append_imm_vec4(struct wined3d_shader_buffer *buffer, const float *values)
+{
+ char str[4][16];
+
+ shader_glsl_ftoa(values[0], str[0]);
+ shader_glsl_ftoa(values[1], str[1]);
+ shader_glsl_ftoa(values[2], str[2]);
+ shader_glsl_ftoa(values[3], str[3]);
+ shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]);
+}
+
/* Extract a line from the info log.
* Note that this modifies the source string. */
static char *get_info_log_line(char **ptr)
@@ -1206,10 +1264,12 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
if (ps_args->srgb_correction)
{
- shader_addline(buffer, "const vec4 srgb_const0 = vec4(%.8e, %.8e, %.8e, %.8e);\n",
- srgb_pow, srgb_mul_high, srgb_sub_high, srgb_mul_low);
- shader_addline(buffer, "const vec4 srgb_const1 = vec4(%.8e, 0.0, 0.0, 0.0);\n",
- srgb_cmp);
+ shader_addline(buffer, "const vec4 srgb_const0 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "const vec4 srgb_const1 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_addline(buffer, ";\n");
}
if (reg_maps->vpos || reg_maps->usesdsy)
{
@@ -1221,13 +1281,21 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
else
{
- /* This happens because we do not have proper tracking of the constant registers that are
- * actually used, only the max limit of the shader version
- */
+ float ycorrection[] =
+ {
+ context->render_offscreen ? 0.0f : fb->render_targets[0]->resource.height,
+ context->render_offscreen ? 1.0f : -1.0f,
+ 0.0f,
+ 0.0f,
+ };
+
+ /* This happens because we do not have proper tracking of the
+ * constant registers that are actually used, only the max
+ * limit of the shader version. */
FIXME("Cannot find a free uniform for vpos correction params\n");
- shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n",
- context->render_offscreen ? 0.0f : fb->render_targets[0]->resource.height,
- context->render_offscreen ? 1.0f : -1.0f);
+ shader_addline(buffer, "const vec4 ycorrection = ");
+ shader_glsl_append_imm_vec4(buffer, ycorrection);
+ shader_addline(buffer, ";\n");
}
shader_addline(buffer, "vec4 vpos;\n");
}
@@ -1261,10 +1329,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
{
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
{
- 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]);
+ shader_addline(buffer, "const vec4 %s_lc%u = ", prefix, lconst->idx);
+ shader_glsl_append_imm_vec4(buffer, (const float *)lconst->value);
+ shader_addline(buffer, ";\n");
}
}
@@ -1388,6 +1455,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
const char *prefix = shader_glsl_get_prefix(version->type);
struct glsl_src_param rel_param0, rel_param1;
+ char imm_str[4][16];
if (reg->idx[0].offset != ~0U && reg->idx[0].rel_addr)
shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param0);
@@ -1583,7 +1651,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
switch (reg->data_type)
{
case WINED3D_DATA_FLOAT:
- sprintf(register_name, "%.8e", *(const float *)reg->immconst_data);
+ shader_glsl_ftoa(*(const float *)reg->immconst_data, register_name);
break;
case WINED3D_DATA_INT:
sprintf(register_name, "%#x", reg->immconst_data[0]);
@@ -1603,9 +1671,12 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
switch (reg->data_type)
{
case WINED3D_DATA_FLOAT:
- sprintf(register_name, "vec4(%.8e, %.8e, %.8e, %.8e)",
- *(const float *)®->immconst_data[0], *(const float *)®->immconst_data[1],
- *(const float *)®->immconst_data[2], *(const float *)®->immconst_data[3]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[0], imm_str[0]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[1], imm_str[1]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[2], imm_str[2]);
+ shader_glsl_ftoa(*(const float *)®->immconst_data[3], imm_str[3]);
+ sprintf(register_name, "vec4(%s, %s, %s, %s)",
+ imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
break;
case WINED3D_DATA_INT:
sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
@@ -5399,10 +5470,12 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
if (settings->sRGB_write)
{
- shader_addline(buffer, "const vec4 srgb_const0 = vec4(%.8e, %.8e, %.8e, %.8e);\n",
- srgb_pow, srgb_mul_high, srgb_sub_high, srgb_mul_low);
- shader_addline(buffer, "const vec4 srgb_const1 = vec4(%.8e, 0.0, 0.0, 0.0);\n",
- srgb_cmp);
+ shader_addline(buffer, "const vec4 srgb_const0 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "const vec4 srgb_const1 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_addline(buffer, ";\n");
}
shader_addline(buffer, "void main()\n{\n");
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 6539548..4ac9098 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2854,13 +2854,6 @@ struct ps_np2fixup_info {
WORD num_consts;
};
-/* sRGB correction constants */
-static const float srgb_cmp = 0.0031308f;
-static const float srgb_mul_low = 12.92f;
-static const float srgb_pow = 0.41666f;
-static const float srgb_mul_high = 1.055f;
-static const float srgb_sub_high = 0.055f;
-
struct wined3d_palette
{
LONG ref;
--
1.8.1.5
More information about the wine-patches
mailing list