D3D12: Use std::thread for worker thread

Using CreateThread can create issues if any CRT calls are made, as
thread-specific data may not be initialized. Additionally, TerminateThread
is not a good idea for similar reasons, and may not free CRT resources.
This commit is contained in:
Stenzek 2016-02-17 14:25:42 +10:00
parent ffe0e326d2
commit 759b77474d
2 changed files with 11 additions and 8 deletions

View File

@ -14,9 +14,8 @@ constexpr size_t BufferOffsetForQueueItemType()
return sizeof(T) + sizeof(D3DQueueItemType) * 2;
}
DWORD WINAPI ID3D12QueuedCommandList::BackgroundThreadFunction(LPVOID param)
void ID3D12QueuedCommandList::BackgroundThreadFunction(ID3D12QueuedCommandList* parent_queued_command_list)
{
ID3D12QueuedCommandList* parent_queued_command_list = static_cast<ID3D12QueuedCommandList*>(param);
ID3D12GraphicsCommandList* command_list = parent_queued_command_list->m_command_list;
byte* queue_array = parent_queued_command_list->m_queue_array;
@ -26,6 +25,8 @@ DWORD WINAPI ID3D12QueuedCommandList::BackgroundThreadFunction(LPVOID param)
while (true)
{
WaitForSingleObject(parent_queued_command_list->m_begin_execution_event, INFINITE);
if (parent_queued_command_list->m_background_thread_exit.load())
break;
byte* item = &queue_array[queue_array_front];
@ -374,13 +375,14 @@ ID3D12QueuedCommandList::ID3D12QueuedCommandList(ID3D12GraphicsCommandList* back
m_begin_execution_event = CreateSemaphore(nullptr, 0, 256, nullptr);
m_stop_execution_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
m_background_thread = CreateThread(nullptr, 0, BackgroundThreadFunction, this, 0, &m_background_thread_id);
m_background_thread = std::thread(BackgroundThreadFunction, this);
}
ID3D12QueuedCommandList::~ID3D12QueuedCommandList()
{
TerminateThread(m_background_thread, 0);
CloseHandle(m_background_thread);
m_background_thread_exit.store(true);
ReleaseSemaphore(m_begin_execution_event, 1, nullptr);
m_background_thread.join();
CloseHandle(m_begin_execution_event);
CloseHandle(m_stop_execution_event);

View File

@ -6,6 +6,7 @@
#include <atomic>
#include <d3d12.h>
#include <thread>
namespace DX12
{
@ -612,15 +613,15 @@ private:
void ResetQueueOverflowTracking();
void CheckForOverflow();
static DWORD WINAPI BackgroundThreadFunction(LPVOID param);
static void BackgroundThreadFunction(ID3D12QueuedCommandList* parent_queued_command_list);
byte m_queue_array[QUEUE_ARRAY_SIZE];
byte* m_queue_array_back = m_queue_array;
byte* m_queue_array_back_at_start_of_frame = m_queue_array_back;
DWORD m_background_thread_id;
HANDLE m_background_thread;
std::thread m_background_thread;
std::atomic_bool m_background_thread_exit;
HANDLE m_begin_execution_event;
HANDLE m_stop_execution_event;