[PATCH 2/5] wined3d: Use the ftoa helper function in the ARB shader backend
Stefan Dösinger
stefan at codeweavers.com
Thu Sep 5 03:42:12 CDT 2013
This is the ARB equivalent to e0494afa007a1d1ba2f4b649beedca27cb20808e.
---
dlls/wined3d/arb_program_shader.c | 94 +++++++++++++++++++++++----------------
dlls/wined3d/glsl_shader.c | 76 ++++++-------------------------
dlls/wined3d/shader.c | 5 +++
dlls/wined3d/utils.c | 49 ++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 4 ++
5 files changed, 127 insertions(+), 101 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 9f02d21..494c9c8 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -39,13 +39,6 @@ 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;
@@ -770,6 +763,17 @@ static void shader_arb_update_float_pixel_constants(struct wined3d_device *devic
priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count);
}
+static void shader_arb_append_imm_vec4(struct wined3d_shader_buffer *buffer, const float *values)
+{
+ char str[4][16];
+
+ wined3d_ftoa(values[0], str[0]);
+ wined3d_ftoa(values[1], str[1]);
+ wined3d_ftoa(values[2], str[2]);
+ wined3d_ftoa(values[3], str[3]);
+ shader_addline(buffer, "{%s, %s, %s, %s}", str[0], str[1], str[2], str[3]);
+}
+
/* Generate the variable & register declarations for the ARB_vertex_program output target */
static void shader_generate_arb_declarations(const struct wined3d_shader *shader,
const struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_buffer *buffer,
@@ -874,8 +878,9 @@ static void shader_generate_arb_declarations(const struct wined3d_shader *shader
{
const float *value;
value = (const float *)lconst->value;
- shader_addline(buffer, "PARAM C%u = {%.8e, %.8e, %.8e, %.8e};\n", lconst->idx,
- value[0], value[1], value[2], value[3]);
+ shader_addline(buffer, "PARAM C%u = ", lconst->idx);
+ shader_arb_append_imm_vec4(buffer, value);
+ shader_addline(buffer, ";\n");
}
}
@@ -3448,29 +3453,29 @@ static void arbfp_add_sRGB_correction(struct wined3d_shader_buffer *buffer, cons
if(condcode)
{
/* Sigh. MOVC CC doesn't work, so use one of the temps as dummy dest */
- shader_addline(buffer, "SUBC %s, %s.x, srgb_consts1.y;\n", tmp1, fragcolor);
+ shader_addline(buffer, "SUBC %s, %s.x, srgb_consts1.x;\n", tmp1, fragcolor);
/* Calculate the > 0.0031308 case */
- shader_addline(buffer, "POW %s.x (GE), %s.x, srgb_consts1.z;\n", fragcolor, fragcolor);
- shader_addline(buffer, "POW %s.y (GE), %s.y, srgb_consts1.z;\n", fragcolor, fragcolor);
- shader_addline(buffer, "POW %s.z (GE), %s.z, srgb_consts1.z;\n", fragcolor, fragcolor);
- shader_addline(buffer, "MUL %s.xyz (GE), %s, srgb_consts1.w;\n", fragcolor, fragcolor);
- shader_addline(buffer, "SUB %s.xyz (GE), %s, srgb_consts2.x;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "POW %s.x (GE), %s.x, srgb_consts0.x;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "POW %s.y (GE), %s.y, srgb_consts0.x;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "POW %s.z (GE), %s.z, srgb_consts0.x;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "MUL %s.xyz (GE), %s, srgb_consts0.y;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "SUB %s.xyz (GE), %s, srgb_consts0.z;\n", fragcolor, fragcolor);
/* Calculate the < case */
- shader_addline(buffer, "MUL %s.xyz (LT), srgb_consts1.x, %s;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "MUL %s.xyz (LT), srgb_consts0.w, %s;\n", fragcolor, fragcolor);
}
else
{
/* Calculate the > 0.0031308 case */
- shader_addline(buffer, "POW %s.x, %s.x, srgb_consts1.z;\n", tmp1, fragcolor);
- shader_addline(buffer, "POW %s.y, %s.y, srgb_consts1.z;\n", tmp1, fragcolor);
- shader_addline(buffer, "POW %s.z, %s.z, srgb_consts1.z;\n", tmp1, fragcolor);
- shader_addline(buffer, "MUL %s, %s, srgb_consts1.w;\n", tmp1, tmp1);
- shader_addline(buffer, "SUB %s, %s, srgb_consts2.x;\n", tmp1, tmp1);
+ shader_addline(buffer, "POW %s.x, %s.x, srgb_consts0.x;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.y, %s.y, srgb_consts0.x;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.z, %s.z, srgb_consts0.x;\n", tmp1, fragcolor);
+ shader_addline(buffer, "MUL %s, %s, srgb_consts0.y;\n", tmp1, tmp1);
+ shader_addline(buffer, "SUB %s, %s, srgb_consts0.z;\n", tmp1, tmp1);
/* Calculate the < case */
- shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor);
+ shader_addline(buffer, "MUL %s, srgb_consts0.w, %s;\n", tmp2, fragcolor);
/* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
- shader_addline(buffer, "SLT %s, srgb_consts1.y, %s;\n", tmp3, fragcolor);
- shader_addline(buffer, "SGE %s, srgb_consts1.y, %s;\n", tmp4, fragcolor);
+ shader_addline(buffer, "SLT %s, srgb_consts1.x, %s;\n", tmp3, fragcolor);
+ shader_addline(buffer, "SGE %s, srgb_consts1.x, %s;\n", tmp4, fragcolor);
/* Store the components > 0.0031308 in the destination */
shader_addline(buffer, "MUL %s.xyz, %s, %s;\n", fragcolor, tmp1, tmp3);
/* Add the components that are < 0.0031308 */
@@ -3599,6 +3604,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
BOOL custom_linear_fog = FALSE;
char srgbtmp[4][4];
+ char ftoa_tmp[16];
unsigned int i, found = 0;
for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
@@ -3724,7 +3730,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */
shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
- shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %1.10f, 0.0 };\n", eps);
+ wined3d_ftoa(eps, ftoa_tmp);
+ shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %s, 0.0 };\n", ftoa_tmp);
if (reg_maps->shader_version.major < 2)
{
@@ -3748,11 +3755,14 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
}
}
- if(args->super.srgb_correction) {
- shader_addline(buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
- srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
- shader_addline(buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
- srgb_sub_high, 0.0, 0.0, 0.0);
+ if (args->super.srgb_correction)
+ {
+ shader_addline(buffer, "PARAM srgb_consts0 = ");
+ shader_arb_append_imm_vec4(buffer, wined3d_srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "PARAM srgb_consts1 = ");
+ shader_arb_append_imm_vec4(buffer, wined3d_srgb_const1);
+ shader_addline(buffer, ";\n");
}
/* Base Declarations */
@@ -4209,7 +4219,9 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
shader_addline(buffer, "TEMP TMP_FOGCOORD;\n");
if (need_helper_const(shader_data, reg_maps, gl_info))
{
- shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %1.10f};\n", eps);
+ char ftoa_tmp[16];
+ wined3d_ftoa(eps, ftoa_tmp);
+ shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %s};\n", ftoa_tmp);
}
if (need_rel_addr_const(shader_data, reg_maps, gl_info))
{
@@ -6291,11 +6303,14 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
}
shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE);
- if(settings->sRGB_write) {
- shader_addline(&buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
- srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
- shader_addline(&buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
- srgb_sub_high, 0.0, 0.0, 0.0);
+ if (settings->sRGB_write)
+ {
+ shader_addline(&buffer, "PARAM srgb_consts0 = ");
+ shader_arb_append_imm_vec4(&buffer, wined3d_srgb_const0);
+ shader_addline(&buffer, ";\n");
+ shader_addline(&buffer, "PARAM srgb_consts1 = ");
+ shader_arb_append_imm_vec4(&buffer, wined3d_srgb_const1);
+ shader_addline(&buffer, ";\n");
}
if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
@@ -6888,6 +6903,8 @@ static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum compl
static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, char *luminance)
{
const char *tex;
+ static const float yv12_coef[]
+ = {2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f};
switch(textype) {
case GL_TEXTURE_2D: tex = "2D"; break;
@@ -6935,8 +6952,9 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
* When reading from rectangle textures, keep in mind that the input y coordinates
* go from 0 to d3d_height, whereas the opengl texture height is 1.5 * d3d_height
*/
- shader_addline(buffer, "PARAM yv12_coef = {%f, %f, %f, %f};\n",
- 2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f);
+ shader_addline(buffer, "PARAM yv12_coef = ");
+ shader_arb_append_imm_vec4(buffer, yv12_coef);
+ shader_addline(buffer, ";\n");
shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
/* the chroma planes have only half the width */
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 93ec2a8..0dd0197 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -47,9 +47,6 @@ 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];
@@ -251,61 +248,14 @@ static const char *shader_glsl_get_prefix(enum wined3d_shader_type type)
}
}
-/* This should be equivalent to using the %.8e format specifier, but always
- * using '.' as decimal separator. This doesn't handle +/-INF or NAN, since
- * the GLSL parser wouldn't be able to handle those anyway. */
-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]);
+ wined3d_ftoa(values[0], str[0]);
+ wined3d_ftoa(values[1], str[1]);
+ wined3d_ftoa(values[2], str[2]);
+ wined3d_ftoa(values[3], str[3]);
shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]);
}
@@ -1275,10 +1225,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
if (ps_args->srgb_correction)
{
shader_addline(buffer, "const vec4 srgb_const0 = ");
- shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0);
shader_addline(buffer, ";\n");
shader_addline(buffer, "const vec4 srgb_const1 = ");
- shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1);
shader_addline(buffer, ";\n");
}
if (reg_maps->vpos || reg_maps->usesdsy)
@@ -1661,7 +1611,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
switch (reg->data_type)
{
case WINED3D_DATA_FLOAT:
- shader_glsl_ftoa(*(const float *)reg->immconst_data, register_name);
+ wined3d_ftoa(*(const float *)reg->immconst_data, register_name);
break;
case WINED3D_DATA_INT:
sprintf(register_name, "%#x", reg->immconst_data[0]);
@@ -1681,10 +1631,10 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
switch (reg->data_type)
{
case WINED3D_DATA_FLOAT:
- 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]);
+ wined3d_ftoa(*(const float *)®->immconst_data[0], imm_str[0]);
+ wined3d_ftoa(*(const float *)®->immconst_data[1], imm_str[1]);
+ wined3d_ftoa(*(const float *)®->immconst_data[2], imm_str[2]);
+ wined3d_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;
@@ -5491,10 +5441,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
if (settings->sRGB_write)
{
shader_addline(buffer, "const vec4 srgb_const0 = ");
- shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const0);
shader_addline(buffer, ";\n");
shader_addline(buffer, "const vec4 srgb_const1 = ");
- shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_glsl_append_imm_vec4(buffer, wined3d_srgb_const1);
shader_addline(buffer, ";\n");
}
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 1d98f27..2948aa9 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -33,6 +33,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+/* pow, mul_high, sub_high, mul_low */
+const float wined3d_srgb_const0[] = {0.41666f, 1.055f, 0.055f, 12.92f};
+/* cmp */
+const float wined3d_srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f};
+
static const char * const shader_opcode_names[] =
{
/* WINED3DSIH_ABS */ "abs",
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 0744e03..61f7df0 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -27,6 +27,8 @@
#include "config.h"
#include "wine/port.h"
+#include <stdio.h>
+
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -3724,3 +3726,50 @@ const char *wined3d_debug_location(DWORD location)
return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
}
+
+/* This should be equivalent to using the %.8e format specifier, but always
+ * using '.' as decimal separator. This doesn't handle +/-INF or NAN, since
+ * the GLSL and ARB parsers wouldn't be able to handle those anyway. */
+void wined3d_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);
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1a341b7..28df2c9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1710,6 +1710,10 @@ const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *frag
const struct ffp_frag_settings *settings) DECLSPEC_HIDDEN;
void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN;
void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) DECLSPEC_HIDDEN;
+void wined3d_ftoa(float value, char *s) DECLSPEC_HIDDEN;
+
+extern const float wined3d_srgb_const0[] DECLSPEC_HIDDEN;
+extern const float wined3d_srgb_const1[] DECLSPEC_HIDDEN;
enum wined3d_ffp_vs_fog_mode
{
--
1.8.1.5
More information about the wine-patches
mailing list