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
732a9a15
Commit
732a9a15
authored
May 26, 2009
by
Stefan Dösinger
Committed by
Alexandre Julliard
May 28, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Remove the forward declaration added in the last patch.
parent
d0d681c8
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
401 additions
and
407 deletions
+401
-407
arb_program_shader.c
dlls/wined3d/arb_program_shader.c
+223
-227
glsl_shader.c
dlls/wined3d/glsl_shader.c
+178
-180
No files found.
dlls/wined3d/arb_program_shader.c
View file @
732a9a15
...
...
@@ -1926,232 +1926,6 @@ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en
return
program_id
;
}
static
GLuint
shader_arb_generate_pshader
(
IWineD3DPixelShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
ps_compile_args
*
args
);
/* GL locking is done by the caller */
static
GLuint
find_arb_pshader
(
IWineD3DPixelShaderImpl
*
shader
,
const
struct
ps_compile_args
*
args
)
{
UINT
i
;
DWORD
new_size
;
struct
ps_compiled_shader
*
new_array
;
SHADER_BUFFER
buffer
;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
* (cache coherency etc)
*/
for
(
i
=
0
;
i
<
shader
->
num_gl_shaders
;
i
++
)
{
if
(
memcmp
(
&
shader
->
gl_shaders
[
i
].
args
,
args
,
sizeof
(
*
args
))
==
0
)
{
return
shader
->
gl_shaders
[
i
].
prgId
;
}
}
TRACE
(
"No matching GL shader found, compiling a new shader
\n
"
);
if
(
shader
->
shader_array_size
==
shader
->
num_gl_shaders
)
{
if
(
shader
->
num_gl_shaders
)
{
new_size
=
shader
->
shader_array_size
+
max
(
1
,
shader
->
shader_array_size
/
2
);
new_array
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
shader
->
gl_shaders
,
new_size
*
sizeof
(
*
shader
->
gl_shaders
));
}
else
{
new_array
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
shader
->
gl_shaders
));
new_size
=
1
;
}
if
(
!
new_array
)
{
ERR
(
"Out of memory
\n
"
);
return
0
;
}
shader
->
gl_shaders
=
new_array
;
shader
->
shader_array_size
=
new_size
;
}
shader
->
gl_shaders
[
shader
->
num_gl_shaders
].
args
=
*
args
;
pixelshader_update_samplers
(
&
shader
->
baseShader
.
reg_maps
,
((
IWineD3DDeviceImpl
*
)
shader
->
baseShader
.
device
)
->
stateBlock
->
textures
);
shader_buffer_init
(
&
buffer
);
shader
->
gl_shaders
[
shader
->
num_gl_shaders
].
prgId
=
shader_arb_generate_pshader
((
IWineD3DPixelShader
*
)
shader
,
&
buffer
,
args
);
shader_buffer_free
(
&
buffer
);
return
shader
->
gl_shaders
[
shader
->
num_gl_shaders
++
].
prgId
;
}
/* GL locking is done by the caller */
static
void
shader_arb_select
(
IWineD3DDevice
*
iface
,
BOOL
usePS
,
BOOL
useVS
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
useVS
)
{
struct
vs_compile_args
compile_args
;
TRACE
(
"Using vertex shader
\n
"
);
find_vs_compile_args
((
IWineD3DVertexShaderImpl
*
)
This
->
stateBlock
->
vertexShader
,
This
->
stateBlock
,
&
compile_args
);
priv
->
current_vprogram_id
=
find_gl_vshader
((
IWineD3DVertexShaderImpl
*
)
This
->
stateBlock
->
vertexShader
,
&
compile_args
);
/* Bind the vertex program */
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
priv
->
current_vprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);"
);
/* Enable OpenGL vertex programs */
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_VERTEX_PROGRAM_ARB);"
);
TRACE
(
"(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_vprogram_id
);
}
else
if
(
GL_SUPPORT
(
ARB_VERTEX_PROGRAM
))
{
priv
->
current_vprogram_id
=
0
;
glDisable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_VERTEX_PROGRAM_ARB)"
);
}
if
(
usePS
)
{
struct
ps_compile_args
compile_args
;
TRACE
(
"Using pixel shader
\n
"
);
find_ps_compile_args
((
IWineD3DPixelShaderImpl
*
)
This
->
stateBlock
->
pixelShader
,
This
->
stateBlock
,
&
compile_args
);
priv
->
current_fprogram_id
=
find_arb_pshader
((
IWineD3DPixelShaderImpl
*
)
This
->
stateBlock
->
pixelShader
,
&
compile_args
);
/* Bind the fragment program */
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
priv
->
current_fprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id);"
);
if
(
!
priv
->
use_arbfp_fixed_func
)
{
/* Enable OpenGL fragment programs */
glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_FRAGMENT_PROGRAM_ARB);"
);
}
TRACE
(
"(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_fprogram_id
);
shader_arb_ps_local_constants
(
This
);
}
else
if
(
GL_SUPPORT
(
ARB_FRAGMENT_PROGRAM
)
&&
!
priv
->
use_arbfp_fixed_func
)
{
/* Disable only if we're not using arbfp fixed function fragment processing. If this is used,
* keep GL_FRAGMENT_PROGRAM_ARB enabled, and the fixed function pipeline will bind the fixed function
* replacement shader
*/
glDisable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_FRAGMENT_PROGRAM_ARB)"
);
priv
->
current_fprogram_id
=
0
;
}
}
/* GL locking is done by the caller */
static
void
shader_arb_select_depth_blt
(
IWineD3DDevice
*
iface
,
enum
tex_types
tex_type
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
GLuint
*
blt_fprogram
=
&
priv
->
depth_blt_fprogram_id
[
tex_type
];
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
!
priv
->
depth_blt_vprogram_id
)
priv
->
depth_blt_vprogram_id
=
create_arb_blt_vertex_program
(
gl_info
);
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
priv
->
depth_blt_vprogram_id
));
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
if
(
!*
blt_fprogram
)
*
blt_fprogram
=
create_arb_blt_fragment_program
(
gl_info
,
tex_type
);
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
*
blt_fprogram
));
glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
}
/* GL locking is done by the caller */
static
void
shader_arb_deselect_depth_blt
(
IWineD3DDevice
*
iface
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
priv
->
current_vprogram_id
)
{
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
priv
->
current_vprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);"
);
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_VERTEX_PROGRAM_ARB);"
);
TRACE
(
"(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_vprogram_id
);
}
else
{
glDisable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_VERTEX_PROGRAM_ARB)"
);
}
if
(
priv
->
current_fprogram_id
)
{
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
priv
->
current_fprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);"
);
glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_FRAGMENT_PROGRAM_ARB);"
);
TRACE
(
"(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_fprogram_id
);
}
else
{
glDisable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_FRAGMENT_PROGRAM_ARB)"
);
}
}
static
void
shader_arb_destroy
(
IWineD3DBaseShader
*
iface
)
{
IWineD3DBaseShaderImpl
*
baseShader
=
(
IWineD3DBaseShaderImpl
*
)
iface
;
const
WineD3D_GL_Info
*
gl_info
=
&
((
IWineD3DDeviceImpl
*
)
baseShader
->
baseShader
.
device
)
->
adapter
->
gl_info
;
if
(
shader_is_pshader_version
(
baseShader
->
baseShader
.
reg_maps
.
shader_version
.
type
))
{
IWineD3DPixelShaderImpl
*
This
=
(
IWineD3DPixelShaderImpl
*
)
iface
;
UINT
i
;
ENTER_GL
();
for
(
i
=
0
;
i
<
This
->
num_gl_shaders
;
i
++
)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
This
->
gl_shaders
[
i
].
prgId
));
checkGLcall
(
"GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))"
);
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
This
->
gl_shaders
);
This
->
gl_shaders
=
NULL
;
This
->
num_gl_shaders
=
0
;
This
->
shader_array_size
=
0
;
}
else
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
UINT
i
;
ENTER_GL
();
for
(
i
=
0
;
i
<
This
->
num_gl_shaders
;
i
++
)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
This
->
gl_shaders
[
i
].
prgId
));
checkGLcall
(
"GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))"
);
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
This
->
gl_shaders
);
This
->
gl_shaders
=
NULL
;
This
->
num_gl_shaders
=
0
;
This
->
shader_array_size
=
0
;
}
}
static
HRESULT
shader_arb_alloc
(
IWineD3DDevice
*
iface
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
This
->
shader_priv
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
struct
shader_arb_priv
));
return
WINED3D_OK
;
}
static
void
shader_arb_free
(
IWineD3DDevice
*
iface
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
int
i
;
ENTER_GL
();
if
(
priv
->
depth_blt_vprogram_id
)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
priv
->
depth_blt_vprogram_id
));
}
for
(
i
=
0
;
i
<
tex_type_count
;
++
i
)
{
if
(
priv
->
depth_blt_fprogram_id
[
i
])
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
priv
->
depth_blt_fprogram_id
[
i
]));
}
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
This
->
shader_priv
);
}
static
BOOL
shader_arb_dirty_const
(
IWineD3DDevice
*
iface
)
{
return
TRUE
;
}
static
void
arbfp_add_sRGB_correction
(
SHADER_BUFFER
*
buffer
,
const
char
*
fragcolor
,
const
char
*
tmp1
,
const
char
*
tmp2
,
const
char
*
tmp3
)
{
/* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
...
...
@@ -2169,7 +1943,6 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol
shader_addline
(
buffer
,
"CMP result.color.xyz, %s, %s, %s;
\n
"
,
tmp3
,
tmp2
,
tmp1
);
}
/* GL locking is done by the caller */
static
GLuint
shader_arb_generate_pshader
(
IWineD3DPixelShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
ps_compile_args
*
args
)
{
...
...
@@ -2427,6 +2200,229 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface,
return
ret
;
}
/* GL locking is done by the caller */
static
GLuint
find_arb_pshader
(
IWineD3DPixelShaderImpl
*
shader
,
const
struct
ps_compile_args
*
args
)
{
UINT
i
;
DWORD
new_size
;
struct
ps_compiled_shader
*
new_array
;
SHADER_BUFFER
buffer
;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
* (cache coherency etc)
*/
for
(
i
=
0
;
i
<
shader
->
num_gl_shaders
;
i
++
)
{
if
(
memcmp
(
&
shader
->
gl_shaders
[
i
].
args
,
args
,
sizeof
(
*
args
))
==
0
)
{
return
shader
->
gl_shaders
[
i
].
prgId
;
}
}
TRACE
(
"No matching GL shader found, compiling a new shader
\n
"
);
if
(
shader
->
shader_array_size
==
shader
->
num_gl_shaders
)
{
if
(
shader
->
num_gl_shaders
)
{
new_size
=
shader
->
shader_array_size
+
max
(
1
,
shader
->
shader_array_size
/
2
);
new_array
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
shader
->
gl_shaders
,
new_size
*
sizeof
(
*
shader
->
gl_shaders
));
}
else
{
new_array
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
shader
->
gl_shaders
));
new_size
=
1
;
}
if
(
!
new_array
)
{
ERR
(
"Out of memory
\n
"
);
return
0
;
}
shader
->
gl_shaders
=
new_array
;
shader
->
shader_array_size
=
new_size
;
}
shader
->
gl_shaders
[
shader
->
num_gl_shaders
].
args
=
*
args
;
pixelshader_update_samplers
(
&
shader
->
baseShader
.
reg_maps
,
((
IWineD3DDeviceImpl
*
)
shader
->
baseShader
.
device
)
->
stateBlock
->
textures
);
shader_buffer_init
(
&
buffer
);
shader
->
gl_shaders
[
shader
->
num_gl_shaders
].
prgId
=
shader_arb_generate_pshader
((
IWineD3DPixelShader
*
)
shader
,
&
buffer
,
args
);
shader_buffer_free
(
&
buffer
);
return
shader
->
gl_shaders
[
shader
->
num_gl_shaders
++
].
prgId
;
}
/* GL locking is done by the caller */
static
void
shader_arb_select
(
IWineD3DDevice
*
iface
,
BOOL
usePS
,
BOOL
useVS
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
useVS
)
{
struct
vs_compile_args
compile_args
;
TRACE
(
"Using vertex shader
\n
"
);
find_vs_compile_args
((
IWineD3DVertexShaderImpl
*
)
This
->
stateBlock
->
vertexShader
,
This
->
stateBlock
,
&
compile_args
);
priv
->
current_vprogram_id
=
find_gl_vshader
((
IWineD3DVertexShaderImpl
*
)
This
->
stateBlock
->
vertexShader
,
&
compile_args
);
/* Bind the vertex program */
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
priv
->
current_vprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);"
);
/* Enable OpenGL vertex programs */
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_VERTEX_PROGRAM_ARB);"
);
TRACE
(
"(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_vprogram_id
);
}
else
if
(
GL_SUPPORT
(
ARB_VERTEX_PROGRAM
))
{
priv
->
current_vprogram_id
=
0
;
glDisable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_VERTEX_PROGRAM_ARB)"
);
}
if
(
usePS
)
{
struct
ps_compile_args
compile_args
;
TRACE
(
"Using pixel shader
\n
"
);
find_ps_compile_args
((
IWineD3DPixelShaderImpl
*
)
This
->
stateBlock
->
pixelShader
,
This
->
stateBlock
,
&
compile_args
);
priv
->
current_fprogram_id
=
find_arb_pshader
((
IWineD3DPixelShaderImpl
*
)
This
->
stateBlock
->
pixelShader
,
&
compile_args
);
/* Bind the fragment program */
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
priv
->
current_fprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id);"
);
if
(
!
priv
->
use_arbfp_fixed_func
)
{
/* Enable OpenGL fragment programs */
glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_FRAGMENT_PROGRAM_ARB);"
);
}
TRACE
(
"(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_fprogram_id
);
shader_arb_ps_local_constants
(
This
);
}
else
if
(
GL_SUPPORT
(
ARB_FRAGMENT_PROGRAM
)
&&
!
priv
->
use_arbfp_fixed_func
)
{
/* Disable only if we're not using arbfp fixed function fragment processing. If this is used,
* keep GL_FRAGMENT_PROGRAM_ARB enabled, and the fixed function pipeline will bind the fixed function
* replacement shader
*/
glDisable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_FRAGMENT_PROGRAM_ARB)"
);
priv
->
current_fprogram_id
=
0
;
}
}
/* GL locking is done by the caller */
static
void
shader_arb_select_depth_blt
(
IWineD3DDevice
*
iface
,
enum
tex_types
tex_type
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
GLuint
*
blt_fprogram
=
&
priv
->
depth_blt_fprogram_id
[
tex_type
];
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
!
priv
->
depth_blt_vprogram_id
)
priv
->
depth_blt_vprogram_id
=
create_arb_blt_vertex_program
(
gl_info
);
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
priv
->
depth_blt_vprogram_id
));
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
if
(
!*
blt_fprogram
)
*
blt_fprogram
=
create_arb_blt_fragment_program
(
gl_info
,
tex_type
);
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
*
blt_fprogram
));
glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
}
/* GL locking is done by the caller */
static
void
shader_arb_deselect_depth_blt
(
IWineD3DDevice
*
iface
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
priv
->
current_vprogram_id
)
{
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
priv
->
current_vprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);"
);
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_VERTEX_PROGRAM_ARB);"
);
TRACE
(
"(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_vprogram_id
);
}
else
{
glDisable
(
GL_VERTEX_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_VERTEX_PROGRAM_ARB)"
);
}
if
(
priv
->
current_fprogram_id
)
{
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
priv
->
current_fprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);"
);
glEnable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glEnable(GL_FRAGMENT_PROGRAM_ARB);"
);
TRACE
(
"(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB
\n
"
,
This
,
priv
->
current_fprogram_id
);
}
else
{
glDisable
(
GL_FRAGMENT_PROGRAM_ARB
);
checkGLcall
(
"glDisable(GL_FRAGMENT_PROGRAM_ARB)"
);
}
}
static
void
shader_arb_destroy
(
IWineD3DBaseShader
*
iface
)
{
IWineD3DBaseShaderImpl
*
baseShader
=
(
IWineD3DBaseShaderImpl
*
)
iface
;
const
WineD3D_GL_Info
*
gl_info
=
&
((
IWineD3DDeviceImpl
*
)
baseShader
->
baseShader
.
device
)
->
adapter
->
gl_info
;
if
(
shader_is_pshader_version
(
baseShader
->
baseShader
.
reg_maps
.
shader_version
.
type
))
{
IWineD3DPixelShaderImpl
*
This
=
(
IWineD3DPixelShaderImpl
*
)
iface
;
UINT
i
;
ENTER_GL
();
for
(
i
=
0
;
i
<
This
->
num_gl_shaders
;
i
++
)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
This
->
gl_shaders
[
i
].
prgId
));
checkGLcall
(
"GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))"
);
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
This
->
gl_shaders
);
This
->
gl_shaders
=
NULL
;
This
->
num_gl_shaders
=
0
;
This
->
shader_array_size
=
0
;
}
else
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
UINT
i
;
ENTER_GL
();
for
(
i
=
0
;
i
<
This
->
num_gl_shaders
;
i
++
)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
This
->
gl_shaders
[
i
].
prgId
));
checkGLcall
(
"GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))"
);
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
This
->
gl_shaders
);
This
->
gl_shaders
=
NULL
;
This
->
num_gl_shaders
=
0
;
This
->
shader_array_size
=
0
;
}
}
static
HRESULT
shader_arb_alloc
(
IWineD3DDevice
*
iface
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
This
->
shader_priv
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
struct
shader_arb_priv
));
return
WINED3D_OK
;
}
static
void
shader_arb_free
(
IWineD3DDevice
*
iface
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
struct
shader_arb_priv
*
priv
=
This
->
shader_priv
;
int
i
;
ENTER_GL
();
if
(
priv
->
depth_blt_vprogram_id
)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
priv
->
depth_blt_vprogram_id
));
}
for
(
i
=
0
;
i
<
tex_type_count
;
++
i
)
{
if
(
priv
->
depth_blt_fprogram_id
[
i
])
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
priv
->
depth_blt_fprogram_id
[
i
]));
}
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
This
->
shader_priv
);
}
static
BOOL
shader_arb_dirty_const
(
IWineD3DDevice
*
iface
)
{
return
TRUE
;
}
static
void
shader_arb_get_caps
(
WINED3DDEVTYPE
devtype
,
const
WineD3D_GL_Info
*
gl_info
,
struct
shader_caps
*
pCaps
)
{
/* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
...
...
dlls/wined3d/glsl_shader.c
View file @
732a9a15
...
...
@@ -3608,8 +3608,185 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD
checkGLcall
(
"Hardcoding local constants
\n
"
);
}
/* GL locking is done by the caller */
static
GLuint
shader_glsl_generate_pshader
(
IWineD3DPixelShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
ps_compile_args
*
args
);
SHADER_BUFFER
*
buffer
,
const
struct
ps_compile_args
*
args
)
{
IWineD3DPixelShaderImpl
*
This
=
(
IWineD3DPixelShaderImpl
*
)
iface
;
const
struct
shader_reg_maps
*
reg_maps
=
&
This
->
baseShader
.
reg_maps
;
CONST
DWORD
*
function
=
This
->
baseShader
.
function
;
const
char
*
fragcolor
;
const
WineD3D_GL_Info
*
gl_info
=
&
((
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
)
->
adapter
->
gl_info
;
struct
shader_glsl_ctx_priv
priv_ctx
;
/* Create the hw GLSL shader object and assign it as the shader->prgId */
GLhandleARB
shader_obj
=
GL_EXTCALL
(
glCreateShaderObjectARB
(
GL_FRAGMENT_SHADER_ARB
));
memset
(
&
priv_ctx
,
0
,
sizeof
(
priv_ctx
));
priv_ctx
.
cur_ps_args
=
args
;
shader_addline
(
buffer
,
"#version 120
\n
"
);
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
{
shader_addline
(
buffer
,
"#extension GL_ARB_draw_buffers : enable
\n
"
);
}
if
(
GL_SUPPORT
(
ARB_SHADER_TEXTURE_LOD
)
&&
reg_maps
->
usestexldd
)
{
shader_addline
(
buffer
,
"#extension GL_ARB_shader_texture_lod : enable
\n
"
);
}
if
(
GL_SUPPORT
(
ARB_TEXTURE_RECTANGLE
))
{
/* The spec says that it doesn't have to be explicitly enabled, but the nvidia
* drivers write a warning if we don't do so
*/
shader_addline
(
buffer
,
"#extension GL_ARB_texture_rectangle : enable
\n
"
);
}
/* Base Declarations */
shader_generate_glsl_declarations
(
(
IWineD3DBaseShader
*
)
This
,
reg_maps
,
buffer
,
&
GLINFO_LOCATION
,
args
);
/* Pack 3.0 inputs */
if
(
reg_maps
->
shader_version
.
major
>=
3
&&
args
->
vp_mode
!=
vertexshader
)
{
pshader_glsl_input_pack
(
iface
,
buffer
,
This
->
input_signature
,
reg_maps
,
args
->
vp_mode
);
}
/* Base Shader Body */
shader_generate_main
((
IWineD3DBaseShader
*
)
This
,
buffer
,
reg_maps
,
function
,
&
priv_ctx
);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if
(
reg_maps
->
shader_version
.
major
<
2
)
{
/* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
shader_addline
(
buffer
,
"gl_FragData[0] = R0;
\n
"
);
else
shader_addline
(
buffer
,
"gl_FragColor = R0;
\n
"
);
}
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
{
fragcolor
=
"gl_FragData[0]"
;
}
else
{
fragcolor
=
"gl_FragColor"
;
}
if
(
args
->
srgb_correction
)
{
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
);
shader_addline
(
buffer
,
"tmp1.xyz = %s.xyz * srgb_mul_low.xyz;
\n
"
,
fragcolor
);
shader_addline
(
buffer
,
"%s.x = %s.x < srgb_comparison.x ? tmp1.x : tmp0.x;
\n
"
,
fragcolor
,
fragcolor
);
shader_addline
(
buffer
,
"%s.y = %s.y < srgb_comparison.y ? tmp1.y : tmp0.y;
\n
"
,
fragcolor
,
fragcolor
);
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
(
reg_maps
->
shader_version
.
major
<
3
)
{
switch
(
args
->
fog
)
{
case
FOG_OFF
:
break
;
case
FOG_LINEAR
:
shader_addline
(
buffer
,
"float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start);
\n
"
);
shader_addline
(
buffer
,
"float fogend = gl_Fog.end * -fogstart;
\n
"
);
shader_addline
(
buffer
,
"float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0);
\n
"
);
shader_addline
(
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
break
;
case
FOG_EXP
:
/* Fog = e^(-gl_Fog.density * gl_FogFragCoord) */
shader_addline
(
buffer
,
"float Fog = exp(-gl_Fog.density * gl_FogFragCoord);
\n
"
);
shader_addline
(
buffer
,
"Fog = clamp(Fog, 0.0, 1.0);
\n
"
);
shader_addline
(
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
break
;
case
FOG_EXP2
:
/* Fog = e^(-(gl_Fog.density * gl_FogFragCoord)^2) */
shader_addline
(
buffer
,
"float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);
\n
"
);
shader_addline
(
buffer
,
"Fog = clamp(Fog, 0.0, 1.0);
\n
"
);
shader_addline
(
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
break
;
}
}
shader_addline
(
buffer
,
"}
\n
"
);
TRACE
(
"Compiling shader object %u
\n
"
,
shader_obj
);
GL_EXTCALL
(
glShaderSourceARB
(
shader_obj
,
1
,
(
const
char
**
)
&
buffer
->
buffer
,
NULL
));
GL_EXTCALL
(
glCompileShaderARB
(
shader_obj
));
print_glsl_info_log
(
&
GLINFO_LOCATION
,
shader_obj
);
/* Store the shader object */
return
shader_obj
;
}
/* GL locking is done by the caller */
/* GL locking is done by the caller */
static
GLuint
shader_glsl_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
vs_compile_args
*
args
)
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
const
struct
shader_reg_maps
*
reg_maps
=
&
This
->
baseShader
.
reg_maps
;
CONST
DWORD
*
function
=
This
->
baseShader
.
function
;
const
WineD3D_GL_Info
*
gl_info
=
&
((
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
)
->
adapter
->
gl_info
;
struct
shader_glsl_ctx_priv
priv_ctx
;
/* Create the hw GLSL shader program and assign it as the shader->prgId */
GLhandleARB
shader_obj
=
GL_EXTCALL
(
glCreateShaderObjectARB
(
GL_VERTEX_SHADER_ARB
));
shader_addline
(
buffer
,
"#version 120
\n
"
);
memset
(
&
priv_ctx
,
0
,
sizeof
(
priv_ctx
));
priv_ctx
.
cur_vs_args
=
args
;
/* Base Declarations */
shader_generate_glsl_declarations
(
(
IWineD3DBaseShader
*
)
This
,
reg_maps
,
buffer
,
&
GLINFO_LOCATION
,
NULL
);
/* Base Shader Body */
shader_generate_main
((
IWineD3DBaseShader
*
)
This
,
buffer
,
reg_maps
,
function
,
&
priv_ctx
);
/* Unpack 3.0 outputs */
if
(
reg_maps
->
shader_version
.
major
>=
3
)
shader_addline
(
buffer
,
"order_ps_input(OUT);
\n
"
);
else
shader_addline
(
buffer
,
"order_ps_input();
\n
"
);
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
* or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
* the fog frag coord is thrown away. If the fog frag coord is used, but not written by
* the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
*/
if
(
args
->
fog_src
==
VS_FOG_Z
)
{
shader_addline
(
buffer
,
"gl_FogFragCoord = gl_Position.z;
\n
"
);
}
else
if
(
!
reg_maps
->
fog
)
{
shader_addline
(
buffer
,
"gl_FogFragCoord = 0.0;
\n
"
);
}
/* Write the final position.
*
* OpenGL coordinates specify the center of the pixel while d3d coords specify
* the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
* 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
* contains 1.0 to allow a mad.
*/
shader_addline
(
buffer
,
"gl_Position.y = gl_Position.y * posFixup.y;
\n
"
);
shader_addline
(
buffer
,
"gl_Position.xy += posFixup.zw * gl_Position.ww;
\n
"
);
shader_addline
(
buffer
,
"gl_ClipVertex = gl_Position;
\n
"
);
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
*
* Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run
* before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w,
* which is the same as z = z * 2 - w.
*/
shader_addline
(
buffer
,
"gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;
\n
"
);
shader_addline
(
buffer
,
"}
\n
"
);
TRACE
(
"Compiling shader object %u
\n
"
,
shader_obj
);
GL_EXTCALL
(
glShaderSourceARB
(
shader_obj
,
1
,
(
const
char
**
)
&
buffer
->
buffer
,
NULL
));
GL_EXTCALL
(
glCompileShaderARB
(
shader_obj
));
print_glsl_info_log
(
&
GLINFO_LOCATION
,
shader_obj
);
return
shader_obj
;
}
static
GLhandleARB
find_glsl_pshader
(
IWineD3DPixelShaderImpl
*
shader
,
const
struct
ps_compile_args
*
args
)
{
...
...
@@ -4213,185 +4390,6 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
return
FALSE
;
}
/* GL locking is done by the caller */
static
GLuint
shader_glsl_generate_pshader
(
IWineD3DPixelShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
ps_compile_args
*
args
)
{
IWineD3DPixelShaderImpl
*
This
=
(
IWineD3DPixelShaderImpl
*
)
iface
;
const
struct
shader_reg_maps
*
reg_maps
=
&
This
->
baseShader
.
reg_maps
;
CONST
DWORD
*
function
=
This
->
baseShader
.
function
;
const
char
*
fragcolor
;
const
WineD3D_GL_Info
*
gl_info
=
&
((
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
)
->
adapter
->
gl_info
;
struct
shader_glsl_ctx_priv
priv_ctx
;
/* Create the hw GLSL shader object and assign it as the shader->prgId */
GLhandleARB
shader_obj
=
GL_EXTCALL
(
glCreateShaderObjectARB
(
GL_FRAGMENT_SHADER_ARB
));
memset
(
&
priv_ctx
,
0
,
sizeof
(
priv_ctx
));
priv_ctx
.
cur_ps_args
=
args
;
shader_addline
(
buffer
,
"#version 120
\n
"
);
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
{
shader_addline
(
buffer
,
"#extension GL_ARB_draw_buffers : enable
\n
"
);
}
if
(
GL_SUPPORT
(
ARB_SHADER_TEXTURE_LOD
)
&&
reg_maps
->
usestexldd
)
{
shader_addline
(
buffer
,
"#extension GL_ARB_shader_texture_lod : enable
\n
"
);
}
if
(
GL_SUPPORT
(
ARB_TEXTURE_RECTANGLE
))
{
/* The spec says that it doesn't have to be explicitly enabled, but the nvidia
* drivers write a warning if we don't do so
*/
shader_addline
(
buffer
,
"#extension GL_ARB_texture_rectangle : enable
\n
"
);
}
/* Base Declarations */
shader_generate_glsl_declarations
(
(
IWineD3DBaseShader
*
)
This
,
reg_maps
,
buffer
,
&
GLINFO_LOCATION
,
args
);
/* Pack 3.0 inputs */
if
(
reg_maps
->
shader_version
.
major
>=
3
&&
args
->
vp_mode
!=
vertexshader
)
{
pshader_glsl_input_pack
(
iface
,
buffer
,
This
->
input_signature
,
reg_maps
,
args
->
vp_mode
);
}
/* Base Shader Body */
shader_generate_main
((
IWineD3DBaseShader
*
)
This
,
buffer
,
reg_maps
,
function
,
&
priv_ctx
);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if
(
reg_maps
->
shader_version
.
major
<
2
)
{
/* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
shader_addline
(
buffer
,
"gl_FragData[0] = R0;
\n
"
);
else
shader_addline
(
buffer
,
"gl_FragColor = R0;
\n
"
);
}
if
(
GL_SUPPORT
(
ARB_DRAW_BUFFERS
))
{
fragcolor
=
"gl_FragData[0]"
;
}
else
{
fragcolor
=
"gl_FragColor"
;
}
if
(
args
->
srgb_correction
)
{
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
);
shader_addline
(
buffer
,
"tmp1.xyz = %s.xyz * srgb_mul_low.xyz;
\n
"
,
fragcolor
);
shader_addline
(
buffer
,
"%s.x = %s.x < srgb_comparison.x ? tmp1.x : tmp0.x;
\n
"
,
fragcolor
,
fragcolor
);
shader_addline
(
buffer
,
"%s.y = %s.y < srgb_comparison.y ? tmp1.y : tmp0.y;
\n
"
,
fragcolor
,
fragcolor
);
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
(
reg_maps
->
shader_version
.
major
<
3
)
{
switch
(
args
->
fog
)
{
case
FOG_OFF
:
break
;
case
FOG_LINEAR
:
shader_addline
(
buffer
,
"float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start);
\n
"
);
shader_addline
(
buffer
,
"float fogend = gl_Fog.end * -fogstart;
\n
"
);
shader_addline
(
buffer
,
"float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0);
\n
"
);
shader_addline
(
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
break
;
case
FOG_EXP
:
/* Fog = e^(-gl_Fog.density * gl_FogFragCoord) */
shader_addline
(
buffer
,
"float Fog = exp(-gl_Fog.density * gl_FogFragCoord);
\n
"
);
shader_addline
(
buffer
,
"Fog = clamp(Fog, 0.0, 1.0);
\n
"
);
shader_addline
(
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
break
;
case
FOG_EXP2
:
/* Fog = e^(-(gl_Fog.density * gl_FogFragCoord)^2) */
shader_addline
(
buffer
,
"float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);
\n
"
);
shader_addline
(
buffer
,
"Fog = clamp(Fog, 0.0, 1.0);
\n
"
);
shader_addline
(
buffer
,
"%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);
\n
"
,
fragcolor
,
fragcolor
);
break
;
}
}
shader_addline
(
buffer
,
"}
\n
"
);
TRACE
(
"Compiling shader object %u
\n
"
,
shader_obj
);
GL_EXTCALL
(
glShaderSourceARB
(
shader_obj
,
1
,
(
const
char
**
)
&
buffer
->
buffer
,
NULL
));
GL_EXTCALL
(
glCompileShaderARB
(
shader_obj
));
print_glsl_info_log
(
&
GLINFO_LOCATION
,
shader_obj
);
/* Store the shader object */
return
shader_obj
;
}
/* GL locking is done by the caller */
static
GLuint
shader_glsl_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
vs_compile_args
*
args
)
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
const
struct
shader_reg_maps
*
reg_maps
=
&
This
->
baseShader
.
reg_maps
;
CONST
DWORD
*
function
=
This
->
baseShader
.
function
;
const
WineD3D_GL_Info
*
gl_info
=
&
((
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
)
->
adapter
->
gl_info
;
struct
shader_glsl_ctx_priv
priv_ctx
;
/* Create the hw GLSL shader program and assign it as the shader->prgId */
GLhandleARB
shader_obj
=
GL_EXTCALL
(
glCreateShaderObjectARB
(
GL_VERTEX_SHADER_ARB
));
shader_addline
(
buffer
,
"#version 120
\n
"
);
memset
(
&
priv_ctx
,
0
,
sizeof
(
priv_ctx
));
priv_ctx
.
cur_vs_args
=
args
;
/* Base Declarations */
shader_generate_glsl_declarations
(
(
IWineD3DBaseShader
*
)
This
,
reg_maps
,
buffer
,
&
GLINFO_LOCATION
,
NULL
);
/* Base Shader Body */
shader_generate_main
((
IWineD3DBaseShader
*
)
This
,
buffer
,
reg_maps
,
function
,
&
priv_ctx
);
/* Unpack 3.0 outputs */
if
(
reg_maps
->
shader_version
.
major
>=
3
)
shader_addline
(
buffer
,
"order_ps_input(OUT);
\n
"
);
else
shader_addline
(
buffer
,
"order_ps_input();
\n
"
);
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
* or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
* the fog frag coord is thrown away. If the fog frag coord is used, but not written by
* the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
*/
if
(
args
->
fog_src
==
VS_FOG_Z
)
{
shader_addline
(
buffer
,
"gl_FogFragCoord = gl_Position.z;
\n
"
);
}
else
if
(
!
reg_maps
->
fog
)
{
shader_addline
(
buffer
,
"gl_FogFragCoord = 0.0;
\n
"
);
}
/* Write the final position.
*
* OpenGL coordinates specify the center of the pixel while d3d coords specify
* the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
* 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
* contains 1.0 to allow a mad.
*/
shader_addline
(
buffer
,
"gl_Position.y = gl_Position.y * posFixup.y;
\n
"
);
shader_addline
(
buffer
,
"gl_Position.xy += posFixup.zw * gl_Position.ww;
\n
"
);
shader_addline
(
buffer
,
"gl_ClipVertex = gl_Position;
\n
"
);
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
*
* Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run
* before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w,
* which is the same as z = z * 2 - w.
*/
shader_addline
(
buffer
,
"gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;
\n
"
);
shader_addline
(
buffer
,
"}
\n
"
);
TRACE
(
"Compiling shader object %u
\n
"
,
shader_obj
);
GL_EXTCALL
(
glShaderSourceARB
(
shader_obj
,
1
,
(
const
char
**
)
&
buffer
->
buffer
,
NULL
));
GL_EXTCALL
(
glCompileShaderARB
(
shader_obj
));
print_glsl_info_log
(
&
GLINFO_LOCATION
,
shader_obj
);
return
shader_obj
;
}
static
void
shader_glsl_get_caps
(
WINED3DDEVTYPE
devtype
,
const
WineD3D_GL_Info
*
gl_info
,
struct
shader_caps
*
pCaps
)
{
/* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
...
...
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