wined3d: Implement NOOVERWRITE and DISCARD volume maps.
This commit is contained in:
parent
8c708486c3
commit
bd866c0294
|
@ -922,56 +922,6 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
|
||||||
context_release(context);
|
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)
|
struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer)
|
||||||
{
|
{
|
||||||
TRACE("buffer %p.\n", 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);
|
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;
|
count = ++buffer->resource.map_count;
|
||||||
|
|
||||||
if (buffer->buffer_object)
|
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])
|
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,
|
buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint,
|
||||||
0, buffer->resource.size, mapflags));
|
0, buffer->resource.size, mapflags));
|
||||||
checkGLcall("glMapBufferRange");
|
checkGLcall("glMapBufferRange");
|
||||||
|
|
|
@ -358,3 +358,53 @@ void wined3d_resource_free_sysmem(void *mem)
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, *(--p));
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -469,6 +469,7 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
|
||||||
map_desc->data = NULL;
|
map_desc->data = NULL;
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags);
|
||||||
|
|
||||||
if (volume->flags & WINED3D_VFLAG_PBO)
|
if (volume->flags & WINED3D_VFLAG_PBO)
|
||||||
{
|
{
|
||||||
|
@ -476,18 +477,31 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
|
||||||
gl_info = context->gl_info;
|
gl_info = context->gl_info;
|
||||||
|
|
||||||
wined3d_volume_prepare_pbo(volume, context);
|
wined3d_volume_prepare_pbo(volume, context);
|
||||||
|
if (flags & WINED3D_MAP_DISCARD)
|
||||||
|
wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER);
|
||||||
|
else
|
||||||
wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
|
wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER);
|
||||||
|
|
||||||
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
|
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo));
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
base_memory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
||||||
|
}
|
||||||
|
|
||||||
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
||||||
checkGLcall("Map PBO");
|
checkGLcall("Map PBO");
|
||||||
|
|
||||||
context_release(context);
|
context_release(context);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
|
|
||||||
{
|
{
|
||||||
if (!volume_prepare_system_memory(volume))
|
if (!volume_prepare_system_memory(volume))
|
||||||
{
|
{
|
||||||
|
@ -495,6 +509,13 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
|
||||||
map_desc->data = NULL;
|
map_desc->data = NULL;
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & WINED3D_MAP_DISCARD)
|
||||||
|
{
|
||||||
|
wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM);
|
||||||
|
}
|
||||||
|
else if (!(volume->locations & WINED3D_LOCATION_SYSMEM))
|
||||||
|
{
|
||||||
context = context_acquire(device, NULL);
|
context = context_acquire(device, NULL);
|
||||||
wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM);
|
wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM);
|
||||||
context_release(context);
|
context_release(context);
|
||||||
|
|
|
@ -1968,6 +1968,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
|
||||||
const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
|
const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
|
||||||
DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
|
DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
|
||||||
void resource_unload(struct wined3d_resource *resource) 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 */
|
/* Tests show that the start address of resources is 32 byte aligned */
|
||||||
#define RESOURCE_ALIGNMENT 16
|
#define RESOURCE_ALIGNMENT 16
|
||||||
|
|
Loading…
Reference in New Issue