Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
ba5c61ba
Commit
ba5c61ba
authored
Nov 20, 2007
by
Stefan Dösinger
Committed by
Alexandre Julliard
Nov 27, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Fog is applied after sRGB correction.
parent
d2ac521c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
134 additions
and
50 deletions
+134
-50
visual.c
dlls/d3d9/tests/visual.c
+102
-0
pixelshader.c
dlls/wined3d/pixelshader.c
+32
-50
No files found.
dlls/d3d9/tests/visual.c
View file @
ba5c61ba
...
...
@@ -4888,6 +4888,107 @@ void test_vshader_input(IDirect3DDevice9 *device)
IDirect3DVertexDeclaration9_Release
(
decl_color_float
);
}
static
void
fog_srgbwrite_test
(
IDirect3DDevice9
*
device
)
{
/* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
* if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
* stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
* 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
* 0.73
*
* At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
* so use shaders for this task
*/
IDirect3DPixelShader9
*
pshader
;
IDirect3DVertexShader9
*
vshader
;
IDirect3D9
*
d3d
;
DWORD
vshader_code
[]
=
{
0xfffe0101
,
/* vs_1_1 */
0x0000001f
,
0x80000000
,
0x900f0000
,
/* dcl_position v0 */
0x00000051
,
0xa00f0000
,
0x3f000000
,
0x00000000
,
0x00000000
,
0x00000000
,
/* def c0, 0.5, 0.0, 0.0, 0.0 */
0x00000001
,
0xc00f0000
,
0x90e40000
,
/* mov oPos, v0 */
0x00000001
,
0xc00f0001
,
0xa0000000
,
/* mov oFog, c0.x */
0x0000ffff
/* end */
};
DWORD
pshader_code
[]
=
{
0xffff0101
,
/* ps_1_1 */
0x00000051
,
0xa00f0000
,
0x00000000
,
0x00000000
,
0x00000000
,
0x00000000
,
/* def c0, 0.0, 0.0, 0.0, 0.0 */
0x00000001
,
0x800f0000
,
0xa0e40000
,
/* mov r0, c0 */
0x0000ffff
/* end */
};
const
float
quad
[]
=
{
-
1
.
0
,
-
1
.
0
,
0
.
1
,
1
.
0
,
-
1
.
0
,
0
.
1
,
-
1
.
0
,
1
.
0
,
0
.
1
,
1
.
0
,
1
.
0
,
0
.
1
};
HRESULT
hr
;
DWORD
color
;
IDirect3DDevice9_GetDirect3D
(
device
,
&
d3d
);
if
(
IDirect3D9_CheckDeviceFormat
(
d3d
,
0
,
D3DDEVTYPE_HAL
,
D3DFMT_X8R8G8B8
,
D3DUSAGE_RENDERTARGET
|
D3DUSAGE_QUERY_SRGBWRITE
,
D3DRTYPE_SURFACE
,
D3DFMT_A8R8G8B8
)
!=
D3D_OK
)
{
skip
(
"No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8
\n
"
);
IDirect3D9_Release
(
d3d
);
return
;
}
IDirect3D9_Release
(
d3d
);
hr
=
IDirect3DDevice9_Clear
(
device
,
0
,
NULL
,
D3DCLEAR_TARGET
,
0xffffff00
,
0
.
0
,
0
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Clear returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_FOGENABLE
,
TRUE
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_FOGTABLEMODE
,
D3DFOG_NONE
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_FOGVERTEXMODE
,
D3DFOG_LINEAR
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_FOGCOLOR
,
0xffffffff
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_SRGBWRITEENABLE
,
TRUE
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_CreateVertexShader
(
device
,
vshader_code
,
&
vshader
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreateVertexShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_CreatePixelShader
(
device
,
pshader_code
,
&
pshader
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_CreatePixelShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetFVF
(
device
,
D3DFVF_XYZ
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetFVF returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetVertexShader
(
device
,
vshader
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetVertexShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetPixelShader
(
device
,
pshader
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetPixelShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_BeginScene
(
device
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_BeginScene returned %s
\n
"
,
DXGetErrorString9
(
hr
));
if
(
SUCCEEDED
(
hr
))
{
hr
=
IDirect3DDevice9_DrawPrimitiveUP
(
device
,
D3DPT_TRIANGLESTRIP
,
2
,
quad
,
sizeof
(
float
)
*
3
);
ok
(
hr
==
D3D_OK
,
"DrawPrimitiveUP failed (%08x)
\n
"
,
hr
);
hr
=
IDirect3DDevice9_EndScene
(
device
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_EndScene returned %s
\n
"
,
DXGetErrorString9
(
hr
));
}
hr
=
IDirect3DDevice9_SetVertexShader
(
device
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetVertexShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetPixelShader
(
device
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetPixelShader returned %s
\n
"
,
DXGetErrorString9
(
hr
));
IDirect3DPixelShader9_Release
(
pshader
);
IDirect3DVertexShader9_Release
(
vshader
);
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_FOGENABLE
,
FALSE
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_SetRenderState
(
device
,
D3DRS_SRGBWRITEENABLE
,
FALSE
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_SetRenderState returned %s
\n
"
,
DXGetErrorString9
(
hr
));
hr
=
IDirect3DDevice9_Present
(
device
,
NULL
,
NULL
,
NULL
,
NULL
);
ok
(
hr
==
D3D_OK
,
"IDirect3DDevice9_Present failed with %s
\n
"
,
DXGetErrorString9
(
hr
));
color
=
getPixelColor
(
device
,
160
,
360
);
ok
(
color
==
0x00808080
||
color
==
0x007f7f7f
||
color
==
0x00818181
,
"Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080
\n
"
,
color
);
}
START_TEST
(
visual
)
{
IDirect3DDevice9
*
device_ptr
;
...
...
@@ -4988,6 +5089,7 @@ START_TEST(visual)
if
(
caps
.
VertexShaderVersion
>=
D3DVS_VERSION
(
1
,
1
)
&&
caps
.
PixelShaderVersion
>=
D3DPS_VERSION
(
1
,
1
))
{
fog_with_shader_test
(
device_ptr
);
fog_srgbwrite_test
(
device_ptr
);
}
else
skip
(
"No vs_1_1 and ps_1_1 support
\n
"
);
...
...
dlls/wined3d/pixelshader.c
View file @
ba5c61ba
...
...
@@ -286,6 +286,7 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
IWineD3DPixelShaderImpl
*
This
=
(
IWineD3DPixelShaderImpl
*
)
iface
;
SHADER_BUFFER
buffer
;
const
char
*
fragcolor
;
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
...
...
@@ -341,27 +342,12 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_addline
(
&
buffer
,
"gl_FragColor = R0;
\n
"
);
}
/* Pixel shader < 3.0 do not replace the fog stage.
* This implements linear fog computation and blending.
* TODO: non linear fog
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
* -1/(e-s) and e/(e-s) respectively.
*/
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
3
,
0
))
{
shader_addline
(
&
buffer
,
"float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);
\n
"
);
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
shader_addline
(
&
buffer
,
"gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, Fog);
\n
"
);
else
shader_addline
(
&
buffer
,
"gl_FragColor.xyz = mix(gl_Fog.color.xyz, gl_FragColor.xyz, Fog);
\n
"
);
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
{
fragcolor
=
"gl_FragData[0]"
;
}
else
{
fragcolor
=
"gl_FragColor"
;
}
if
(
This
->
srgb_enabled
)
{
const
char
*
fragcolor
;
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
{
fragcolor
=
"gl_FragData[0]"
;
}
else
{
fragcolor
=
"gl_FragColor"
;
}
shader_addline
(
&
buffer
,
"tmp0.xyz = pow(%s.xyz, vec3(%f, %f, %f)) * vec3(%f, %f, %f) - vec3(%f, %f, %f);
\n
"
,
fragcolor
,
srgb_pow
,
srgb_pow
,
srgb_pow
,
srgb_mul_high
,
srgb_mul_high
,
srgb_mul_high
,
srgb_sub_high
,
srgb_sub_high
,
srgb_sub_high
);
...
...
@@ -371,6 +357,16 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_addline
(
&
buffer
,
"%s.z = %s.z < srgb_comparison.z ? tmp1.z : tmp0.z;
\n
"
,
fragcolor
,
fragcolor
);
shader_addline
(
&
buffer
,
"%s = clamp(%s, 0.0, 1.0);
\n
"
,
fragcolor
,
fragcolor
);
}
/* Pixel shader < 3.0 do not replace the fog stage.
* This implements linear fog computation and blending.
* TODO: non linear fog
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
* -1/(e-s) and e/(e-s) respectively.
*/
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
3
,
0
))
{
shader_addline
(
&
buffer
,
"float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);
\n
"
);
shader_addline
(
&
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
}
shader_addline
(
&
buffer
,
"}
\n
"
);
...
...
@@ -413,48 +409,34 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
*/
shader_addline
(
&
buffer
,
"MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;
\n
"
);
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
2
,
0
))
{
fragcolor
=
"R0"
;
}
else
{
fragcolor
=
"TMP_COLOR"
;
}
if
(
This
->
srgb_enabled
)
{
const
char
*
color_reg
;
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
2
,
0
))
{
color_reg
=
"R0"
;
}
else
{
color_reg
=
"TMP_COLOR"
;
}
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
2
,
0
))
{
shader_addline
(
&
buffer
,
"LRP R0.rgb, TMP_FOG.x, R0, state.fog.color;
\n
"
);
shader_addline
(
&
buffer
,
"MOV result.color.a, R0.a;
\n
"
);
}
else
{
shader_addline
(
&
buffer
,
"LRP TMP_COLOR.rgb, TMP_FOG.x, TMP_COLOR, state.fog.color;
\n
"
);
shader_addline
(
&
buffer
,
"MOV result.color.a, TMP_COLOR.a;
\n
"
);
}
/* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
/* Calculate the > 0.0031308 case */
shader_addline
(
&
buffer
,
"POW TMP.x, %s.x, srgb_pow.x;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"POW TMP.y, %s.y, srgb_pow.y;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"POW TMP.z, %s.z, srgb_pow.z;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"POW TMP.x, %s.x, srgb_pow.x;
\n
"
,
fragcolor
);
shader_addline
(
&
buffer
,
"POW TMP.y, %s.y, srgb_pow.y;
\n
"
,
fragcolor
);
shader_addline
(
&
buffer
,
"POW TMP.z, %s.z, srgb_pow.z;
\n
"
,
fragcolor
);
shader_addline
(
&
buffer
,
"MUL TMP, TMP, srgb_mul_hi;
\n
"
);
shader_addline
(
&
buffer
,
"SUB TMP, TMP, srgb_sub_hi;
\n
"
);
/* Calculate the < case */
shader_addline
(
&
buffer
,
"MUL TMP2, srgb_mul_low, %s;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"MUL TMP2, srgb_mul_low, %s;
\n
"
,
fragcolor
);
/* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
shader_addline
(
&
buffer
,
"SLT TA, srgb_comparison, %s;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"SGE TB, srgb_comparison, %s;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"SLT TA, srgb_comparison, %s;
\n
"
,
fragcolor
);
shader_addline
(
&
buffer
,
"SGE TB, srgb_comparison, %s;
\n
"
,
fragcolor
);
/* Store the components > 0.0031308 in the destination */
shader_addline
(
&
buffer
,
"MUL %s, TMP, TA;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"MUL %s, TMP, TA;
\n
"
,
fragcolor
);
/* Add the components that are < 0.0031308 */
shader_addline
(
&
buffer
,
"MAD result.color.xyz, TMP2, TB, %s;
\n
"
,
color_reg
);
shader_addline
(
&
buffer
,
"MAD result.color.xyz, TMP2, TB, %s;
\n
"
,
fragcolor
);
/* [0.0;1.0] clamping. Not needed, this is done implicitly */
}
else
{
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
2
,
0
))
{
shader_addline
(
&
buffer
,
"LRP result.color.rgb, TMP_FOG.x, R0, state.fog.color;
\n
"
);
shader_addline
(
&
buffer
,
"MOV result.color.a, R0.a;
\n
"
);
}
else
{
shader_addline
(
&
buffer
,
"LRP result.color.rgb, TMP_FOG.x, TMP_COLOR, state.fog.color;
\n
"
);
shader_addline
(
&
buffer
,
"MOV result.color.a, TMP_COLOR.a;
\n
"
);
}
}
if
(
This
->
baseShader
.
hex_version
<
WINED3DPS_VERSION
(
3
,
0
))
{
shader_addline
(
&
buffer
,
"LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;
\n
"
,
fragcolor
);
shader_addline
(
&
buffer
,
"MOV result.color.a, %s.a;
\n
"
,
fragcolor
);
}
shader_addline
(
&
buffer
,
"END
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment