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
8dcd5128
Commit
8dcd5128
authored
Feb 05, 2009
by
Stefan Dösinger
Committed by
Alexandre Julliard
Feb 11, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WineD3D: Put vertex shader duplication infrastructure in place.
parent
ad880ba0
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
167 additions
and
100 deletions
+167
-100
arb_program_shader.c
dlls/wined3d/arb_program_shader.c
+31
-23
baseshader.c
dlls/wined3d/baseshader.c
+2
-1
glsl_shader.c
dlls/wined3d/glsl_shader.c
+45
-25
vertexshader.c
dlls/wined3d/vertexshader.c
+62
-44
wined3d_private.h
dlls/wined3d/wined3d_private.h
+27
-7
No files found.
dlls/wined3d/arb_program_shader.c
View file @
8dcd5128
...
...
@@ -510,7 +510,7 @@ static void vshader_program_add_param(const SHADER_OPCODE_ARG *arg, const DWORD
break
;
case
WINED3DSPR_INPUT
:
if
(
This
->
swizzle_map
&
(
1
<<
reg
))
is_color
=
TRUE
;
if
(
This
->
cur_args
->
swizzle_map
&
(
1
<<
reg
))
is_color
=
TRUE
;
sprintf
(
tmpReg
,
"vertex.attrib[%u]"
,
reg
);
strcat
(
hwLine
,
tmpReg
);
...
...
@@ -1745,14 +1745,15 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
const
WineD3D_GL_Info
*
gl_info
=
&
This
->
adapter
->
gl_info
;
if
(
useVS
)
{
TRACE
(
"Using vertex shader
\n
"
);
IWineD3DVertexShaderImpl_CompileShader
(
This
->
stateBlock
->
vertexShader
);
struct
vs_compile_args
compile_args
;
priv
->
current_vprogram_id
=
((
IWineD3DVertexShaderImpl
*
)
This
->
stateBlock
->
vertexShader
)
->
prgId
;
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,
vertexShader->prgI
d);"
);
checkGLcall
(
"glBindProgramARB(GL_VERTEX_PROGRAM_ARB,
priv->current_vprogram_i
d);"
);
/* Enable OpenGL vertex programs */
glEnable
(
GL_VERTEX_PROGRAM_ARB
);
...
...
@@ -1773,7 +1774,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
/* Bind the fragment program */
GL_EXTCALL
(
glBindProgramARB
(
GL_FRAGMENT_PROGRAM_ARB
,
priv
->
current_fprogram_id
));
checkGLcall
(
"glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, p
ixelShader->prgI
d);"
);
checkGLcall
(
"glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, p
riv->current_fprogram_i
d);"
);
if
(
!
priv
->
use_arbfp_fixed_func
)
{
/* Enable OpenGL fragment programs */
...
...
@@ -1860,14 +1861,19 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
This
->
shader_array_size
=
0
;
}
else
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
UINT
i
;
ENTER_GL
();
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
This
->
prgId
));
checkGLcall
(
"GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId))"
);
((
IWineD3DVertexShaderImpl
*
)
This
)
->
prgId
=
0
;
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
;
}
baseShader
->
baseShader
.
is_compiled
=
FALSE
;
}
static
HRESULT
shader_arb_alloc
(
IWineD3DDevice
*
iface
)
{
...
...
@@ -2008,13 +2014,14 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
return
retval
;
}
static
void
shader_arb_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
)
{
static
GLuint
shader_arb_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
vs_compile_args
*
args
)
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
const
shader_reg_maps
*
reg_maps
=
&
This
->
baseShader
.
reg_maps
;
CONST
DWORD
*
function
=
This
->
baseShader
.
function
;
IWineD3DDeviceImpl
*
device
=
(
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
;
const
WineD3D_GL_Info
*
gl_info
=
&
device
->
adapter
->
gl_info
;
const
local_constant
*
lconst
;
GLuint
ret
;
/* Create the hw ARB shader */
shader_addline
(
buffer
,
"!!ARBvp1.0
\n
"
);
...
...
@@ -2086,12 +2093,12 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
shader_addline
(
buffer
,
"END
\n
"
);
/* TODO: change to resource.glObjectHandle or something like that */
GL_EXTCALL
(
glGenProgramsARB
(
1
,
&
This
->
prgId
));
GL_EXTCALL
(
glGenProgramsARB
(
1
,
&
ret
));
TRACE
(
"Creating a hw vertex shader, prg=%d
\n
"
,
This
->
prgId
);
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
This
->
prgId
));
TRACE
(
"Creating a hw vertex shader, prg=%d
\n
"
,
ret
);
GL_EXTCALL
(
glBindProgramARB
(
GL_VERTEX_PROGRAM_ARB
,
ret
));
TRACE
(
"Created hw vertex shader, prg=%d
\n
"
,
This
->
prgId
);
TRACE
(
"Created hw vertex shader, prg=%d
\n
"
,
ret
);
/* Create the program and check for errors */
GL_EXTCALL
(
glProgramStringARB
(
GL_VERTEX_PROGRAM_ARB
,
GL_PROGRAM_FORMAT_ASCII_ARB
,
buffer
->
bsize
,
buffer
->
buffer
));
...
...
@@ -2101,16 +2108,17 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
glGetIntegerv
(
GL_PROGRAM_ERROR_POSITION_ARB
,
&
errPos
);
FIXME
(
"HW VertexShader Error at position %d: %s
\n
"
,
errPos
,
debugstr_a
((
const
char
*
)
glGetString
(
GL_PROGRAM_ERROR_STRING_ARB
)));
This
->
prgId
=
-
1
;
}
/* Load immediate constants */
if
(
!
This
->
baseShader
.
load_local_constsF
)
{
LIST_FOR_EACH_ENTRY
(
lconst
,
&
This
->
baseShader
.
constantsF
,
local_constant
,
entry
)
{
const
float
*
value
=
(
const
float
*
)
lconst
->
value
;
GL_EXTCALL
(
glProgramLocalParameter4fvARB
(
GL_VERTEX_PROGRAM_ARB
,
lconst
->
idx
,
value
));
ret
=
-
1
;
}
else
{
/* Load immediate constants */
if
(
!
This
->
baseShader
.
load_local_constsF
)
{
LIST_FOR_EACH_ENTRY
(
lconst
,
&
This
->
baseShader
.
constantsF
,
local_constant
,
entry
)
{
const
float
*
value
=
(
const
float
*
)
lconst
->
value
;
GL_EXTCALL
(
glProgramLocalParameter4fvARB
(
GL_VERTEX_PROGRAM_ARB
,
lconst
->
idx
,
value
))
;
}
}
}
return
ret
;
}
static
void
shader_arb_get_caps
(
WINED3DDEVTYPE
devtype
,
const
WineD3D_GL_Info
*
gl_info
,
struct
shader_caps
*
pCaps
)
...
...
dlls/wined3d/baseshader.c
View file @
8dcd5128
...
...
@@ -1133,8 +1133,9 @@ static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
FIXME
(
"NONE shader backend asked to generate a pixel shader
\n
"
);
return
0
;
}
static
void
shader_none_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
)
{
static
GLuint
shader_none_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
vs_compile_args
*
args
)
{
FIXME
(
"NONE shader backend asked to generate a vertex shader
\n
"
);
return
0
;
}
#define GLINFO_LOCATION (*gl_info)
...
...
dlls/wined3d/glsl_shader.c
View file @
8dcd5128
...
...
@@ -101,16 +101,18 @@ struct glsl_shader_prog_link {
GLhandleARB
luminanceoffset_location
[
MAX_TEXTURES
];
GLhandleARB
ycorrection_location
;
GLenum
vertex_color_clamp
;
GLhandleARB
vshader
;
IWineD3DVertexShader
*
vshader
;
IWineD3DPixelShader
*
pshader
;
struct
vs_compile_args
vs_args
;
struct
ps_compile_args
ps_args
;
UINT
constant_version
;
};
typedef
struct
{
GLhandleARB
vshader
;
IWineD3DVertexShader
*
vshader
;
IWineD3DPixelShader
*
pshader
;
struct
ps_compile_args
ps_args
;
struct
vs_compile_args
vs_args
;
}
glsl_program_key_t
;
...
...
@@ -1030,7 +1032,7 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
strcpy
(
tmpStr
,
"gl_SecondaryColor"
);
}
}
else
{
if
(((
IWineD3DVertexShaderImpl
*
)
This
)
->
swizzle_map
&
(
1
<<
reg
))
*
is_color
=
TRUE
;
if
(((
IWineD3DVertexShaderImpl
*
)
This
)
->
cur_args
->
swizzle_map
&
(
1
<<
reg
))
*
is_color
=
TRUE
;
sprintf
(
tmpStr
,
"attrib%u"
,
reg
);
}
break
;
...
...
@@ -2918,17 +2920,20 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh
key
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
glsl_program_key_t
));
key
->
vshader
=
entry
->
vshader
;
key
->
pshader
=
entry
->
pshader
;
key
->
vs_args
=
entry
->
vs_args
;
key
->
ps_args
=
entry
->
ps_args
;
hash_table_put
(
priv
->
glsl_program_lookup
,
key
,
entry
);
}
static
struct
glsl_shader_prog_link
*
get_glsl_program_entry
(
struct
shader_glsl_priv
*
priv
,
GLhandleARB
vshader
,
IWineD3DPixelShader
*
pshader
,
struct
ps_compile_args
*
ps_args
)
{
IWineD3DVertexShader
*
vshader
,
IWineD3DPixelShader
*
pshader
,
struct
vs_compile_args
*
vs_args
,
struct
ps_compile_args
*
ps_args
)
{
glsl_program_key_t
key
;
key
.
vshader
=
vshader
;
key
.
pshader
=
pshader
;
key
.
vs_args
=
*
vs_args
;
key
.
ps_args
=
*
ps_args
;
return
hash_table_get
(
priv
->
glsl_program_lookup
,
&
key
);
...
...
@@ -2942,6 +2947,7 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD
key
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
glsl_program_key_t
));
key
->
vshader
=
entry
->
vshader
;
key
->
pshader
=
entry
->
pshader
;
key
->
vs_args
=
entry
->
vs_args
;
key
->
ps_args
=
entry
->
ps_args
;
hash_table_remove
(
priv
->
glsl_program_lookup
,
key
);
...
...
@@ -3293,21 +3299,22 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
int
i
;
char
glsl_name
[
8
];
GLhandleARB
vshader_id
,
pshader_id
;
struct
ps_compile_args
compile_args
;
struct
ps_compile_args
ps_compile_args
;
struct
vs_compile_args
vs_compile_args
;
if
(
use_vs
)
{
IWineD3DVertexShaderImpl_CompileShader
(
vshader
);
vshader_id
=
((
IWineD3DVertexShaderImpl
*
)
vshader
)
->
prgId
;
find_vs_compile_args
((
IWineD3DVertexShaderImpl
*
)
This
->
stateBlock
->
vertexShader
,
This
->
stateBlock
,
&
vs_compile_args
);
}
else
{
vshader_id
=
0
;
/* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
memset
(
&
vs_compile_args
,
0
,
sizeof
(
vs_compile_args
));
}
if
(
use_ps
)
{
find_ps_compile_args
((
IWineD3DPixelShaderImpl
*
)
This
->
stateBlock
->
pixelShader
,
This
->
stateBlock
,
&
compile_args
);
find_ps_compile_args
((
IWineD3DPixelShaderImpl
*
)
This
->
stateBlock
->
pixelShader
,
This
->
stateBlock
,
&
ps_
compile_args
);
}
else
{
/* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
memset
(
&
compile_args
,
0
,
sizeof
(
compile_args
));
memset
(
&
ps_compile_args
,
0
,
sizeof
(
ps_
compile_args
));
}
entry
=
get_glsl_program_entry
(
priv
,
vshader
_id
,
pshader
,
&
compile_args
);
entry
=
get_glsl_program_entry
(
priv
,
vshader
,
pshader
,
&
vs_compile_args
,
&
ps_
compile_args
);
if
(
entry
)
{
priv
->
glsl_program
=
entry
;
return
;
...
...
@@ -3320,9 +3327,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
/* Create the entry */
entry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
glsl_shader_prog_link
));
entry
->
programId
=
programId
;
entry
->
vshader
=
vshader
_id
;
entry
->
vshader
=
vshader
;
entry
->
pshader
=
pshader
;
entry
->
ps_args
=
compile_args
;
entry
->
vs_args
=
vs_compile_args
;
entry
->
ps_args
=
ps_compile_args
;
entry
->
constant_version
=
0
;
/* Add the hash table entry */
add_glsl_program_entry
(
priv
,
entry
);
...
...
@@ -3330,6 +3338,12 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
/* Set the current program */
priv
->
glsl_program
=
entry
;
if
(
use_vs
)
{
vshader_id
=
find_gl_vshader
((
IWineD3DVertexShaderImpl
*
)
vshader
,
&
vs_compile_args
);
}
else
{
vshader_id
=
0
;
}
/* Attach GLSL vshader */
if
(
vshader_id
)
{
int
max_attribs
=
16
;
/* TODO: Will this always be the case? It is at the moment... */
...
...
@@ -3369,7 +3383,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
}
if
(
use_ps
)
{
pshader_id
=
find_gl_pshader
((
IWineD3DPixelShaderImpl
*
)
pshader
,
&
compile_args
);
pshader_id
=
find_gl_pshader
((
IWineD3DPixelShaderImpl
*
)
pshader
,
&
ps_
compile_args
);
}
else
{
pshader_id
=
0
;
}
...
...
@@ -3619,7 +3633,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
if
(
ps
->
num_gl_shaders
==
0
)
return
;
}
else
{
vs
=
(
IWineD3DVertexShaderImpl
*
)
This
;
if
(
vs
->
prgId
==
0
)
return
;
if
(
vs
->
num_gl_shaders
==
0
)
return
;
}
linked_programs
=
&
This
->
baseShader
.
linked_programs
;
...
...
@@ -3654,13 +3668,19 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
ps
->
num_gl_shaders
=
0
;
ps
->
shader_array_size
=
0
;
}
else
{
TRACE
(
"Deleting shader object %u
\n
"
,
vs
->
prgId
);
UINT
i
;
ENTER_GL
();
GL_EXTCALL
(
glDeleteObjectARB
(
vs
->
prgId
));
checkGLcall
(
"glDeleteObjectARB"
);
for
(
i
=
0
;
i
<
vs
->
num_gl_shaders
;
i
++
)
{
TRACE
(
"deleting vshader %u
\n
"
,
vs
->
gl_shaders
[
i
].
prgId
);
GL_EXTCALL
(
glDeleteObjectARB
(
vs
->
gl_shaders
[
i
].
prgId
));
checkGLcall
(
"glDeleteObjectARB"
);
}
LEAVE_GL
();
vs
->
prgId
=
0
;
vs
->
baseShader
.
is_compiled
=
FALSE
;
HeapFree
(
GetProcessHeap
(),
0
,
vs
->
gl_shaders
);
vs
->
gl_shaders
=
NULL
;
vs
->
num_gl_shaders
=
0
;
vs
->
shader_array_size
=
0
;
}
}
...
...
@@ -3668,7 +3688,7 @@ static unsigned int glsl_program_key_hash(const void *key)
{
const
glsl_program_key_t
*
k
=
key
;
unsigned
int
hash
=
k
->
vshader
|
((
DWORD_PTR
)
k
->
pshader
)
<<
16
;
unsigned
int
hash
=
((
DWORD_PTR
)
k
->
vshader
)
|
((
DWORD_PTR
)
k
->
pshader
)
<<
16
;
hash
+=
~
(
hash
<<
15
);
hash
^=
(
hash
>>
10
);
hash
+=
(
hash
<<
3
);
...
...
@@ -3685,7 +3705,8 @@ static BOOL glsl_program_key_compare(const void *keya, const void *keyb)
const
glsl_program_key_t
*
kb
=
keyb
;
return
ka
->
vshader
==
kb
->
vshader
&&
ka
->
pshader
==
kb
->
pshader
&&
(
memcmp
(
&
ka
->
ps_args
,
&
kb
->
ps_args
,
sizeof
(
kb
->
ps_args
))
==
0
);
(
memcmp
(
&
ka
->
ps_args
,
&
kb
->
ps_args
,
sizeof
(
kb
->
ps_args
))
==
0
)
&&
(
memcmp
(
&
ka
->
vs_args
,
&
kb
->
vs_args
,
sizeof
(
kb
->
vs_args
))
==
0
);
}
static
BOOL
constant_heap_init
(
struct
constant_heap
*
heap
,
unsigned
int
constant_count
)
...
...
@@ -3870,7 +3891,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
return
shader_obj
;
}
static
void
shader_glsl_generate_vshader
(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
)
{
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
;
...
...
@@ -3920,8 +3941,7 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
GL_EXTCALL
(
glCompileShaderARB
(
shader_obj
));
print_glsl_info_log
(
&
GLINFO_LOCATION
,
shader_obj
);
/* Store the shader object */
This
->
prgId
=
shader_obj
;
return
shader_obj
;
}
static
void
shader_glsl_get_caps
(
WINED3DDEVTYPE
devtype
,
const
WineD3D_GL_Info
*
gl_info
,
struct
shader_caps
*
pCaps
)
...
...
dlls/wined3d/vertexshader.c
View file @
8dcd5128
...
...
@@ -216,21 +216,6 @@ BOOL vshader_get_input(
return
FALSE
;
}
/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
or GLSL and send it to the card */
static
void
IWineD3DVertexShaderImpl_GenerateShader
(
IWineD3DVertexShader
*
iface
,
const
struct
shader_reg_maps
*
reg_maps
,
const
DWORD
*
pFunction
)
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
SHADER_BUFFER
buffer
;
This
->
swizzle_map
=
((
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
)
->
strided_streams
.
swizzle_map
;
shader_buffer_init
(
&
buffer
);
((
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
)
->
shader_backend
->
shader_generate_vshader
(
iface
,
&
buffer
);
shader_buffer_free
(
&
buffer
);
}
/* *******************************************
IWineD3DVertexShader IUnknown parts follow
******************************************* */
...
...
@@ -416,40 +401,20 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
return
WINED3D_OK
;
}
HRESULT
IWineD3DVertexShaderImpl_CompileShader
(
IWineD3DVertexShader
*
iface
)
{
IWineD3DVertexShaderImpl
*
This
=
(
IWineD3DVertexShaderImpl
*
)
iface
;
CONST
DWORD
*
function
=
This
->
baseShader
.
function
;
static
GLuint
vertexshader_compile
(
IWineD3DVertexShaderImpl
*
This
,
const
struct
vs_compile_args
*
args
)
{
IWineD3DDeviceImpl
*
deviceImpl
=
(
IWineD3DDeviceImpl
*
)
This
->
baseShader
.
device
;
TRACE
(
"(%p) : function %p
\n
"
,
iface
,
function
);
/* We're already compiled. */
if
(
This
->
baseShader
.
is_compiled
)
{
if
((
This
->
swizzle_map
&
deviceImpl
->
strided_streams
.
use_map
)
!=
deviceImpl
->
strided_streams
.
swizzle_map
)
{
WARN
(
"Recompiling vertex shader %p due to D3DCOLOR input changes
\n
"
,
This
);
goto
recompile
;
}
return
WINED3D_OK
;
recompile
:
if
(
This
->
recompile_count
<
50
)
{
This
->
recompile_count
++
;
}
else
{
FIXME
(
"Vertexshader %p recompiled more than 50 times
\n
"
,
This
);
}
deviceImpl
->
shader_backend
->
shader_destroy
((
IWineD3DBaseShader
*
)
iface
);
}
SHADER_BUFFER
buffer
;
GLuint
ret
;
/* Generate the HW shader */
TRACE
(
"(%p) : Generating hardware program
\n
"
,
This
);
IWineD3DVertexShaderImpl_GenerateShader
(
iface
,
&
This
->
baseShader
.
reg_maps
,
function
);
This
->
baseShader
.
is_compiled
=
TRUE
;
shader_buffer_init
(
&
buffer
);
This
->
cur_args
=
args
;
ret
=
deviceImpl
->
shader_backend
->
shader_generate_vshader
((
IWineD3DVertexShader
*
)
This
,
&
buffer
,
args
);
This
->
cur_args
=
NULL
;
shader_buffer_free
(
&
buffer
);
return
WINED3D_OK
;
return
ret
;
}
const
IWineD3DVertexShaderVtbl
IWineD3DVertexShader_Vtbl
=
...
...
@@ -468,3 +433,56 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
IWineD3DVertexShaderImpl_FakeSemantics
,
IWIneD3DVertexShaderImpl_SetLocalConstantsF
};
void
find_vs_compile_args
(
IWineD3DVertexShaderImpl
*
shader
,
IWineD3DStateBlockImpl
*
stateblock
,
struct
vs_compile_args
*
args
)
{
args
->
fog_src
=
stateblock
->
renderState
[
WINED3DRS_FOGTABLEMODE
]
==
WINED3DFOG_NONE
?
VS_FOG_COORD
:
VS_FOG_Z
;
args
->
swizzle_map
=
((
IWineD3DDeviceImpl
*
)
shader
->
baseShader
.
device
)
->
strided_streams
.
swizzle_map
;
}
static
inline
BOOL
vs_args_equal
(
const
struct
vs_compile_args
*
stored
,
const
struct
vs_compile_args
*
new
,
const
DWORD
use_map
)
{
if
((
stored
->
swizzle_map
&
use_map
)
!=
new
->
swizzle_map
)
return
FALSE
;
return
stored
->
fog_src
==
new
->
fog_src
;
}
GLuint
find_gl_vshader
(
IWineD3DVertexShaderImpl
*
shader
,
const
struct
vs_compile_args
*
args
)
{
UINT
i
;
DWORD
new_size
=
shader
->
shader_array_size
;
struct
vs_compiled_shader
*
new_array
;
DWORD
use_map
=
((
IWineD3DDeviceImpl
*
)
shader
->
baseShader
.
device
)
->
strided_streams
.
use_map
;
/* 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
(
vs_args_equal
(
&
shader
->
gl_shaders
[
i
].
args
,
args
,
use_map
))
{
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
->
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
;
shader
->
gl_shaders
[
shader
->
num_gl_shaders
].
prgId
=
vertexshader_compile
(
shader
,
args
);
return
shader
->
gl_shaders
[
shader
->
num_gl_shaders
++
].
prgId
;
}
dlls/wined3d/wined3d_private.h
View file @
8dcd5128
...
...
@@ -459,6 +459,18 @@ struct ps_compile_args {
/* Texture types(2D, Cube, 3D) in ps 1.x */
};
#define MAX_ATTRIBS 16
enum
fog_src_type
{
VS_FOG_Z
=
0
,
VS_FOG_COORD
=
1
};
struct
vs_compile_args
{
WORD
fog_src
;
WORD
swizzle_map
;
/* MAX_ATTRIBS, 16 */
};
typedef
struct
{
const
SHADER_HANDLER
*
shader_instruction_handler_table
;
void
(
*
shader_select
)(
IWineD3DDevice
*
iface
,
BOOL
usePS
,
BOOL
useVS
);
...
...
@@ -473,7 +485,7 @@ typedef struct {
void
(
*
shader_free_private
)(
IWineD3DDevice
*
iface
);
BOOL
(
*
shader_dirtifyable_constants
)(
IWineD3DDevice
*
iface
);
GLuint
(
*
shader_generate_pshader
)(
IWineD3DPixelShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
ps_compile_args
*
args
);
void
(
*
shader_generate_vshader
)(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
);
GLuint
(
*
shader_generate_vshader
)(
IWineD3DVertexShader
*
iface
,
SHADER_BUFFER
*
buffer
,
const
struct
vs_compile_args
*
args
);
void
(
*
shader_get_caps
)(
WINED3DDEVTYPE
devtype
,
const
WineD3D_GL_Info
*
gl_info
,
struct
shader_caps
*
caps
);
BOOL
(
*
shader_color_fixup_supported
)(
struct
color_fixup_desc
fixup
);
}
shader_backend_t
;
...
...
@@ -2207,7 +2219,6 @@ typedef struct IWineD3DBaseShaderClass
CONST
SHADER_OPCODE
*
shader_ins
;
DWORD
*
function
;
UINT
functionLength
;
BOOL
is_compiled
;
UINT
cur_loop_depth
,
cur_loop_regno
;
BOOL
load_local_constsF
;
BOOL
uses_bool_consts
,
uses_int_consts
;
...
...
@@ -2323,8 +2334,14 @@ static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD
}
/*****************************************************************************
* IDirect3DVertexShader implementation structure
* IDirect3DVertexShader implementation structure
s
*/
struct
vs_compiled_shader
{
struct
vs_compile_args
args
;
GLuint
prgId
;
};
typedef
struct
IWineD3DVertexShaderImpl
{
/* IUnknown parts*/
const
IWineD3DVertexShaderVtbl
*
lpVtbl
;
...
...
@@ -2338,22 +2355,25 @@ typedef struct IWineD3DVertexShaderImpl {
DWORD
usage
;
/* The GL shader */
GLuint
prgId
;
struct
vs_compiled_shader
*
gl_shaders
;
UINT
num_gl_shaders
,
shader_array_size
;
/* Vertex shader input and output semantics */
semantic
semantics_in
[
MAX_ATTRIBS
];
semantic
semantics_out
[
MAX_REG_OUTPUT
];
WORD
swizzle_map
;
/* MAX_ATTRIBS, 16 */
UINT
min_rel_offset
,
max_rel_offset
;
UINT
rel_offset
;
UINT
recompile_count
;
const
struct
vs_compile_args
*
cur_args
;
}
IWineD3DVertexShaderImpl
;
extern
const
SHADER_OPCODE
IWineD3DVertexShaderImpl_shader_ins
[];
extern
const
IWineD3DVertexShaderVtbl
IWineD3DVertexShader_Vtbl
;
HRESULT
IWineD3DVertexShaderImpl_CompileShader
(
IWineD3DVertexShader
*
iface
);
void
find_vs_compile_args
(
IWineD3DVertexShaderImpl
*
shader
,
IWineD3DStateBlockImpl
*
stateblock
,
struct
vs_compile_args
*
args
);
GLuint
find_gl_vshader
(
IWineD3DVertexShaderImpl
*
shader
,
const
struct
vs_compile_args
*
args
);
/*****************************************************************************
* IDirect3DPixelShader implementation structure
...
...
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