Using a registry setting. Games sometimes use DEFAULT usage and no CPU access combined with UpdateSubresource() for often-changing constants, causing us to interrupt the render pass and transfer through a staging buffer on each update. In such cases forcing the buffers to be mappable greatly increases performance.
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- I'm not sure if that kind of change is desired upstream, but I think it's pretty useful. --- dlls/wined3d/buffer.c | 9 +++++++-- dlls/wined3d/wined3d_main.c | 5 +++++ dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index da61f36af45..a42259a5ece 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1139,6 +1139,7 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d { const struct wined3d_format *format = wined3d_get_format(device->adapter, WINED3DFMT_R8_UNORM, desc->bind_flags); struct wined3d_resource *resource = &buffer->resource; + unsigned int access; HRESULT hr;
TRACE("buffer %p, device %p, desc byte_width %u, usage %s, bind_flags %s, " @@ -1164,8 +1165,12 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d return E_INVALIDARG; }
+ access = desc->access; + if (desc->bind_flags & WINED3D_BIND_CONSTANT_BUFFER && wined3d_settings.write_mappable_cbuffers) + access |= WINED3D_RESOURCE_ACCESS_MAP_W; + if (FAILED(hr = resource_init(resource, device, WINED3D_RTYPE_BUFFER, format, - WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->bind_flags, desc->access, + WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->bind_flags, access, desc->byte_width, 1, 1, desc->byte_width, parent, parent_ops, &buffer_resource_ops))) { WARN("Failed to initialize resource, hr %#x.\n", hr); @@ -1179,7 +1184,7 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d buffer, buffer->resource.size, buffer->resource.usage, buffer->resource.heap_memory);
if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING - || wined3d_resource_access_is_managed(desc->access)) + || wined3d_resource_access_is_managed(access)) { /* SWvp and managed buffers always return the same pointer in buffer * maps and retain data in DISCARD maps. Keep a system memory copy of diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 6e93b8dc683..a059598ec21 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -394,6 +394,11 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) wined3d_settings.renderer = WINED3D_RENDERER_NO3D; } } + if (!get_config_key_dword(hkey, appkey, "WriteMappableConstantBuffers", &tmpvalue) && tmpvalue) + { + TRACE("Forcing all constant buffers to be write-mappable.\n"); + wined3d_settings.write_mappable_cbuffers = TRUE; + } }
if (appkey) RegCloseKey( appkey ); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 86c053df0db..9357223cb97 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -482,6 +482,7 @@ struct wined3d_settings unsigned int max_sm_cs; enum wined3d_renderer renderer; enum wined3d_shader_backend shader_backend; + BOOL write_mappable_cbuffers; };
extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN;