Skip to content

Commit 84ef685

Browse files
committed
Add support for calling "update_buffer_region" with size "UINT64_MAX"
1 parent 25b70ba commit 84ef685

File tree

9 files changed

+72
-39
lines changed

9 files changed

+72
-39
lines changed

source/d3d10/d3d10_device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ void STDMETHODCALLTYPE D3D10Device::UpdateSubresource(ID3D10Resource *pDstRes
567567
if (type == D3D10_RESOURCE_DIMENSION_BUFFER)
568568
{
569569
assert(DstSubresource == 0);
570-
570+
571571
if (reshade::invoke_addon_event<reshade::addon_event::update_buffer_region>(
572572
this,
573573
pSrcData,

source/d3d10/d3d10_impl_device.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,14 @@ void reshade::d3d10::device_impl::unmap_texture_region(api::resource resource, u
548548
void reshade::d3d10::device_impl::update_buffer_region(const void *data, api::resource resource, uint64_t offset, uint64_t size)
549549
{
550550
assert(resource != 0);
551+
552+
if (UINT64_MAX == size)
553+
{
554+
D3D10_BUFFER_DESC desc;
555+
reinterpret_cast<ID3D10Buffer *>(resource.handle)->GetDesc(&desc);
556+
size = desc.ByteWidth;
557+
}
558+
551559
assert(offset <= std::numeric_limits<UINT>::max() && size <= std::numeric_limits<UINT>::max());
552560

553561
if (data == nullptr)

source/d3d11/d3d11_device_context.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,7 @@ void STDMETHODCALLTYPE D3D11DeviceContext::CopySubresourceRegion1(ID3D11Resou
11871187
pSrcBox != nullptr ? pSrcBox->left : 0,
11881188
to_handle(pDstResource),
11891189
DstX,
1190-
pSrcBox != nullptr ? pSrcBox->right - pSrcBox->left : ~0ull))
1190+
pSrcBox != nullptr ? pSrcBox->right - pSrcBox->left : UINT64_MAX))
11911191
return;
11921192
}
11931193
else
@@ -1312,7 +1312,7 @@ void STDMETHODCALLTYPE D3D11DeviceContext::UpdateSubresource1(ID3D11Resource
13121312
if (type == D3D11_RESOURCE_DIMENSION_BUFFER)
13131313
{
13141314
assert(DstSubresource == 0);
1315-
1315+
13161316
if (reshade::invoke_addon_event<reshade::addon_event::update_buffer_region_command>(
13171317
this,
13181318
pSrcData,

source/d3d11/d3d11_impl_device.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,14 @@ void reshade::d3d11::device_impl::unmap_texture_region(api::resource resource, u
680680
void reshade::d3d11::device_impl::update_buffer_region(const void *data, api::resource resource, uint64_t offset, uint64_t size)
681681
{
682682
assert(resource != 0);
683+
684+
if (UINT64_MAX == size)
685+
{
686+
D3D11_BUFFER_DESC desc;
687+
reinterpret_cast<ID3D11Buffer *>(resource.handle)->GetDesc(&desc);
688+
size = desc.ByteWidth;
689+
}
690+
683691
assert(offset <= std::numeric_limits<UINT>::max() && size <= std::numeric_limits<UINT>::max());
684692

685693
if (data == nullptr)

source/d3d12/d3d12_impl_device.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,9 @@ void reshade::d3d12::device_impl::update_buffer_region(const void *data, api::re
708708
if (immediate_command_list == nullptr)
709709
return; // No point in creating upload buffer when it cannot be uploaded
710710

711+
if (UINT64_MAX == size)
712+
size = reinterpret_cast<ID3D12Resource *>(resource.handle)->GetDesc().Width;
713+
711714
// Allocate host memory for upload
712715
D3D12_RESOURCE_DESC intermediate_desc = { D3D12_RESOURCE_DIMENSION_BUFFER };
713716
intermediate_desc.Width = size;

source/d3d9/d3d9_impl_device.cpp

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,38 +1033,24 @@ void reshade::d3d9::device_impl::unmap_texture_region(api::resource resource, ui
10331033
void reshade::d3d9::device_impl::update_buffer_region(const void *data, api::resource resource, uint64_t offset, uint64_t size)
10341034
{
10351035
assert(resource != 0);
1036-
assert(offset <= std::numeric_limits<UINT>::max() && size <= std::numeric_limits<UINT>::max());
1036+
assert(offset <= std::numeric_limits<UINT>::max() && (size == UINT64_MAX || size <= std::numeric_limits<UINT>::max()));
10371037

10381038
if (data == nullptr)
10391039
return;
10401040

10411041
const auto object = reinterpret_cast<IDirect3DResource9 *>(resource.handle);
10421042

1043-
switch (IDirect3DResource9_GetType(object))
1043+
// 'IDirect3DVertexBuffer9_Lock' and 'IDirect3DIndexBuffer9_Lock' are located at the same virtual function table index and have the same interface
1044+
if (void *mapped_data;
1045+
SUCCEEDED(IDirect3DVertexBuffer9_Lock(
1046+
static_cast<IDirect3DVertexBuffer9 *>(object),
1047+
static_cast<UINT>(offset),
1048+
size != UINT64_MAX ? static_cast<UINT>(size) : 0,
1049+
&mapped_data,
1050+
0)))
10441051
{
1045-
case D3DRTYPE_VERTEXBUFFER:
1046-
{
1047-
void *mapped_ptr;
1048-
if (SUCCEEDED(IDirect3DVertexBuffer9_Lock(static_cast<IDirect3DVertexBuffer9 *>(object), static_cast<UINT>(offset), static_cast<UINT>(size), &mapped_ptr, 0)))
1049-
{
1050-
std::memcpy(mapped_ptr, data, static_cast<size_t>(size));
1051-
IDirect3DVertexBuffer9_Unlock(static_cast<IDirect3DVertexBuffer9 *>(object));
1052-
}
1053-
}
1054-
break;
1055-
case D3DRTYPE_INDEXBUFFER:
1056-
{
1057-
void *mapped_ptr;
1058-
if (SUCCEEDED(IDirect3DIndexBuffer9_Lock(static_cast<IDirect3DIndexBuffer9 *>(object), static_cast<UINT>(offset), static_cast<UINT>(size), &mapped_ptr, 0)))
1059-
{
1060-
std::memcpy(mapped_ptr, data, static_cast<size_t>(size));
1061-
IDirect3DIndexBuffer9_Unlock(static_cast<IDirect3DIndexBuffer9 *>(object));
1062-
}
1063-
}
1064-
break;
1065-
default:
1066-
assert(false); // Not implemented
1067-
break;
1052+
std::memcpy(mapped_data, data, static_cast<size_t>(size));
1053+
IDirect3DVertexBuffer9_Unlock(static_cast<IDirect3DVertexBuffer9 *>(object));
10681054
}
10691055
}
10701056
void reshade::d3d9::device_impl::update_texture_region(const api::subresource_data &data, api::resource resource, uint32_t subresource, const api::subresource_box *box)
@@ -1611,11 +1597,11 @@ bool reshade::d3d9::device_impl::create_pipeline(api::pipeline_layout, uint32_t
16111597
goto exit_failure;
16121598
}
16131599

1614-
if (float *data;
1615-
SUCCEEDED(IDirect3DVertexBuffer9_Lock(_default_input_stream.get(), 0, max_vertices * sizeof(float), reinterpret_cast<void **>(&data), 0)))
1600+
if (float *mapped_data;
1601+
SUCCEEDED(IDirect3DVertexBuffer9_Lock(_default_input_stream.get(), 0, max_vertices * sizeof(float), reinterpret_cast<void **>(&mapped_data), 0)))
16161602
{
16171603
for (UINT i = 0; i < max_vertices; ++i)
1618-
data[i] = static_cast<float>(i);
1604+
mapped_data[i] = static_cast<float>(i);
16191605
IDirect3DVertexBuffer9_Unlock(_default_input_stream.get());
16201606
}
16211607
}

source/opengl/opengl_impl_device.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,7 @@ void reshade::opengl::device_impl::unmap_texture_region(api::resource resource,
18031803
void reshade::opengl::device_impl::update_buffer_region(const void *data, api::resource resource, uint64_t offset, uint64_t size)
18041804
{
18051805
assert(resource != 0 && (resource.handle >> 40) == GL_BUFFER);
1806-
assert(offset <= static_cast<uint64_t>(std::numeric_limits<GLintptr>::max()) && size <= static_cast<uint64_t>(std::numeric_limits<GLsizeiptr>::max()));
1806+
assert(offset <= static_cast<uint64_t>(std::numeric_limits<GLintptr>::max()) && (size == UINT64_MAX || size <= static_cast<uint64_t>(std::numeric_limits<GLsizeiptr>::max())));
18071807

18081808
if (data == nullptr)
18091809
return;
@@ -1812,6 +1812,18 @@ void reshade::opengl::device_impl::update_buffer_region(const void *data, api::r
18121812

18131813
if (gl.VERSION_4_5)
18141814
{
1815+
if (UINT64_MAX == size)
1816+
{
1817+
#ifndef _WIN64
1818+
GLint max_size = 0;
1819+
gl.GetNamedBufferParameteriv(object, GL_BUFFER_SIZE, &max_size);
1820+
#else
1821+
GLint64 max_size = 0;
1822+
gl.GetNamedBufferParameteri64v(object, GL_BUFFER_SIZE, &max_size);
1823+
#endif
1824+
size = max_size;
1825+
}
1826+
18151827
gl.NamedBufferSubData(object, static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size), data);
18161828
}
18171829
else
@@ -1821,6 +1833,18 @@ void reshade::opengl::device_impl::update_buffer_region(const void *data, api::r
18211833
if (object != prev_binding)
18221834
gl.BindBuffer(GL_COPY_WRITE_BUFFER, object);
18231835

1836+
if (UINT64_MAX == size)
1837+
{
1838+
#ifndef _WIN64
1839+
GLint max_size = 0;
1840+
gl.GetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &max_size);
1841+
#else
1842+
GLint64 max_size = 0;
1843+
gl.GetBufferParameteri64v(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &max_size);
1844+
#endif
1845+
size = max_size;
1846+
}
1847+
18241848
gl.BufferSubData(GL_COPY_WRITE_BUFFER, static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size), data);
18251849

18261850
// The 'GL_COPY_WRITE_BUFFER' target does not affect other OpenGL state, so should be fine to leave it bound

source/vulkan/vulkan_impl_command_list.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ void reshade::vulkan::command_list_impl::copy_resource(api::resource src, api::r
768768

769769
if (desc.type == api::resource_type::buffer)
770770
{
771-
copy_buffer_region(src, 0, dst, 0, ~0llu);
771+
copy_buffer_region(src, 0, dst, 0, UINT64_MAX);
772772
}
773773
else
774774
{

source/vulkan/vulkan_impl_device.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,14 +1140,18 @@ void reshade::vulkan::device_impl::update_buffer_region(const void *data, api::r
11401140
if (data == nullptr)
11411141
return;
11421142

1143-
if (const auto immediate_command_list = get_immediate_command_list())
1144-
{
1145-
immediate_command_list->_has_commands = true;
1143+
const auto immediate_command_list = get_immediate_command_list();
1144+
if (immediate_command_list == nullptr)
1145+
return;
11461146

1147-
vk.CmdUpdateBuffer(immediate_command_list->_orig, (VkBuffer)resource.handle, offset, size, data);
1147+
if (UINT64_MAX == size)
1148+
size = get_private_data_for_object<VK_OBJECT_TYPE_BUFFER>((VkBuffer)resource.handle)->create_info.size;
11481149

1149-
immediate_command_list->flush_and_wait();
1150-
}
1150+
immediate_command_list->_has_commands = true;
1151+
1152+
vk.CmdUpdateBuffer(immediate_command_list->_orig, (VkBuffer)resource.handle, offset, size, data);
1153+
1154+
immediate_command_list->flush_and_wait();
11511155
}
11521156
void reshade::vulkan::device_impl::update_texture_region(const api::subresource_data &data, api::resource resource, uint32_t subresource, const api::subresource_box *box)
11531157
{

0 commit comments

Comments
 (0)