Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
1181762f
Commit
1181762f
authored
Mar 21, 2010
by
Stefan Dösinger
Committed by
Alexandre Julliard
Mar 23, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wined3d: Implement manual buffer fencing.
parent
fd13a6ae
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
157 additions
and
10 deletions
+157
-10
buffer.c
dlls/wined3d/buffer.c
+63
-6
device.c
dlls/wined3d/device.c
+8
-0
drawprim.c
dlls/wined3d/drawprim.c
+5
-0
query.c
dlls/wined3d/query.c
+72
-4
wined3d_private.h
dlls/wined3d/wined3d_private.h
+9
-0
No files found.
dlls/wined3d/buffer.c
View file @
1181762f
...
...
@@ -108,6 +108,11 @@ static void delete_gl_buffer(struct wined3d_buffer *This)
LEAVE_GL
();
This
->
buffer_object
=
0
;
if
(
This
->
query
)
{
wined3d_event_query_destroy
(
This
->
query
);
This
->
query
=
NULL
;
}
This
->
flags
&=
~
WINED3D_BUFFER_APPLESYNC
;
}
...
...
@@ -774,23 +779,68 @@ static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface)
return
resource_get_priority
((
IWineD3DResource
*
)
iface
);
}
/* The caller provides a context and
GL locking and
binds the buffer */
static
void
buffer_sync_apple
(
struct
wined3d_buffer
*
This
,
DWORD
flags
)
/* The caller provides a context and binds the buffer */
static
void
buffer_sync_apple
(
struct
wined3d_buffer
*
This
,
DWORD
flags
,
const
struct
wined3d_gl_info
*
gl_info
)
{
enum
wined3d_event_query_result
ret
;
/* No fencing needs to be done if the app promises not to overwrite
* existing data */
if
(
flags
&
WINED3DLOCK_NOOVERWRITE
)
return
;
if
(
flags
&
WINED3DLOCK_DISCARD
)
{
ENTER_GL
();
GL_EXTCALL
(
glBufferDataARB
(
This
->
buffer_type_hint
,
This
->
resource
.
size
,
NULL
,
This
->
buffer_object_usage
));
checkGLcall
(
"glBufferDataARB
\n
"
);
LEAVE_GL
();
return
;
}
/* Drop the unserialized updates for now */
FIXME
(
"Implement fences for unserialized buffers
\n
"
);
if
(
!
This
->
query
)
{
HRESULT
hr
;
TRACE
(
"Creating event query for buffer %p
\n
"
,
This
);
hr
=
wined3d_event_query_init
(
gl_info
,
&
This
->
query
);
if
(
FAILED
(
hr
))
{
ERR
(
"Failed to create an event query, dropping async buffer locks
\n
"
);
goto
drop_query
;
}
/* Since we don't know about old draws a glFinish is needed once */
wglFinish
();
return
;
}
TRACE
(
"Synchronizing buffer %p
\n
"
,
This
);
ret
=
wined3d_event_query_finish
(
This
->
query
,
This
->
resource
.
device
);
switch
(
ret
)
{
case
WINED3D_EVENT_QUERY_NOT_STARTED
:
case
WINED3D_EVENT_QUERY_OK
:
/* All done */
return
;
case
WINED3D_EVENT_QUERY_WRONG_THREAD
:
WARN
(
"Cannot synchronize buffer lock due to a thread conflict
\n
"
);
goto
drop_query
;
default:
ERR
(
"wined3d_event_query_finish returned %u, dropping async buffer locks
\n
"
,
ret
);
goto
drop_query
;
}
drop_query:
if
(
This
->
query
)
{
wined3d_event_query_destroy
(
This
->
query
);
This
->
query
=
NULL
;
}
wglFinish
();
ENTER_GL
();
GL_EXTCALL
(
glBufferParameteriAPPLE
(
This
->
buffer_type_hint
,
GL_BUFFER_SERIALIZED_MODIFY_APPLE
,
GL_TRUE
));
checkGLcall
(
"glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"
);
LEAVE_GL
();
This
->
flags
&=
~
WINED3D_BUFFER_APPLESYNC
;
}
...
...
@@ -826,7 +876,9 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined
DWORD
syncflags
=
0
;
if
(
flags
&
WINED3D_BUFFER_DISCARD
)
syncflags
|=
WINED3DLOCK_DISCARD
;
if
(
flags
&
WINED3D_BUFFER_NOSYNC
)
syncflags
|=
WINED3DLOCK_NOOVERWRITE
;
buffer_sync_apple
(
This
,
syncflags
);
LEAVE_GL
();
buffer_sync_apple
(
This
,
syncflags
,
gl_info
);
ENTER_GL
();
}
map
=
GL_EXTCALL
(
glMapBufferARB
(
This
->
buffer_type_hint
,
GL_WRITE_ONLY_ARB
));
checkGLcall
(
"glMapBufferARB"
);
...
...
@@ -1216,7 +1268,12 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
}
else
{
if
(
This
->
flags
&
WINED3D_BUFFER_APPLESYNC
)
buffer_sync_apple
(
This
,
flags
);
if
(
This
->
flags
&
WINED3D_BUFFER_APPLESYNC
)
{
LEAVE_GL
();
buffer_sync_apple
(
This
,
flags
,
gl_info
);
ENTER_GL
();
}
This
->
resource
.
allocatedMemory
=
GL_EXTCALL
(
glMapBufferARB
(
This
->
buffer_type_hint
,
GL_READ_WRITE_ARB
));
checkGLcall
(
"glMapBufferARB"
);
}
...
...
dlls/wined3d/device.c
View file @
1181762f
...
...
@@ -305,6 +305,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
}
}
This
->
num_buffer_queries
=
0
;
if
(
!
This
->
stateBlock
->
streamIsUP
)
{
WORD
map
=
stream_info
->
use_map
;
...
...
@@ -314,6 +315,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
{
struct
wined3d_stream_info_element
*
element
;
struct
wined3d_buffer
*
buffer
;
struct
wined3d_event_query
*
query
;
if
(
!
(
map
&
1
))
continue
;
...
...
@@ -327,6 +329,12 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
element
->
buffer_object
=
0
;
element
->
data
=
buffer_get_sysmem
(
buffer
)
+
(
ptrdiff_t
)
element
->
data
;
}
query
=
((
struct
wined3d_buffer
*
)
buffer
)
->
query
;
if
(
query
)
{
This
->
buffer_queries
[
This
->
num_buffer_queries
++
]
=
query
;
}
}
}
}
...
...
dlls/wined3d/drawprim.c
View file @
1181762f
...
...
@@ -689,6 +689,11 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
/* Finished updating the screen, restore lock */
LEAVE_GL
();
for
(
i
=
0
;
i
<
This
->
num_buffer_queries
;
i
++
)
{
wined3d_event_query_issue
(
This
->
buffer_queries
[
i
],
This
);
}
wglFlush
();
/* Flush to ensure ordering across contexts. */
context_release
(
context
);
...
...
dlls/wined3d/query.c
View file @
1181762f
...
...
@@ -27,7 +27,7 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
d3d
);
#define GLINFO_LOCATION (*gl_info)
static
HRESULT
wined3d_event_query_init
(
const
struct
wined3d_gl_info
*
gl_info
,
struct
wined3d_event_query
**
query
)
HRESULT
wined3d_event_query_init
(
const
struct
wined3d_gl_info
*
gl_info
,
struct
wined3d_event_query
**
query
)
{
struct
wined3d_event_query
*
ret
;
*
query
=
NULL
;
...
...
@@ -45,13 +45,13 @@ static HRESULT wined3d_event_query_init(const struct wined3d_gl_info *gl_info, s
return
WINED3D_OK
;
}
static
void
wined3d_event_query_destroy
(
struct
wined3d_event_query
*
query
)
void
wined3d_event_query_destroy
(
struct
wined3d_event_query
*
query
)
{
if
(
query
->
context
)
context_free_event_query
(
query
);
HeapFree
(
GetProcessHeap
(),
0
,
query
);
}
static
enum
wined3d_event_query_result
wined3d_event_query_test
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
enum
wined3d_event_query_result
wined3d_event_query_test
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
{
struct
wined3d_context
*
context
;
const
struct
wined3d_gl_info
*
gl_info
;
...
...
@@ -125,7 +125,75 @@ static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_e
return
ret
;
}
static
void
wined3d_event_query_issue
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
enum
wined3d_event_query_result
wined3d_event_query_finish
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
{
struct
wined3d_context
*
context
;
const
struct
wined3d_gl_info
*
gl_info
;
enum
wined3d_event_query_result
ret
;
TRACE
(
"(%p)
\n
"
,
query
);
if
(
!
query
->
context
)
{
TRACE
(
"Query not started
\n
"
);
return
WINED3D_EVENT_QUERY_NOT_STARTED
;
}
gl_info
=
query
->
context
->
gl_info
;
if
(
query
->
context
->
tid
!=
GetCurrentThreadId
()
&&
!
gl_info
->
supported
[
ARB_SYNC
])
{
/* A glFinish does not reliably wait for draws in other contexts. The caller has
* to find its own way to cope with the thread switch
*/
WARN
(
"Event query finished from wrong thread
\n
"
);
return
WINED3D_EVENT_QUERY_WRONG_THREAD
;
}
context
=
context_acquire
(
device
,
query
->
context
->
current_rt
,
CTXUSAGE_RESOURCELOAD
);
ENTER_GL
();
if
(
gl_info
->
supported
[
ARB_SYNC
])
{
GLenum
gl_ret
=
GL_EXTCALL
(
glClientWaitSync
(
query
->
object
.
sync
,
0
,
~
(
GLuint64
)
0
));
checkGLcall
(
"glClientWaitSync"
);
switch
(
gl_ret
)
{
case
GL_ALREADY_SIGNALED
:
case
GL_CONDITION_SATISFIED
:
ret
=
WINED3D_EVENT_QUERY_OK
;
break
;
/* We don't expect a timeout for a ~584 year wait */
default:
ERR
(
"glClientWaitSync returned %#x.
\n
"
,
gl_ret
);
ret
=
WINED3D_EVENT_QUERY_ERROR
;
}
}
else
if
(
context
->
gl_info
->
supported
[
APPLE_FENCE
])
{
GL_EXTCALL
(
glFinishFenceAPPLE
(
query
->
object
.
id
));
checkGLcall
(
"glFinishFenceAPPLE"
);
ret
=
WINED3D_EVENT_QUERY_OK
;
}
else
if
(
context
->
gl_info
->
supported
[
NV_FENCE
])
{
GL_EXTCALL
(
glFinishFenceNV
(
query
->
object
.
id
));
checkGLcall
(
"glFinishFenceNV"
);
ret
=
WINED3D_EVENT_QUERY_OK
;
}
else
{
ERR
(
"Event query created without GL support
\n
"
);
ret
=
WINED3D_EVENT_QUERY_ERROR
;
}
LEAVE_GL
();
context_release
(
context
);
return
ret
;
}
void
wined3d_event_query_issue
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
{
const
struct
wined3d_gl_info
*
gl_info
;
struct
wined3d_context
*
context
;
...
...
dlls/wined3d/wined3d_private.h
View file @
1181762f
...
...
@@ -1033,6 +1033,12 @@ enum wined3d_event_query_result
WINED3D_EVENT_QUERY_ERROR
};
HRESULT
wined3d_event_query_init
(
const
struct
wined3d_gl_info
*
gl_info
,
struct
wined3d_event_query
**
query
)
DECLSPEC_HIDDEN
;
void
wined3d_event_query_destroy
(
struct
wined3d_event_query
*
query
)
DECLSPEC_HIDDEN
;
enum
wined3d_event_query_result
wined3d_event_query_test
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
DECLSPEC_HIDDEN
;
enum
wined3d_event_query_result
wined3d_event_query_finish
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
DECLSPEC_HIDDEN
;
void
wined3d_event_query_issue
(
struct
wined3d_event_query
*
query
,
IWineD3DDeviceImpl
*
device
)
DECLSPEC_HIDDEN
;
struct
wined3d_context
{
const
struct
wined3d_gl_info
*
gl_info
;
...
...
@@ -1695,6 +1701,8 @@ struct IWineD3DDeviceImpl
/* Stream source management */
struct
wined3d_stream_info
strided_streams
;
const
WineDirect3DVertexStridedData
*
up_strided
;
struct
wined3d_event_query
*
buffer_queries
[
MAX_ATTRIBS
];
unsigned
int
num_buffer_queries
;
/* Context management */
struct
wined3d_context
**
contexts
;
...
...
@@ -2495,6 +2503,7 @@ struct wined3d_buffer
LONG
lock_count
;
struct
wined3d_map_range
*
maps
;
ULONG
maps_size
,
modified_areas
;
struct
wined3d_event_query
*
query
;
/* conversion stuff */
UINT
decl_change_count
,
full_conversion_count
;
...
...
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