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
a1784d9e
Commit
a1784d9e
authored
Apr 16, 2014
by
Matteo Bruni
Committed by
Alexandre Julliard
Apr 17, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Add support for timestamp queries.
parent
4811a839
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
301 additions
and
5 deletions
+301
-5
query.c
dlls/d3d9/query.c
+19
-2
context.c
dlls/wined3d/context.c
+67
-0
query.c
dlls/wined3d/query.c
+194
-3
wined3d_private.h
dlls/wined3d/wined3d_private.h
+15
-0
wined3d.h
include/wine/wined3d.h
+6
-0
No files found.
dlls/d3d9/query.c
View file @
a1784d9e
...
...
@@ -108,12 +108,17 @@ static D3DQUERYTYPE WINAPI d3d9_query_GetType(IDirect3DQuery9 *iface)
static
DWORD
WINAPI
d3d9_query_GetDataSize
(
IDirect3DQuery9
*
iface
)
{
struct
d3d9_query
*
query
=
impl_from_IDirect3DQuery9
(
iface
);
enum
wined3d_query_type
type
;
DWORD
ret
;
TRACE
(
"iface %p.
\n
"
,
iface
);
wined3d_mutex_lock
();
ret
=
wined3d_query_get_data_size
(
query
->
wined3d_query
);
type
=
wined3d_query_get_type
(
query
->
wined3d_query
);
if
(
type
==
WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
)
ret
=
sizeof
(
BOOL
);
else
ret
=
wined3d_query_get_data_size
(
query
->
wined3d_query
);
wined3d_mutex_unlock
();
return
ret
;
...
...
@@ -136,13 +141,25 @@ static HRESULT WINAPI d3d9_query_Issue(IDirect3DQuery9 *iface, DWORD flags)
static
HRESULT
WINAPI
d3d9_query_GetData
(
IDirect3DQuery9
*
iface
,
void
*
data
,
DWORD
size
,
DWORD
flags
)
{
struct
d3d9_query
*
query
=
impl_from_IDirect3DQuery9
(
iface
);
enum
wined3d_query_type
type
;
HRESULT
hr
;
TRACE
(
"iface %p, data %p, size %u, flags %#x.
\n
"
,
iface
,
data
,
size
,
flags
);
wined3d_mutex_lock
();
hr
=
wined3d_query_get_data
(
query
->
wined3d_query
,
data
,
size
,
flags
);
type
=
wined3d_query_get_type
(
query
->
wined3d_query
);
if
(
type
==
WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
&&
data
)
{
struct
wined3d_query_data_timestamp_disjoint
data_disjoint
;
hr
=
wined3d_query_get_data
(
query
->
wined3d_query
,
&
data_disjoint
,
sizeof
(
data_disjoint
),
flags
);
*
(
BOOL
*
)
data
=
data_disjoint
.
disjoint
;
}
else
{
hr
=
wined3d_query_get_data
(
query
->
wined3d_query
,
data
,
size
,
flags
);
}
wined3d_mutex_unlock
();
return
hr
;
...
...
dlls/wined3d/context.c
View file @
a1784d9e
...
...
@@ -614,6 +614,53 @@ void context_free_event_query(struct wined3d_event_query *query)
context
->
free_event_queries
[
context
->
free_event_query_count
++
]
=
query
->
object
;
}
/* Context activation is done by the caller. */
void
context_alloc_timestamp_query
(
struct
wined3d_context
*
context
,
struct
wined3d_timestamp_query
*
query
)
{
const
struct
wined3d_gl_info
*
gl_info
=
context
->
gl_info
;
if
(
context
->
free_timestamp_query_count
)
{
query
->
id
=
context
->
free_timestamp_queries
[
--
context
->
free_timestamp_query_count
];
}
else
{
GL_EXTCALL
(
glGenQueriesARB
(
1
,
&
query
->
id
));
checkGLcall
(
"glGenQueriesARB"
);
TRACE
(
"Allocated timestamp query %u in context %p.
\n
"
,
query
->
id
,
context
);
}
query
->
context
=
context
;
list_add_head
(
&
context
->
timestamp_queries
,
&
query
->
entry
);
}
void
context_free_timestamp_query
(
struct
wined3d_timestamp_query
*
query
)
{
struct
wined3d_context
*
context
=
query
->
context
;
list_remove
(
&
query
->
entry
);
query
->
context
=
NULL
;
if
(
context
->
free_timestamp_query_count
>=
context
->
free_timestamp_query_size
-
1
)
{
UINT
new_size
=
context
->
free_timestamp_query_size
<<
1
;
GLuint
*
new_data
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
context
->
free_timestamp_queries
,
new_size
*
sizeof
(
*
context
->
free_timestamp_queries
));
if
(
!
new_data
)
{
ERR
(
"Failed to grow free list, leaking query %u in context %p.
\n
"
,
query
->
id
,
context
);
return
;
}
context
->
free_timestamp_query_size
=
new_size
;
context
->
free_timestamp_queries
=
new_data
;
}
context
->
free_timestamp_queries
[
context
->
free_timestamp_query_count
++
]
=
query
->
id
;
}
typedef
void
(
context_fbo_entry_func_t
)(
struct
wined3d_context
*
context
,
struct
fbo_entry
*
entry
);
static
void
context_enum_surface_fbo_entries
(
const
struct
wined3d_device
*
device
,
...
...
@@ -914,6 +961,7 @@ static void context_update_window(struct wined3d_context *context)
static
void
context_destroy_gl_resources
(
struct
wined3d_context
*
context
)
{
const
struct
wined3d_gl_info
*
gl_info
=
context
->
gl_info
;
struct
wined3d_timestamp_query
*
timestamp_query
;
struct
wined3d_occlusion_query
*
occlusion_query
;
struct
wined3d_event_query
*
event_query
;
struct
fbo_entry
*
entry
,
*
entry2
;
...
...
@@ -929,6 +977,13 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
else
if
(
context
->
valid
)
context_set_gl_context
(
context
);
LIST_FOR_EACH_ENTRY
(
timestamp_query
,
&
context
->
timestamp_queries
,
struct
wined3d_timestamp_query
,
entry
)
{
if
(
context
->
valid
)
GL_EXTCALL
(
glDeleteQueriesARB
(
1
,
&
timestamp_query
->
id
));
timestamp_query
->
context
=
NULL
;
}
LIST_FOR_EACH_ENTRY
(
occlusion_query
,
&
context
->
occlusion_queries
,
struct
wined3d_occlusion_query
,
entry
)
{
if
(
context
->
valid
&&
gl_info
->
supported
[
ARB_OCCLUSION_QUERY
])
...
...
@@ -969,6 +1024,9 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
GL_EXTCALL
(
glDeleteProgramsARB
(
1
,
&
context
->
dummy_arbfp_prog
));
}
if
(
gl_info
->
supported
[
ARB_TIMER_QUERY
])
GL_EXTCALL
(
glDeleteQueriesARB
(
context
->
free_timestamp_query_count
,
context
->
free_timestamp_queries
));
if
(
gl_info
->
supported
[
ARB_OCCLUSION_QUERY
])
GL_EXTCALL
(
glDeleteQueriesARB
(
context
->
free_occlusion_query_count
,
context
->
free_occlusion_queries
));
...
...
@@ -997,6 +1055,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
checkGLcall
(
"context cleanup"
);
}
HeapFree
(
GetProcessHeap
(),
0
,
context
->
free_timestamp_queries
);
HeapFree
(
GetProcessHeap
(),
0
,
context
->
free_occlusion_queries
);
HeapFree
(
GetProcessHeap
(),
0
,
context
->
free_event_queries
);
...
...
@@ -1358,6 +1417,13 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
if
(
!
ret
->
draw_buffers
)
goto
out
;
ret
->
free_timestamp_query_size
=
4
;
ret
->
free_timestamp_queries
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ret
->
free_timestamp_query_size
*
sizeof
(
*
ret
->
free_timestamp_queries
));
if
(
!
ret
->
free_timestamp_queries
)
goto
out
;
list_init
(
&
ret
->
timestamp_queries
);
ret
->
free_occlusion_query_size
=
4
;
ret
->
free_occlusion_queries
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ret
->
free_occlusion_query_size
*
sizeof
(
*
ret
->
free_occlusion_queries
));
...
...
@@ -1700,6 +1766,7 @@ out:
device
->
shader_backend
->
shader_free_context_data
(
ret
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
free_event_queries
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
free_occlusion_queries
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
free_timestamp_queries
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
draw_buffers
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
->
blit_targets
);
HeapFree
(
GetProcessHeap
(),
0
,
ret
);
...
...
dlls/wined3d/query.c
View file @
a1784d9e
...
...
@@ -257,6 +257,14 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
if
(
oq
->
context
)
context_free_occlusion_query
(
oq
);
HeapFree
(
GetProcessHeap
(),
0
,
query
->
extendedData
);
}
else
if
(
query
->
type
==
WINED3D_QUERY_TYPE_TIMESTAMP
)
{
struct
wined3d_timestamp_query
*
tq
=
query
->
extendedData
;
if
(
tq
->
context
)
context_free_timestamp_query
(
tq
);
HeapFree
(
GetProcessHeap
(),
0
,
query
->
extendedData
);
}
HeapFree
(
GetProcessHeap
(),
0
,
query
);
}
...
...
@@ -519,6 +527,148 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW
return
WINED3D_OK
;
/* can be WINED3DERR_INVALIDCALL. */
}
static
HRESULT
wined3d_timestamp_query_ops_get_data
(
struct
wined3d_query
*
query
,
void
*
data
,
DWORD
size
,
DWORD
flags
)
{
struct
wined3d_timestamp_query
*
tq
=
query
->
extendedData
;
struct
wined3d_device
*
device
=
query
->
device
;
const
struct
wined3d_gl_info
*
gl_info
=
&
device
->
adapter
->
gl_info
;
struct
wined3d_context
*
context
;
UINT64
*
u64data
=
data
;
GLuint
available
;
GLuint64
timestamp
;
HRESULT
res
;
TRACE
(
"(%p) : type D3DQUERY_TIMESTAMP, data %p, size %#x, flags %#x.
\n
"
,
query
,
data
,
size
,
flags
);
if
(
!
tq
->
context
)
query
->
state
=
QUERY_CREATED
;
if
(
query
->
state
==
QUERY_CREATED
)
{
/* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */
TRACE
(
"Query wasn't yet started, returning S_OK.
\n
"
);
if
(
u64data
)
*
u64data
=
0
;
return
S_OK
;
}
if
(
tq
->
context
->
tid
!=
GetCurrentThreadId
())
{
FIXME
(
"%p Wrong thread, returning 1.
\n
"
,
query
);
if
(
u64data
)
*
u64data
=
1
;
return
S_OK
;
}
context
=
context_acquire
(
query
->
device
,
tq
->
context
->
current_rt
);
GL_EXTCALL
(
glGetQueryObjectuivARB
(
tq
->
id
,
GL_QUERY_RESULT_AVAILABLE_ARB
,
&
available
));
checkGLcall
(
"glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)"
);
TRACE
(
"available %#x.
\n
"
,
available
);
if
(
available
)
{
if
(
u64data
)
{
GL_EXTCALL
(
glGetQueryObjectui64v
(
tq
->
id
,
GL_QUERY_RESULT_ARB
,
&
timestamp
));
checkGLcall
(
"glGetQueryObjectuivARB(GL_QUERY_RESULT)"
);
TRACE
(
"Returning timestamp %s.
\n
"
,
wine_dbgstr_longlong
(
timestamp
));
*
u64data
=
timestamp
;
}
res
=
S_OK
;
}
else
{
res
=
S_FALSE
;
}
context_release
(
context
);
return
res
;
}
static
HRESULT
wined3d_timestamp_query_ops_issue
(
struct
wined3d_query
*
query
,
DWORD
flags
)
{
struct
wined3d_device
*
device
=
query
->
device
;
const
struct
wined3d_gl_info
*
gl_info
=
&
device
->
adapter
->
gl_info
;
TRACE
(
"query %p, flags %#x.
\n
"
,
query
,
flags
);
if
(
gl_info
->
supported
[
ARB_TIMER_QUERY
])
{
struct
wined3d_timestamp_query
*
tq
=
query
->
extendedData
;
struct
wined3d_context
*
context
;
if
(
flags
&
WINED3DISSUE_BEGIN
)
{
WARN
(
"Ignoring WINED3DISSUE_BEGIN with a TIMESTAMP query.
\n
"
);
}
if
(
flags
&
WINED3DISSUE_END
)
{
if
(
tq
->
context
)
context_free_timestamp_query
(
tq
);
context
=
context_acquire
(
query
->
device
,
NULL
);
context_alloc_timestamp_query
(
context
,
tq
);
GL_EXTCALL
(
glQueryCounter
(
tq
->
id
,
GL_TIMESTAMP
));
checkGLcall
(
"glQueryCounter()"
);
context_release
(
context
);
}
}
else
{
ERR
(
"Timestamp queries not supported.
\n
"
);
}
if
(
flags
&
WINED3DISSUE_END
)
query
->
state
=
QUERY_SIGNALLED
;
return
WINED3D_OK
;
}
static
HRESULT
wined3d_timestamp_disjoint_query_ops_get_data
(
struct
wined3d_query
*
query
,
void
*
data
,
DWORD
size
,
DWORD
flags
)
{
TRACE
(
"(%p) : type D3DQUERY_TIMESTAMP_DISJOINT, data %p, size %#x, flags %#x.
\n
"
,
query
,
data
,
size
,
flags
);
if
(
query
->
type
==
WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
)
{
struct
wined3d_query_data_timestamp_disjoint
*
disjoint_data
=
data
;
if
(
query
->
state
==
QUERY_BUILDING
)
{
TRACE
(
"Query is building, returning S_FALSE.
\n
"
);
return
S_FALSE
;
}
if
(
disjoint_data
)
{
disjoint_data
->
disjoint
=
FALSE
;
disjoint_data
->
frequency
=
1000
*
1000
*
1000
;
}
}
else
{
UINT64
*
u64data
=
data
;
if
(
u64data
)
*
u64data
=
1000
*
1000
*
1000
;
}
return
S_OK
;
}
static
HRESULT
wined3d_timestamp_disjoint_query_ops_issue
(
struct
wined3d_query
*
query
,
DWORD
flags
)
{
TRACE
(
"query %p, flags %#x.
\n
"
,
query
,
flags
);
if
(
flags
&
WINED3DISSUE_BEGIN
)
query
->
state
=
QUERY_BUILDING
;
if
(
flags
&
WINED3DISSUE_END
)
query
->
state
=
QUERY_SIGNALLED
;
return
WINED3D_OK
;
}
static
const
struct
wined3d_query_ops
event_query_ops
=
{
wined3d_event_query_ops_get_data
,
...
...
@@ -531,6 +681,18 @@ static const struct wined3d_query_ops occlusion_query_ops =
wined3d_occlusion_query_ops_issue
,
};
static
const
struct
wined3d_query_ops
timestamp_query_ops
=
{
wined3d_timestamp_query_ops_get_data
,
wined3d_timestamp_query_ops_issue
,
};
static
const
struct
wined3d_query_ops
timestamp_disjoint_query_ops
=
{
wined3d_timestamp_disjoint_query_ops_get_data
,
wined3d_timestamp_disjoint_query_ops_issue
,
};
static
HRESULT
query_init
(
struct
wined3d_query
*
query
,
struct
wined3d_device
*
device
,
enum
wined3d_query_type
type
)
{
const
struct
wined3d_gl_info
*
gl_info
=
&
device
->
adapter
->
gl_info
;
...
...
@@ -575,12 +737,41 @@ static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *de
}
break
;
case
WINED3D_QUERY_TYPE_VCACHE
:
case
WINED3D_QUERY_TYPE_RESOURCE_MANAGER
:
case
WINED3D_QUERY_TYPE_VERTEX_STATS
:
case
WINED3D_QUERY_TYPE_TIMESTAMP
:
TRACE
(
"Timestamp query.
\n
"
);
if
(
!
gl_info
->
supported
[
ARB_TIMER_QUERY
])
{
WARN
(
"Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.
\n
"
);
return
WINED3DERR_NOTAVAILABLE
;
}
query
->
query_ops
=
&
timestamp_query_ops
;
query
->
data_size
=
sizeof
(
UINT64
);
query
->
extendedData
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
wined3d_timestamp_query
));
if
(
!
query
->
extendedData
)
{
ERR
(
"Failed to allocate timestamp query extended data.
\n
"
);
return
E_OUTOFMEMORY
;
}
((
struct
wined3d_timestamp_query
*
)
query
->
extendedData
)
->
context
=
NULL
;
break
;
case
WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
:
case
WINED3D_QUERY_TYPE_TIMESTAMP_FREQ
:
TRACE
(
"TIMESTAMP_DISJOINT query.
\n
"
);
if
(
!
gl_info
->
supported
[
ARB_TIMER_QUERY
])
{
WARN
(
"Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.
\n
"
);
return
WINED3DERR_NOTAVAILABLE
;
}
query
->
query_ops
=
&
timestamp_disjoint_query_ops
;
query
->
data_size
=
type
==
WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
?
sizeof
(
struct
wined3d_query_data_timestamp_disjoint
)
:
sizeof
(
UINT64
);
query
->
extendedData
=
NULL
;
break
;
case
WINED3D_QUERY_TYPE_VCACHE
:
case
WINED3D_QUERY_TYPE_RESOURCE_MANAGER
:
case
WINED3D_QUERY_TYPE_VERTEX_STATS
:
case
WINED3D_QUERY_TYPE_PIPELINE_TIMINGS
:
case
WINED3D_QUERY_TYPE_INTERFACE_TIMINGS
:
case
WINED3D_QUERY_TYPE_VERTEX_TIMINGS
:
...
...
dlls/wined3d/wined3d_private.h
View file @
a1784d9e
...
...
@@ -1045,6 +1045,16 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_
void
wined3d_event_query_issue
(
struct
wined3d_event_query
*
query
,
const
struct
wined3d_device
*
device
)
DECLSPEC_HIDDEN
;
BOOL
wined3d_event_query_supported
(
const
struct
wined3d_gl_info
*
gl_info
)
DECLSPEC_HIDDEN
;
struct
wined3d_timestamp_query
{
struct
list
entry
;
GLuint
id
;
struct
wined3d_context
*
context
;
};
void
context_alloc_timestamp_query
(
struct
wined3d_context
*
context
,
struct
wined3d_timestamp_query
*
query
)
DECLSPEC_HIDDEN
;
void
context_free_timestamp_query
(
struct
wined3d_timestamp_query
*
query
)
DECLSPEC_HIDDEN
;
struct
wined3d_context
{
const
struct
wined3d_gl_info
*
gl_info
;
...
...
@@ -1137,6 +1147,11 @@ struct wined3d_context
UINT
free_event_query_count
;
struct
list
event_queries
;
GLuint
*
free_timestamp_queries
;
UINT
free_timestamp_query_size
;
UINT
free_timestamp_query_count
;
struct
list
timestamp_queries
;
struct
wined3d_stream_info
stream_info
;
/* Fences for GL_APPLE_flush_buffer_range */
...
...
include/wine/wined3d.h
View file @
a1784d9e
...
...
@@ -710,6 +710,12 @@ enum wined3d_query_type
WINED3D_QUERY_TYPE_CACHE_UTILIZATION
=
18
};
struct
wined3d_query_data_timestamp_disjoint
{
UINT64
frequency
;
BOOL
disjoint
;
};
#define WINED3DISSUE_BEGIN (1 << 1)
#define WINED3DISSUE_END (1 << 0)
#define WINED3DGETDATA_FLUSH (1 << 0)
...
...
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