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
4ab7af65
Commit
4ab7af65
authored
Jul 24, 2009
by
Henri Verbeet
Committed by
Alexandre Julliard
Jul 24, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Manage occlusion queries in the context.
parent
6a1aa9b1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
160 additions
and
59 deletions
+160
-59
context.c
dlls/wined3d/context.c
+84
-0
device.c
dlls/wined3d/device.c
+3
-11
query.c
dlls/wined3d/query.c
+58
-43
wined3d_private.h
dlls/wined3d/wined3d_private.h
+15
-5
No files found.
dlls/wined3d/context.c
View file @
4ab7af65
...
...
@@ -451,6 +451,63 @@ static void context_apply_fbo_state(struct WineD3DContext *context)
context_check_fbo_status
(
context
);
}
/* Context activation is done by the caller. */
void
context_alloc_occlusion_query
(
struct
WineD3DContext
*
context
,
struct
wined3d_occlusion_query
*
query
)
{
const
struct
wined3d_gl_info
*
gl_info
=
context
->
gl_info
;
if
(
context
->
free_occlusion_query_count
)
{
query
->
id
=
context
->
free_occlusion_queries
[
--
context
->
free_occlusion_query_count
];
}
else
{
if
(
GL_SUPPORT
(
ARB_OCCLUSION_QUERY
))
{
ENTER_GL
();
GL_EXTCALL
(
glGenQueriesARB
(
1
,
&
query
->
id
));
checkGLcall
(
"glGenQueriesARB"
);
LEAVE_GL
();
TRACE
(
"Allocated occlusion query %u in context %p.
\n
"
,
query
->
id
,
context
);
}
else
{
WARN
(
"Occlusion queries not supported, not allocating query id.
\n
"
);
query
->
id
=
0
;
}
}
query
->
context
=
context
;
list_add_head
(
&
context
->
occlusion_queries
,
&
query
->
entry
);
}
void
context_free_occlusion_query
(
struct
wined3d_occlusion_query
*
query
)
{
struct
WineD3DContext
*
context
=
query
->
context
;
list_remove
(
&
query
->
entry
);
query
->
context
=
NULL
;
if
(
context
->
free_occlusion_query_count
>=
context
->
free_occlusion_query_size
-
1
)
{
UINT
new_size
=
context
->
free_occlusion_query_size
<<
1
;
GLuint
*
new_data
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
context
->
free_occlusion_queries
,
new_size
*
sizeof
(
*
context
->
free_occlusion_queries
));
if
(
!
new_data
)
{
ERR
(
"Failed to grow free list, leaking query %u in context %p.
\n
"
,
query
->
id
,
context
);
return
;
}
context
->
free_occlusion_query_size
=
new_size
;
context
->
free_occlusion_queries
=
new_data
;
}
context
->
free_occlusion_queries
[
context
->
free_occlusion_query_count
++
]
=
query
->
id
;
}
void
context_resource_released
(
IWineD3DDevice
*
iface
,
IWineD3DResource
*
resource
,
WINED3DRESOURCETYPE
type
)
{
IWineD3DDeviceImpl
*
This
=
(
IWineD3DDeviceImpl
*
)
iface
;
...
...
@@ -504,6 +561,7 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
static
void
context_destroy_gl_resources
(
struct
WineD3DContext
*
context
)
{
const
struct
wined3d_gl_info
*
gl_info
=
context
->
gl_info
;
struct
wined3d_occlusion_query
*
occlusion_query
;
struct
fbo_entry
*
entry
,
*
entry2
;
BOOL
has_glctx
;
...
...
@@ -512,6 +570,12 @@ static void context_destroy_gl_resources(struct WineD3DContext *context)
ENTER_GL
();
LIST_FOR_EACH_ENTRY
(
occlusion_query
,
&
context
->
occlusion_queries
,
struct
wined3d_occlusion_query
,
entry
)
{
if
(
has_glctx
&&
GL_SUPPORT
(
ARB_OCCLUSION_QUERY
))
GL_EXTCALL
(
glDeleteQueriesARB
(
1
,
&
occlusion_query
->
id
));
occlusion_query
->
context
=
NULL
;
}
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
entry2
,
&
context
->
fbo_list
,
struct
fbo_entry
,
entry
)
{
if
(
!
has_glctx
)
entry
->
id
=
0
;
context_destroy_fbo_entry
(
context
,
entry
);
...
...
@@ -532,10 +596,16 @@ static void context_destroy_gl_resources(struct WineD3DContext *context)
{
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
context
->
dummy_arbfp_prog
));
}
GL_EXTCALL
(
glDeleteQueriesARB
(
context
->
free_occlusion_query_count
,
context
->
free_occlusion_queries
));
checkGLcall
(
"context cleanup"
);
}
LEAVE_GL
();
HeapFree
(
GetProcessHeap
(),
0
,
context
->
free_occlusion_queries
);
if
(
!
pwglMakeCurrent
(
NULL
,
NULL
))
{
ERR
(
"Failed to disable GL context.
\n
"
);
...
...
@@ -1092,6 +1162,13 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
sizeof
(
*
ret
->
pshader_const_dirty
)
*
GL_LIMITS
(
pshader_constantsF
));
}
ret
->
free_occlusion_query_size
=
4
;
ret
->
free_occlusion_queries
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ret
->
free_occlusion_query_size
*
sizeof
(
*
ret
->
free_occlusion_queries
));
if
(
!
ret
->
free_occlusion_queries
)
goto
out
;
list_init
(
&
ret
->
occlusion_queries
);
TRACE
(
"Successfully created new context %p
\n
"
,
ret
);
list_init
(
&
ret
->
fbo_list
);
...
...
@@ -1187,6 +1264,13 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
return
ret
;
out:
if
(
ret
)
{
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
free_occlusion_queries
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
pshader_const_dirty
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
vshader_const_dirty
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
);
}
return
NULL
;
}
...
...
dlls/wined3d/device.c
View file @
4ab7af65
...
...
@@ -1191,18 +1191,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
/* allocated the 'extended' data based on the type of query requested */
switch
(
Type
){
case
WINED3DQUERYTYPE_OCCLUSION
:
object
->
extendedData
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
WineQueryOcclusionData
));
((
WineQueryOcclusionData
*
)(
object
->
extendedData
))
->
ctx
=
This
->
activeContext
;
if
(
GL_SUPPORT
(
ARB_OCCLUSION_QUERY
))
{
TRACE
(
"(%p) Allocating data for an occlusion query
\n
"
,
This
);
object
->
extendedData
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
wined3d_occlusion_query
));
((
struct
wined3d_occlusion_query
*
)
object
->
extendedData
)
->
context
=
NULL
;
break
;
ActivateContext
(
This
,
NULL
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
GL_EXTCALL
(
glGenQueriesARB
(
1
,
&
((
WineQueryOcclusionData
*
)(
object
->
extendedData
))
->
queryId
));
LEAVE_GL
();
break
;
}
case
WINED3DQUERYTYPE_EVENT
:
object
->
extendedData
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
WineQueryEventData
));
((
WineQueryEventData
*
)(
object
->
extendedData
))
->
ctx
=
This
->
activeContext
;
...
...
dlls/wined3d/query.c
View file @
4ab7af65
...
...
@@ -94,25 +94,11 @@ static ULONG WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
LEAVE_GL
();
}
}
else
if
(
This
->
type
==
WINED3DQUERYTYPE_OCCLUSION
&&
GL_SUPPORT
(
ARB_OCCLUSION_QUERY
)
)
else
if
(
This
->
type
==
WINED3DQUERYTYPE_OCCLUSION
)
{
WineQueryOcclusionData
*
query_data
=
(
WineQueryOcclusionData
*
)
This
->
extendedData
;
struct
wined3d_occlusion_query
*
query
=
This
->
extendedData
;
if
(
query_data
->
ctx
->
tid
!=
GetCurrentThreadId
())
{
FIXME
(
"Query was created in a different thread, skipping deletion.
\n
"
);
}
else
{
ActivateContext
(
This
->
wineD3DDevice
,
query_data
->
ctx
->
surface
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
GL_EXTCALL
(
glDeleteQueriesARB
(
1
,
&
query_data
->
queryId
));
checkGLcall
(
"glDeleteQueriesARB"
);
LEAVE_GL
();
}
if
(
query
->
context
)
context_free_occlusion_query
(
query
);
}
HeapFree
(
GetProcessHeap
(),
0
,
This
->
extendedData
);
...
...
@@ -306,7 +292,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
static
HRESULT
WINAPI
IWineD3DOcclusionQueryImpl_GetData
(
IWineD3DQuery
*
iface
,
void
*
pData
,
DWORD
dwSize
,
DWORD
dwGetDataFlags
)
{
IWineD3DQueryImpl
*
This
=
(
IWineD3DQueryImpl
*
)
iface
;
WineQueryOcclusionData
*
query_data
=
(
WineQueryOcclusionData
*
)
This
->
extendedData
;
struct
wined3d_occlusion_query
*
query
=
This
->
extendedData
;
DWORD
*
data
=
pData
;
GLuint
available
;
GLuint
samples
;
...
...
@@ -314,6 +300,8 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
TRACE
(
"(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x
\n
"
,
This
,
pData
,
dwSize
,
dwGetDataFlags
);
if
(
!
query
->
context
)
This
->
state
=
QUERY_CREATED
;
if
(
This
->
state
==
QUERY_CREATED
)
{
/* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
...
...
@@ -336,18 +324,18 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
return
S_OK
;
}
if
(
query
_data
->
ctx
->
tid
!=
GetCurrentThreadId
())
if
(
query
->
context
->
tid
!=
GetCurrentThreadId
())
{
FIXME
(
"%p Wrong thread, returning 1.
\n
"
,
This
);
*
data
=
1
;
return
S_OK
;
}
ActivateContext
(
This
->
wineD3DDevice
,
query
_data
->
ctx
->
surface
,
CTXUSAGE_RESOURCELOAD
);
ActivateContext
(
This
->
wineD3DDevice
,
query
->
context
->
current_rt
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
GL_EXTCALL
(
glGetQueryObjectuivARB
(
query
_data
->
queryI
d
,
GL_QUERY_RESULT_AVAILABLE_ARB
,
&
available
));
GL_EXTCALL
(
glGetQueryObjectuivARB
(
query
->
i
d
,
GL_QUERY_RESULT_AVAILABLE_ARB
,
&
available
));
checkGLcall
(
"glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)"
);
TRACE
(
"(%p) : available %d.
\n
"
,
This
,
available
);
...
...
@@ -355,7 +343,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
{
if
(
data
)
{
GL_EXTCALL
(
glGetQueryObjectuivARB
(
query
_data
->
queryI
d
,
GL_QUERY_RESULT_ARB
,
&
samples
));
GL_EXTCALL
(
glGetQueryObjectuivARB
(
query
->
i
d
,
GL_QUERY_RESULT_ARB
,
&
samples
));
checkGLcall
(
"glGetQueryObjectuivARB(GL_QUERY_RESULT)"
);
TRACE
(
"(%p) : Returning %d samples.
\n
"
,
This
,
samples
);
*
data
=
samples
;
...
...
@@ -541,38 +529,65 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D
if
(
GL_SUPPORT
(
ARB_OCCLUSION_QUERY
))
{
WineQueryOcclusionData
*
query_data
=
(
WineQueryOcclusionData
*
)
This
->
extendedData
;
struct
wined3d_occlusion_query
*
query
=
This
->
extendedData
;
struct
WineD3DContext
*
context
;
if
(
query_data
->
ctx
->
tid
!=
GetCurrentThreadId
())
/* This is allowed according to msdn and our tests. Reset the query and restart */
if
(
dwIssueFlags
&
WINED3DISSUE_BEGIN
)
{
FIXME
(
"Not the owning context, can't start query.
\n
"
);
}
else
{
ActivateContext
(
This
->
wineD3DDevice
,
query_data
->
ctx
->
surface
,
CTXUSAGE_RESOURCELOAD
);
if
(
This
->
state
==
QUERY_BUILDING
)
{
if
(
query
->
context
->
tid
!=
GetCurrentThreadId
())
{
FIXME
(
"Wrong thread, can't restart query.
\n
"
);
ENTER_GL
();
/* This is allowed according to msdn and our tests. Reset the query and restart */
if
(
dwIssueFlags
&
WINED3DISSUE_BEGIN
)
{
if
(
This
->
state
==
QUERY_BUILDING
)
{
context_free_occlusion_query
(
query
);
context
=
ActivateContext
(
This
->
wineD3DDevice
,
NULL
,
CTXUSAGE_RESOURCELOAD
);
context_alloc_occlusion_query
(
context
,
query
);
}
else
{
ActivateContext
(
This
->
wineD3DDevice
,
query
->
context
->
current_rt
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
GL_EXTCALL
(
glEndQueryARB
(
GL_SAMPLES_PASSED_ARB
));
checkGLcall
(
"glEndQuery()"
);
LEAVE_GL
();
}
GL_EXTCALL
(
glBeginQueryARB
(
GL_SAMPLES_PASSED_ARB
,
query_data
->
queryId
));
checkGLcall
(
"glBeginQuery()"
);
}
if
(
dwIssueFlags
&
WINED3DISSUE_END
)
{
/* Msdn says _END on a non-building occlusion query returns an error, but
* our tests show that it returns OK. But OpenGL doesn't like it, so avoid
* generating an error
*/
if
(
This
->
state
==
QUERY_BUILDING
)
{
else
{
if
(
query
->
context
)
context_free_occlusion_query
(
query
);
context
=
ActivateContext
(
This
->
wineD3DDevice
,
NULL
,
CTXUSAGE_RESOURCELOAD
);
context_alloc_occlusion_query
(
context
,
query
);
}
ENTER_GL
();
GL_EXTCALL
(
glBeginQueryARB
(
GL_SAMPLES_PASSED_ARB
,
query
->
id
));
checkGLcall
(
"glBeginQuery()"
);
LEAVE_GL
();
}
if
(
dwIssueFlags
&
WINED3DISSUE_END
)
{
/* Msdn says _END on a non-building occlusion query returns an error, but
* our tests show that it returns OK. But OpenGL doesn't like it, so avoid
* generating an error
*/
if
(
This
->
state
==
QUERY_BUILDING
)
{
if
(
query
->
context
->
tid
!=
GetCurrentThreadId
())
{
FIXME
(
"Wrong thread, can't end query.
\n
"
);
}
else
{
ActivateContext
(
This
->
wineD3DDevice
,
query
->
context
->
current_rt
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
GL_EXTCALL
(
glEndQueryARB
(
GL_SAMPLES_PASSED_ARB
));
checkGLcall
(
"glEndQuery()"
);
LEAVE_GL
();
}
}
LEAVE_GL
();
}
}
else
{
FIXME
(
"(%p) : Occlusion queries not supported
\n
"
,
This
);
...
...
dlls/wined3d/wined3d_private.h
View file @
4ab7af65
...
...
@@ -1188,6 +1188,13 @@ enum fogsource {
#define WINED3D_MAX_FBO_ENTRIES 64
struct
wined3d_occlusion_query
{
struct
list
entry
;
GLuint
id
;
struct
WineD3DContext
*
context
;
};
/* The new context manager that should deal with onscreen and offscreen rendering */
struct
WineD3DContext
{
...
...
@@ -1248,6 +1255,12 @@ struct WineD3DContext
GLuint
fbo_read_binding
;
GLuint
fbo_draw_binding
;
/* Queries */
GLuint
*
free_occlusion_queries
;
UINT
free_occlusion_query_size
;
UINT
free_occlusion_query_count
;
struct
list
occlusion_queries
;
/* Extension emulation */
GLint
gl_fog_source
;
GLfloat
fog_coord_value
;
...
...
@@ -1265,12 +1278,14 @@ typedef enum ContextUsage {
struct
WineD3DContext
*
ActivateContext
(
IWineD3DDeviceImpl
*
This
,
IWineD3DSurface
*
target
,
enum
ContextUsage
usage
);
WineD3DContext
*
CreateContext
(
IWineD3DDeviceImpl
*
This
,
IWineD3DSurfaceImpl
*
target
,
HWND
win
,
BOOL
create_pbuffer
,
const
WINED3DPRESENT_PARAMETERS
*
pPresentParms
);
void
DestroyContext
(
IWineD3DDeviceImpl
*
This
,
WineD3DContext
*
context
);
void
context_alloc_occlusion_query
(
struct
WineD3DContext
*
context
,
struct
wined3d_occlusion_query
*
query
);
void
context_resource_released
(
IWineD3DDevice
*
iface
,
IWineD3DResource
*
resource
,
WINED3DRESOURCETYPE
type
);
void
context_bind_fbo
(
struct
WineD3DContext
*
context
,
GLenum
target
,
GLuint
*
fbo
);
void
context_attach_depth_stencil_fbo
(
struct
WineD3DContext
*
context
,
GLenum
fbo_target
,
IWineD3DSurface
*
depth_stencil
,
BOOL
use_render_buffer
);
void
context_attach_surface_fbo
(
const
struct
WineD3DContext
*
context
,
GLenum
fbo_target
,
DWORD
idx
,
IWineD3DSurface
*
surface
);
void
context_free_occlusion_query
(
struct
wined3d_occlusion_query
*
query
);
struct
WineD3DContext
*
context_get_current
(
void
);
DWORD
context_get_tls_idx
(
void
);
BOOL
context_set_current
(
struct
WineD3DContext
*
ctx
);
...
...
@@ -2350,11 +2365,6 @@ extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl;
extern
const
IWineD3DQueryVtbl
IWineD3DOcclusionQuery_Vtbl
;
/* Datastructures for IWineD3DQueryImpl.extendedData */
typedef
struct
WineQueryOcclusionData
{
GLuint
queryId
;
WineD3DContext
*
ctx
;
}
WineQueryOcclusionData
;
typedef
struct
WineQueryEventData
{
GLuint
fenceId
;
WineD3DContext
*
ctx
;
...
...
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