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
22319c7f
Commit
22319c7f
authored
Jun 18, 2013
by
Stefan Dösinger
Committed by
Alexandre Julliard
Jun 19, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Work around broken FFP fog with ARB shaders.
parent
b648b741
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
147 additions
and
6 deletions
+147
-6
arb_program_shader.c
dlls/wined3d/arb_program_shader.c
+41
-6
directx.c
dlls/wined3d/directx.c
+105
-0
wined3d_private.h
dlls/wined3d/wined3d_private.h
+1
-0
No files found.
dlls/wined3d/arb_program_shader.c
View file @
22319c7f
...
...
@@ -278,6 +278,7 @@ struct shader_arb_ctx_priv
BOOL
muted
;
unsigned
int
num_loops
,
loop_depth
,
num_ifcs
;
int
aL
;
BOOL
custom_linear_fog
;
unsigned
int
vs_clipplanes
;
BOOL
footer_written
;
...
...
@@ -1160,7 +1161,8 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
break
;
case
WINED3DSPR_COLOROUT
:
if
(
ctx
->
cur_ps_args
->
super
.
srgb_correction
&&
!
reg
->
idx
[
0
].
offset
)
if
((
ctx
->
cur_ps_args
->
super
.
srgb_correction
||
ctx
->
custom_linear_fog
)
&&
!
reg
->
idx
[
0
].
offset
)
{
strcpy
(
register_name
,
"TMP_COLOR"
);
}
...
...
@@ -3559,6 +3561,14 @@ static void init_ps_input(const struct wined3d_shader *shader,
}
}
static
void
arbfp_add_linear_fog
(
struct
wined3d_shader_buffer
*
buffer
,
const
char
*
fragcolor
,
const
char
*
tmp
)
{
shader_addline
(
buffer
,
"SUB %s.x, state.fog.params.z, fragment.fogcoord.x;
\n
"
,
tmp
);
shader_addline
(
buffer
,
"MUL_SAT %s.x, %s.x, state.fog.params.w;
\n
"
,
tmp
,
tmp
);
shader_addline
(
buffer
,
"LRP %s.rgb, %s.x, %s, state.fog.color;
\n
"
,
fragcolor
,
tmp
,
fragcolor
);
}
/* Context activation is done by the caller. */
static
GLuint
shader_arb_generate_pshader
(
const
struct
wined3d_shader
*
shader
,
const
struct
wined3d_gl_info
*
gl_info
,
struct
wined3d_shader_buffer
*
buffer
,
...
...
@@ -3622,6 +3632,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
priv_ctx
.
cur_np2fixup_info
=
&
compiled
->
np2fixup_info
;
init_ps_input
(
shader
,
args
,
&
priv_ctx
);
list_init
(
&
priv_ctx
.
control_frames
);
priv_ctx
.
custom_linear_fog
=
FALSE
;
/* Avoid enabling NV_fragment_program* if we do not need it.
*
...
...
@@ -3674,6 +3685,11 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
case
WINED3D_FFP_PS_FOG_OFF
:
break
;
case
WINED3D_FFP_PS_FOG_LINEAR
:
if
(
gl_info
->
quirks
&
WINED3D_QUIRK_BROKEN_ARB_FOG
)
{
priv_ctx
.
custom_linear_fog
=
TRUE
;
break
;
}
shader_addline
(
buffer
,
"OPTION ARB_fog_linear;
\n
"
);
break
;
case
WINED3D_FFP_PS_FOG_EXP
:
...
...
@@ -3703,7 +3719,7 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
}
else
{
if
(
args
->
super
.
srgb_correction
)
if
(
args
->
super
.
srgb_correction
||
priv_ctx
.
custom_linear_fog
)
{
if
(
shader
->
u
.
ps
.
color0_mov
)
{
...
...
@@ -3854,6 +3870,9 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
priv_ctx
.
target_version
>=
NV2
);
}
if
(
priv_ctx
.
custom_linear_fog
)
arbfp_add_linear_fog
(
buffer
,
fragcolor
,
"TA"
);
if
(
strcmp
(
fragcolor
,
"result.color"
))
{
shader_addline
(
buffer
,
"MOV result.color, %s;
\n
"
,
fragcolor
);
}
...
...
@@ -6147,6 +6166,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
BOOL
op_equal
;
const
char
*
final_combiner_src
=
"ret"
;
GLint
pos
;
BOOL
custom_linear_fog
=
FALSE
;
/* Find out which textures are read */
for
(
stage
=
0
;
stage
<
MAX_TEXTURES
;
++
stage
)
...
...
@@ -6219,7 +6239,15 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
switch
(
settings
->
fog
)
{
case
WINED3D_FFP_PS_FOG_OFF
:
break
;
case
WINED3D_FFP_PS_FOG_LINEAR
:
shader_addline
(
&
buffer
,
"OPTION ARB_fog_linear;
\n
"
);
break
;
case
WINED3D_FFP_PS_FOG_LINEAR
:
if
(
gl_info
->
quirks
&
WINED3D_QUIRK_BROKEN_ARB_FOG
)
{
custom_linear_fog
=
TRUE
;
break
;
}
shader_addline
(
&
buffer
,
"OPTION ARB_fog_linear;
\n
"
);
break
;
case
WINED3D_FFP_PS_FOG_EXP
:
shader_addline
(
&
buffer
,
"OPTION ARB_fog_exp;
\n
"
);
break
;
case
WINED3D_FFP_PS_FOG_EXP2
:
shader_addline
(
&
buffer
,
"OPTION ARB_fog_exp2;
\n
"
);
break
;
default:
FIXME
(
"Unexpected fog setting %d
\n
"
,
settings
->
fog
);
...
...
@@ -6384,12 +6412,19 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
}
}
if
(
settings
->
sRGB_write
)
{
if
(
settings
->
sRGB_write
||
custom_linear_fog
)
{
shader_addline
(
&
buffer
,
"MAD ret, fragment.color.secondary, specular_enable, %s;
\n
"
,
final_combiner_src
);
if
(
settings
->
sRGB_write
)
arbfp_add_sRGB_correction
(
&
buffer
,
"ret"
,
"arg0"
,
"arg1"
,
"arg2"
,
"tempreg"
,
FALSE
);
if
(
custom_linear_fog
)
arbfp_add_linear_fog
(
&
buffer
,
"ret"
,
"arg0"
);
shader_addline
(
&
buffer
,
"MOV result.color, ret;
\n
"
);
}
else
{
shader_addline
(
&
buffer
,
"MAD result.color, fragment.color.secondary, specular_enable, %s;
\n
"
,
final_combiner_src
);
}
else
{
shader_addline
(
&
buffer
,
"MAD result.color, fragment.color.secondary, specular_enable, %s;
\n
"
,
final_combiner_src
);
}
/* Footer */
...
...
dlls/wined3d/directx.c
View file @
22319c7f
...
...
@@ -791,6 +791,101 @@ static BOOL match_r200(const struct wined3d_gl_info *gl_info, const char *gl_ren
return
FALSE
;
}
static
BOOL
match_broken_arb_fog
(
const
struct
wined3d_gl_info
*
gl_info
,
const
char
*
gl_renderer
,
enum
wined3d_gl_vendor
gl_vendor
,
enum
wined3d_pci_vendor
card_vendor
,
enum
wined3d_pci_device
device
)
{
DWORD
data
[
4
];
GLuint
tex
,
fbo
;
GLenum
status
;
float
color
[
4
]
=
{
0
.
0
f
,
1
.
0
f
,
0
.
0
f
,
0
.
0
f
};
GLuint
prog
;
GLint
err_pos
;
static
const
char
*
program_code
=
"!!ARBfp1.0
\n
"
"OPTION ARB_fog_linear;
\n
"
"MOV result.color, {1.0, 0.0, 0.0, 0.0};
\n
"
"END
\n
"
;
if
(
wined3d_settings
.
offscreen_rendering_mode
!=
ORM_FBO
)
return
FALSE
;
if
(
!
gl_info
->
supported
[
ARB_FRAGMENT_PROGRAM
])
return
FALSE
;
gl_info
->
gl_ops
.
gl
.
p_glGenTextures
(
1
,
&
tex
);
gl_info
->
gl_ops
.
gl
.
p_glBindTexture
(
GL_TEXTURE_2D
,
tex
);
gl_info
->
gl_ops
.
gl
.
p_glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MIN_FILTER
,
GL_NEAREST
);
gl_info
->
gl_ops
.
gl
.
p_glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MAG_FILTER
,
GL_NEAREST
);
gl_info
->
gl_ops
.
gl
.
p_glTexImage2D
(
GL_TEXTURE_2D
,
0
,
GL_RGB8
,
4
,
1
,
0
,
GL_BGRA
,
GL_UNSIGNED_INT_8_8_8_8_REV
,
NULL
);
checkGLcall
(
"glTexImage2D"
);
gl_info
->
fbo_ops
.
glGenFramebuffers
(
1
,
&
fbo
);
gl_info
->
fbo_ops
.
glBindFramebuffer
(
GL_FRAMEBUFFER
,
fbo
);
gl_info
->
fbo_ops
.
glFramebufferTexture2D
(
GL_FRAMEBUFFER
,
GL_COLOR_ATTACHMENT0
,
GL_TEXTURE_2D
,
tex
,
0
);
checkGLcall
(
"glFramebufferTexture2D"
);
status
=
gl_info
->
fbo_ops
.
glCheckFramebufferStatus
(
GL_FRAMEBUFFER
);
if
(
status
!=
GL_FRAMEBUFFER_COMPLETE
)
ERR
(
"FBO status %#x
\n
"
,
status
);
checkGLcall
(
"glCheckFramebufferStatus"
);
gl_info
->
gl_ops
.
gl
.
p_glClearColor
(
0
.
0
f
,
0
.
0
f
,
1
.
0
f
,
0
.
0
f
);
gl_info
->
gl_ops
.
gl
.
p_glClear
(
GL_COLOR_BUFFER_BIT
);
checkGLcall
(
"glClear"
);
gl_info
->
gl_ops
.
gl
.
p_glViewport
(
0
,
0
,
4
,
1
);
checkGLcall
(
"glViewport"
);
gl_info
->
gl_ops
.
gl
.
p_glEnable
(
GL_FOG
);
gl_info
->
gl_ops
.
gl
.
p_glFogf
(
GL_FOG_START
,
0
.
5
f
);
gl_info
->
gl_ops
.
gl
.
p_glFogf
(
GL_FOG_END
,
0
.
5
f
);
gl_info
->
gl_ops
.
gl
.
p_glFogi
(
GL_FOG_MODE
,
GL_LINEAR
);
gl_info
->
gl_ops
.
gl
.
p_glHint
(
GL_FOG_HINT
,
GL_NICEST
);
gl_info
->
gl_ops
.
gl
.
p_glFogfv
(
GL_FOG_COLOR
,
color
);
checkGLcall
(
"fog setup"
);
GL_EXTCALL
(
glGenProgramsARB
(
1
,
&
prog
));
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
prog
));
GL_EXTCALL
(
glProgramStringARB
(
GL_FRAGMENT_PROGRAM_ARB
,
GL_PROGRAM_FORMAT_ASCII_ARB
,
strlen
(
program_code
),
program_code
));
gl_info
->
gl_ops
.
gl
.
p_glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"Test fragment program setup"
);
gl_info
->
gl_ops
.
gl
.
p_glGetIntegerv
(
GL_PROGRAM_ERROR_POSITION_ARB
,
&
err_pos
);
if
(
err_pos
!=
-
1
)
{
const
char
*
error_str
;
error_str
=
(
const
char
*
)
gl_info
->
gl_ops
.
gl
.
p_glGetString
(
GL_PROGRAM_ERROR_STRING_ARB
);
FIXME
(
"Fog test program error at position %d: %s
\n\n
"
,
err_pos
,
debugstr_a
(
error_str
));
}
gl_info
->
gl_ops
.
gl
.
p_glBegin
(
GL_TRIANGLE_STRIP
);
gl_info
->
gl_ops
.
gl
.
p_glVertex3f
(
-
1
.
0
f
,
-
1
.
0
f
,
0
.
0
f
);
gl_info
->
gl_ops
.
gl
.
p_glVertex3f
(
1
.
0
f
,
-
1
.
0
f
,
1
.
0
f
);
gl_info
->
gl_ops
.
gl
.
p_glVertex3f
(
-
1
.
0
f
,
1
.
0
f
,
0
.
0
f
);
gl_info
->
gl_ops
.
gl
.
p_glVertex3f
(
1
.
0
f
,
1
.
0
f
,
1
.
0
f
);
gl_info
->
gl_ops
.
gl
.
p_glEnd
();
checkGLcall
(
"ARBfp fog test draw"
);
gl_info
->
gl_ops
.
gl
.
p_glGetTexImage
(
GL_TEXTURE_2D
,
0
,
GL_BGRA
,
GL_UNSIGNED_INT_8_8_8_8_REV
,
data
);
checkGLcall
(
"glGetTexImage"
);
data
[
0
]
&=
0x00ffffff
;
data
[
1
]
&=
0x00ffffff
;
data
[
2
]
&=
0x00ffffff
;
data
[
3
]
&=
0x00ffffff
;
gl_info
->
fbo_ops
.
glBindFramebuffer
(
GL_FRAMEBUFFER
,
0
);
gl_info
->
gl_ops
.
gl
.
p_glBindTexture
(
GL_TEXTURE_2D
,
0
);
gl_info
->
fbo_ops
.
glDeleteFramebuffers
(
1
,
&
fbo
);
gl_info
->
gl_ops
.
gl
.
p_glDeleteTextures
(
1
,
&
tex
);
gl_info
->
gl_ops
.
gl
.
p_glDisable
(
GL_FOG
);
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
0
));
gl_info
->
gl_ops
.
gl
.
p_glDisable
(
GL_FRAGMENT_PROGRAM_ARB
);
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
prog
));
checkGLcall
(
"ARBfp fog test teardown"
);
TRACE
(
"Fog test data: %08x %08x %08x %08x
\n
"
,
data
[
0
],
data
[
1
],
data
[
2
],
data
[
3
]);
return
data
[
0
]
!=
0x00ff0000
||
data
[
3
]
!=
0x0000ff00
;
}
static
void
quirk_apple_glsl_constants
(
struct
wined3d_gl_info
*
gl_info
)
{
/* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
...
...
@@ -914,6 +1009,11 @@ static void quirk_r200_constants(struct wined3d_gl_info *gl_info)
gl_info
->
reserved_arb_constants
=
max
(
gl_info
->
reserved_arb_constants
,
1
);
}
static
void
quirk_broken_arb_fog
(
struct
wined3d_gl_info
*
gl_info
)
{
gl_info
->
quirks
|=
WINED3D_QUIRK_BROKEN_ARB_FOG
;
}
struct
driver_quirk
{
BOOL
(
*
match
)(
const
struct
wined3d_gl_info
*
gl_info
,
const
char
*
gl_renderer
,
...
...
@@ -999,6 +1099,11 @@ static const struct driver_quirk quirk_table[] =
quirk_r200_constants
,
"r200 vertex shader constants"
},
{
match_broken_arb_fog
,
quirk_broken_arb_fog
,
"ARBfp fogstart == fogend workaround"
},
};
/* Certain applications (Steam) complain if we report an outdated driver version. In general,
...
...
dlls/wined3d/wined3d_private.h
View file @
22319c7f
...
...
@@ -62,6 +62,7 @@
#define WINED3D_QUIRK_BROKEN_RGBA16 0x00000040
#define WINED3D_QUIRK_INFO_LOG_SPAM 0x00000080
#define WINED3D_QUIRK_LIMITED_TEX_FILTERING 0x00000100
#define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200
/* Texture format fixups */
...
...
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