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.
This commit is contained in:
parent
278e406f0b
commit
d6b6b070bc
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <strsafe.h>
|
#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.
|
// 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.
|
// Nvidia 3D Vision supports full SBS, so there is no loss in resolution during this process.
|
||||||
D3D11_SUBRESOURCE_DATA sysData;
|
NVSTEREOIMAGEHEADER header;
|
||||||
sysData.SysMemPitch = 4 * width * 2;
|
header.dwSignature = NVSTEREO_IMAGE_SIGNATURE;
|
||||||
sysData.pSysMem = new u8[(height + 1) * sysData.SysMemPitch];
|
header.dwWidth = static_cast<u32>(width * 2);
|
||||||
LPNVSTEREOIMAGEHEADER header =
|
header.dwHeight = static_cast<u32>(height + 1);
|
||||||
(LPNVSTEREOIMAGEHEADER)((u8*)sysData.pSysMem + height * sysData.SysMemPitch);
|
header.dwBPP = 32;
|
||||||
header->dwSignature = NVSTEREO_IMAGE_SIGNATURE;
|
header.dwFlags = 0;
|
||||||
header->dwWidth = width * 2;
|
|
||||||
header->dwHeight = height + 1;
|
const u32 pitch = static_cast<u32>(4 * width * 2);
|
||||||
header->dwBPP = 32;
|
const auto memory = std::make_unique<u8[]>((height + 1) * pitch);
|
||||||
header->dwFlags = 0;
|
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 =
|
s_3d_vision_texture =
|
||||||
D3DTexture2D::Create(width * 2, height + 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT,
|
D3DTexture2D::Create(width * 2, height + 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT,
|
||||||
DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sysData);
|
DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sys_data);
|
||||||
delete[] sysData.pSysMem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight())
|
Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight())
|
||||||
|
|
Loading…
Reference in New Issue