[PATCH 6/6] wined3d: Implement NOOVERWRITE and DISCARD volume maps
Stefan Dösinger
stefan at codeweavers.com
Thu Aug 22 16:22:50 CDT 2013
---
dlls/wined3d/buffer.c | 54 ++----------------------------------------
dlls/wined3d/resource.c | 50 ++++++++++++++++++++++++++++++++++++++
dlls/wined3d/volume.c | 42 ++++++++++++++++++++++++--------
dlls/wined3d/wined3d_private.h | 3 +++
4 files changed, 87 insertions(+), 62 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index b3f760b..8178604 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -922,56 +922,6 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
context_release(context);
}
-static DWORD buffer_sanitize_flags(const struct wined3d_buffer *buffer, DWORD flags)
-{
- /* Not all flags make sense together, but Windows never returns an error.
- * Catch the cases that could cause issues. */
- if (flags & WINED3D_MAP_READONLY)
- {
- if (flags & WINED3D_MAP_DISCARD)
- {
- WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
- return 0;
- }
- if (flags & WINED3D_MAP_NOOVERWRITE)
- {
- WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
- return 0;
- }
- }
- else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
- == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
- {
- WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
- return 0;
- }
- else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
- && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
- {
- WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
- return 0;
- }
-
- return flags;
-}
-
-static GLbitfield buffer_gl_map_flags(DWORD d3d_flags)
-{
- GLbitfield ret = 0;
-
- if (!(d3d_flags & WINED3D_MAP_READONLY))
- ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
- if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
- ret |= GL_MAP_READ_BIT;
-
- if (d3d_flags & WINED3D_MAP_DISCARD)
- ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
- if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
- ret |= GL_MAP_UNSYNCHRONIZED_BIT;
-
- return ret;
-}
-
struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer)
{
TRACE("buffer %p.\n", buffer);
@@ -986,7 +936,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags);
- flags = buffer_sanitize_flags(buffer, flags);
+ flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags);
count = ++buffer->resource.map_count;
if (buffer->buffer_object)
@@ -1017,7 +967,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
- GLbitfield mapflags = buffer_gl_map_flags(flags);
+ GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint,
0, buffer->resource.size, mapflags));
checkGLcall("glMapBufferRange");
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 59fced9..ca322b2 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -358,3 +358,53 @@ void wined3d_resource_free_sysmem(void *mem)
HeapFree(GetProcessHeap(), 0, *(--p));
}
+
+DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags)
+{
+ /* Not all flags make sense together, but Windows never returns an error.
+ * Catch the cases that could cause issues. */
+ if (flags & WINED3D_MAP_READONLY)
+ {
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
+ return 0;
+ }
+ if (flags & WINED3D_MAP_NOOVERWRITE)
+ {
+ WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
+ return 0;
+ }
+ }
+ else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ {
+ WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
+ return 0;
+ }
+ else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
+ && !(resource->usage & WINED3DUSAGE_DYNAMIC))
+ {
+ WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
+ return 0;
+ }
+
+ return flags;
+}
+
+GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
+{
+ GLbitfield ret = 0;
+
+ if (!(d3d_flags & WINED3D_MAP_READONLY))
+ ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
+ if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
+ ret |= GL_MAP_READ_BIT;
+
+ if (d3d_flags & WINED3D_MAP_DISCARD)
+ ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
+ if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
+ ret |= GL_MAP_UNSYNCHRONIZED_BIT;
+
+ return ret;
+}
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index dc747e5..ae9c855 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -477,6 +477,7 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
map_desc->data = NULL;
return WINED3DERR_INVALIDCALL;
}
+ flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
if (volume->flags & WINED3D_VFLAG_PBO)
{
@@ -484,12 +485,28 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
gl_info = context->gl_info;
wined3d_volume_prepare_pbo(volume, context);
- wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
+ if (flags & WINED3D_MAP_DISCARD)
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER);
+ else
+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo)");
- base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
- checkGLcall("glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)");
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GLbitfield mapflags = wined3d_resource_gl_map_flags(flags);
+ mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT;
+ base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER_ARB,
+ 0, volume->resource.size, mapflags));
+ checkGLcall("glMapBufferRange");
+ }
+ else
+ {
+ base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)");
+ }
+
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)");
@@ -497,14 +514,19 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
}
else
{
- if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
+ if (!volume_prepare_system_memory(volume))
+ {
+ WARN("Out of memory.\n");
+ map_desc->data = NULL;
+ return E_OUTOFMEMORY;
+ }
+
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM);
+ }
+ else if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
{
- if (!volume_prepare_system_memory(volume))
- {
- WARN("Out of memory.\n");
- map_desc->data = NULL;
- return E_OUTOFMEMORY;
- }
context = context_acquire(device, NULL);
wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM);
context_release(context);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 52d1c0b..a7dd155 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1964,6 +1964,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource,
+ DWORD flags) DECLSPEC_HIDDEN;
+GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
/* Tests show that the start address of resources is 32 byte aligned */
#define RESOURCE_ALIGNMENT 16
--
1.8.1.5
More information about the wine-patches
mailing list