mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-01-08 05:13:58 +00:00
161 lines
4.2 KiB
C
161 lines
4.2 KiB
C
/**
|
|
* Looking Glass
|
|
* Copyright © 2017-2024 The Looking Glass Authors
|
|
* https://looking-glass.io
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "command_group.h"
|
|
#include "d12.h"
|
|
|
|
#include "com_ref.h"
|
|
#include "common/debug.h"
|
|
#include "common/windebug.h"
|
|
|
|
bool d12_commandGroupCreate(ID3D12Device3 * device, D3D12_COMMAND_LIST_TYPE type,
|
|
D12CommandGroup * dst, LPCWSTR name)
|
|
{
|
|
bool result = false;
|
|
HRESULT hr;
|
|
comRef_scopePush(10);
|
|
|
|
comRef_defineLocal(ID3D12CommandAllocator, allocator);
|
|
hr = ID3D12Device3_CreateCommandAllocator(
|
|
device,
|
|
type,
|
|
&IID_ID3D12CommandAllocator,
|
|
(void **)allocator);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_ERROR("Failed to create the ID3D12CommandAllocator");
|
|
goto exit;
|
|
}
|
|
ID3D12CommandAllocator_SetName(*allocator, name);
|
|
|
|
comRef_defineLocal(ID3D12GraphicsCommandList, gfxList);
|
|
hr = ID3D12Device3_CreateCommandList(
|
|
device,
|
|
0,
|
|
type,
|
|
*allocator,
|
|
NULL,
|
|
&IID_ID3D12GraphicsCommandList,
|
|
(void **)gfxList);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to create ID3D12GraphicsCommandList", hr);
|
|
goto exit;
|
|
}
|
|
ID3D12GraphicsCommandList_SetName(*gfxList, name);
|
|
|
|
comRef_defineLocal(ID3D12CommandList, cmdList);
|
|
hr = ID3D12GraphicsCommandList_QueryInterface(
|
|
*gfxList, &IID_ID3D12CommandList, (void **)cmdList);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to query the ID3D12CommandList interface", hr);
|
|
goto exit;
|
|
}
|
|
|
|
comRef_defineLocal(ID3D12Fence, fence);
|
|
hr = ID3D12Device3_CreateFence(
|
|
device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)fence);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to create ID3D12Fence", hr);
|
|
goto exit;
|
|
}
|
|
|
|
// Create the completion event for the fence
|
|
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
if (!event)
|
|
{
|
|
DEBUG_WINERROR("Failed to create the completion event", GetLastError());
|
|
goto exit;
|
|
}
|
|
|
|
comRef_toGlobal(dst->allocator, allocator);
|
|
comRef_toGlobal(dst->gfxList , gfxList );
|
|
comRef_toGlobal(dst->cmdList , cmdList );
|
|
comRef_toGlobal(dst->fence , fence );
|
|
dst->event = event;
|
|
dst->fenceValue = 0;
|
|
|
|
result = true;
|
|
|
|
exit:
|
|
comRef_scopePop();
|
|
return result;
|
|
}
|
|
|
|
void d12_commandGroupFree(D12CommandGroup * grp)
|
|
{
|
|
// only the handle needs to be free'd, the rest is handled by comRef
|
|
if (grp->event)
|
|
{
|
|
CloseHandle(grp->event);
|
|
grp->event = NULL;
|
|
}
|
|
}
|
|
|
|
bool d12_commandGroupExecute(ID3D12CommandQueue * queue, D12CommandGroup * grp)
|
|
{
|
|
HRESULT hr = ID3D12GraphicsCommandList_Close(*grp->gfxList);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to close the command list", hr);
|
|
return false;
|
|
}
|
|
|
|
ID3D12CommandQueue_ExecuteCommandLists(queue, 1, grp->cmdList);
|
|
|
|
hr = ID3D12CommandQueue_Signal(queue, *grp->fence, ++grp->fenceValue);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to set the fence signal", hr);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void d12_commandGroupWait(D12CommandGroup * grp)
|
|
{
|
|
if (ID3D12Fence_GetCompletedValue(*grp->fence) >= grp->fenceValue)
|
|
return;
|
|
|
|
ID3D12Fence_SetEventOnCompletion(*grp->fence, grp->fenceValue, grp->event);
|
|
WaitForSingleObject(grp->event, INFINITE);
|
|
}
|
|
|
|
bool d12_commandGroupReset(D12CommandGroup * grp)
|
|
{
|
|
HRESULT hr = ID3D12CommandAllocator_Reset(*grp->allocator);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to reset the command allocator", hr);
|
|
return false;
|
|
}
|
|
|
|
hr = ID3D12GraphicsCommandList_Reset(*grp->gfxList, *grp->allocator, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_WINERROR("Failed to reset the graphics command list", hr);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|