summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2017-04-09 17:27:20 -0400
committerLioncash <mathew1800@gmail.com>2017-05-28 23:28:00 -0400
commitd6b6b070bc483eef5fb4d5fd856ab271f3905375 (patch)
tree9cc65304eb41d4e300cf0a6a7fe69d3069b269a2 /Source/Core
parent278e406f0b7becf5ae313f342ad7c5e40a68fb85 (diff)
D3D/Render: Get rid of undefined behavior in Create3DVisionTexture
pSysMem is of the type const void* -- because of this, it makes the original delete[] call undefined behavior, as deleting a void pointer is undefined behavior. Also punning types into existence, like what was done for the stereo image header is undefined behavior as well. The proper way to do this is to either manually add all individual bytes manually, or memcpy the struct into memory. As we want to deallocate the memory before returning, and because pSysMem is a const void*, we keep a unique_ptr to the data and just pass pSysMem a raw pointer to the data.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoBackends/D3D/Render.cpp29
1 files changed, 17 insertions, 12 deletions
diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp
index 6ad2ce94af..e90f5d10f6 100644
--- a/Source/Core/VideoBackends/D3D/Render.cpp
+++ b/Source/Core/VideoBackends/D3D/Render.cpp
@@ -7,6 +7,7 @@
#include <array>
#include <cinttypes>
#include <cmath>
+#include <cstring>
#include <memory>
#include <string>
#include <strsafe.h>
@@ -214,21 +215,25 @@ static void Create3DVisionTexture(int width, int height)
{
// Create a staging texture for 3D vision with signature information in the last row.
// Nvidia 3D Vision supports full SBS, so there is no loss in resolution during this process.
- D3D11_SUBRESOURCE_DATA sysData;
- sysData.SysMemPitch = 4 * width * 2;
- sysData.pSysMem = new u8[(height + 1) * sysData.SysMemPitch];
- LPNVSTEREOIMAGEHEADER header =
- (LPNVSTEREOIMAGEHEADER)((u8*)sysData.pSysMem + height * sysData.SysMemPitch);
- header->dwSignature = NVSTEREO_IMAGE_SIGNATURE;
- header->dwWidth = width * 2;
- header->dwHeight = height + 1;
- header->dwBPP = 32;
- header->dwFlags = 0;
+ NVSTEREOIMAGEHEADER header;
+ header.dwSignature = NVSTEREO_IMAGE_SIGNATURE;
+ header.dwWidth = static_cast<u32>(width * 2);
+ header.dwHeight = static_cast<u32>(height + 1);
+ header.dwBPP = 32;
+ header.dwFlags = 0;
+
+ const u32 pitch = static_cast<u32>(4 * width * 2);
+ const auto memory = std::make_unique<u8[]>((height + 1) * pitch);
+ u8* image_header_location = &memory[height * pitch];
+ std::memcpy(image_header_location, &header, sizeof(header));
+
+ D3D11_SUBRESOURCE_DATA sys_data;
+ sys_data.SysMemPitch = pitch;
+ sys_data.pSysMem = memory.get();
s_3d_vision_texture =
D3DTexture2D::Create(width * 2, height + 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT,
- DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sysData);
- delete[] sysData.pSysMem;
+ DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sys_data);
}
Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight())