mirror of https://github.com/AxioDL/boo.git
Windows bug fixes
This commit is contained in:
parent
41256d2673
commit
c34b93f00f
|
@ -22,6 +22,14 @@ struct SWindowRect
|
||||||
{
|
{
|
||||||
int location[2];
|
int location[2];
|
||||||
int size[2];
|
int size[2];
|
||||||
|
bool operator !=(const SWindowRect& other) const
|
||||||
|
{
|
||||||
|
return location[0] != other.location[0] ||
|
||||||
|
location[1] != other.location[1] ||
|
||||||
|
size[0] != other.size[0] ||
|
||||||
|
size[1] != other.size[1];
|
||||||
|
}
|
||||||
|
bool operator ==(const SWindowRect& other) const {return !(*this != other);}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SWindowCoord
|
struct SWindowCoord
|
||||||
|
|
|
@ -32,7 +32,6 @@ struct IGraphicsCommandQueue
|
||||||
virtual int pendingDynamicSlot()=0;
|
virtual int pendingDynamicSlot()=0;
|
||||||
|
|
||||||
virtual void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)=0;
|
virtual void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)=0;
|
||||||
virtual void flushBufferUpdates()=0;
|
|
||||||
|
|
||||||
virtual void setClearColor(const float rgba[4])=0;
|
virtual void setClearColor(const float rgba[4])=0;
|
||||||
virtual void clearTarget(bool render=true, bool depth=true)=0;
|
virtual void clearTarget(bool render=true, bool depth=true)=0;
|
||||||
|
|
|
@ -563,6 +563,8 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
D3D11Context::Window* m_windowCtx;
|
D3D11Context::Window* m_windowCtx;
|
||||||
IGraphicsContext* m_parent;
|
IGraphicsContext* m_parent;
|
||||||
ComPtr<ID3D11DeviceContext1> m_deferredCtx;
|
ComPtr<ID3D11DeviceContext1> m_deferredCtx;
|
||||||
|
ComPtr<ID3D11DeviceContext1> m_dynamicCtx;
|
||||||
|
ComPtr<ID3D11CommandList> m_dynamicList;
|
||||||
|
|
||||||
size_t m_fillBuf = 0;
|
size_t m_fillBuf = 0;
|
||||||
size_t m_completeBuf = 0;
|
size_t m_completeBuf = 0;
|
||||||
|
@ -594,6 +596,10 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
break;
|
break;
|
||||||
self->m_drawBuf = self->m_completeBuf;
|
self->m_drawBuf = self->m_completeBuf;
|
||||||
|
|
||||||
|
ID3D11CommandList* list = self->m_dynamicList.Get();
|
||||||
|
self->m_ctx->m_devCtx->ExecuteCommandList(list, false);
|
||||||
|
self->m_dynamicList.Reset();
|
||||||
|
|
||||||
if (self->m_texResizes.size())
|
if (self->m_texResizes.size())
|
||||||
{
|
{
|
||||||
for (const auto& resize : self->m_texResizes)
|
for (const auto& resize : self->m_texResizes)
|
||||||
|
@ -620,7 +626,8 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
if (self->m_windowCtx->m_needsResize)
|
if (self->m_windowCtx->m_needsResize)
|
||||||
{
|
{
|
||||||
self->m_windowCtx->m_swapChain->ResizeBuffers(2, self->m_windowCtx->width, self->m_windowCtx->height,
|
self->m_windowCtx->m_swapChain->ResizeBuffers(2,
|
||||||
|
self->m_windowCtx->width, self->m_windowCtx->height,
|
||||||
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
|
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
|
||||||
self->m_windowCtx->m_needsResize = false;
|
self->m_windowCtx->m_needsResize = false;
|
||||||
self->m_cmdLists[self->m_drawBuf].Reset();
|
self->m_cmdLists[self->m_drawBuf].Reset();
|
||||||
|
@ -663,6 +670,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
m_initcv.wait(m_initlk);
|
m_initcv.wait(m_initlk);
|
||||||
m_initlk.unlock();
|
m_initlk.unlock();
|
||||||
ThrowIfFailed(ctx->m_dev->CreateDeferredContext1(0, &m_deferredCtx));
|
ThrowIfFailed(ctx->m_dev->CreateDeferredContext1(0, &m_deferredCtx));
|
||||||
|
ThrowIfFailed(ctx->m_dev->CreateDeferredContext1(0, &m_dynamicCtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
~D3D11CommandQueue()
|
~D3D11CommandQueue()
|
||||||
|
@ -704,8 +712,6 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
int pendingDynamicSlot() {return m_fillBuf;}
|
int pendingDynamicSlot() {return m_fillBuf;}
|
||||||
|
|
||||||
void flushBufferUpdates() {}
|
|
||||||
|
|
||||||
std::unordered_map<D3D11TextureR*, std::pair<size_t, size_t>> m_texResizes;
|
std::unordered_map<D3D11TextureR*, std::pair<size_t, size_t>> m_texResizes;
|
||||||
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
|
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
|
||||||
{
|
{
|
||||||
|
@ -773,6 +779,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
m_workDoPresent[m_fillBuf] = m_doPresent;
|
m_workDoPresent[m_fillBuf] = m_doPresent;
|
||||||
m_doPresent = nullptr;
|
m_doPresent = nullptr;
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
|
ThrowIfFailed(m_dynamicCtx->FinishCommandList(false, &m_dynamicList));
|
||||||
m_completeBuf = m_fillBuf;
|
m_completeBuf = m_fillBuf;
|
||||||
for (size_t i=0 ; i<3 ; ++i)
|
for (size_t i=0 ; i<3 ; ++i)
|
||||||
{
|
{
|
||||||
|
@ -790,42 +797,42 @@ void D3D11GraphicsBufferD::load(const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get();
|
ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get();
|
||||||
D3D11_MAPPED_SUBRESOURCE d;
|
D3D11_MAPPED_SUBRESOURCE d;
|
||||||
m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
m_q->m_dynamicCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
||||||
memcpy(d.pData, data, sz);
|
memcpy(d.pData, data, sz);
|
||||||
m_q->m_deferredCtx->Unmap(res, 0);
|
m_q->m_dynamicCtx->Unmap(res, 0);
|
||||||
}
|
}
|
||||||
void* D3D11GraphicsBufferD::map(size_t sz)
|
void* D3D11GraphicsBufferD::map(size_t sz)
|
||||||
{
|
{
|
||||||
ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get();
|
ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get();
|
||||||
D3D11_MAPPED_SUBRESOURCE d;
|
D3D11_MAPPED_SUBRESOURCE d;
|
||||||
m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
m_q->m_dynamicCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
||||||
return d.pData;
|
return d.pData;
|
||||||
}
|
}
|
||||||
void D3D11GraphicsBufferD::unmap()
|
void D3D11GraphicsBufferD::unmap()
|
||||||
{
|
{
|
||||||
ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get();
|
ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get();
|
||||||
m_q->m_deferredCtx->Unmap(res, 0);
|
m_q->m_dynamicCtx->Unmap(res, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11TextureD::load(const void* data, size_t sz)
|
void D3D11TextureD::load(const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get();
|
ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get();
|
||||||
D3D11_MAPPED_SUBRESOURCE d;
|
D3D11_MAPPED_SUBRESOURCE d;
|
||||||
m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
m_q->m_dynamicCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
||||||
memcpy(d.pData, data, sz);
|
memcpy(d.pData, data, sz);
|
||||||
m_q->m_deferredCtx->Unmap(res, 0);
|
m_q->m_dynamicCtx->Unmap(res, 0);
|
||||||
}
|
}
|
||||||
void* D3D11TextureD::map(size_t sz)
|
void* D3D11TextureD::map(size_t sz)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get();
|
ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get();
|
||||||
D3D11_MAPPED_SUBRESOURCE d;
|
D3D11_MAPPED_SUBRESOURCE d;
|
||||||
m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
m_q->m_dynamicCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d);
|
||||||
return d.pData;
|
return d.pData;
|
||||||
}
|
}
|
||||||
void D3D11TextureD::unmap()
|
void D3D11TextureD::unmap()
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get();
|
ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get();
|
||||||
m_q->m_deferredCtx->Unmap(res, 0);
|
m_q->m_dynamicCtx->Unmap(res, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
class D3D11DataFactory : public ID3DDataFactory
|
class D3D11DataFactory : public ID3DDataFactory
|
||||||
|
|
|
@ -109,6 +109,7 @@ class D3D12GraphicsBufferD : public IGraphicsBufferD
|
||||||
D3D12_RESOURCE_STATES m_state;
|
D3D12_RESOURCE_STATES m_state;
|
||||||
size_t m_mappedSz;
|
size_t m_mappedSz;
|
||||||
void* m_mappedBuf = nullptr;
|
void* m_mappedBuf = nullptr;
|
||||||
|
unsigned m_loaded[2] = {};
|
||||||
D3D12GraphicsBufferD(D3D12CommandQueue* q, BufferUse use, D3D12Context* ctx, size_t stride, size_t count)
|
D3D12GraphicsBufferD(D3D12CommandQueue* q, BufferUse use, D3D12Context* ctx, size_t stride, size_t count)
|
||||||
: m_state(USE_TABLE[int(use)]), m_q(q), m_stride(stride), m_count(count)
|
: m_state(USE_TABLE[int(use)]), m_q(q), m_stride(stride), m_count(count)
|
||||||
{
|
{
|
||||||
|
@ -527,6 +528,7 @@ class D3D12ShaderPipeline : public IShaderPipeline
|
||||||
if (!backfaceCulling)
|
if (!backfaceCulling)
|
||||||
desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||||
desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
|
desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
|
||||||
|
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
|
||||||
if (!depthTest)
|
if (!depthTest)
|
||||||
desc.DepthStencilState.DepthEnable = false;
|
desc.DepthStencilState.DepthEnable = false;
|
||||||
if (!depthWrite)
|
if (!depthWrite)
|
||||||
|
@ -840,10 +842,6 @@ static ID3D12GraphicsCommandList* WaitForLoadList(D3D12Context* ctx)
|
||||||
{
|
{
|
||||||
ThrowIfFailed(ctx->m_loadfence->SetEventOnCompletion(ctx->m_loadfenceval, ctx->m_loadfencehandle));
|
ThrowIfFailed(ctx->m_loadfence->SetEventOnCompletion(ctx->m_loadfenceval, ctx->m_loadfencehandle));
|
||||||
WaitForSingleObject(ctx->m_loadfencehandle, INFINITE);
|
WaitForSingleObject(ctx->m_loadfencehandle, INFINITE);
|
||||||
|
|
||||||
/* Reset allocator and list */
|
|
||||||
ThrowIfFailed(ctx->m_loadqalloc->Reset());
|
|
||||||
ThrowIfFailed(ctx->m_loadlist->Reset(ctx->m_loadqalloc.Get(), nullptr));
|
|
||||||
}
|
}
|
||||||
return ctx->m_loadlist.Get();
|
return ctx->m_loadlist.Get();
|
||||||
}
|
}
|
||||||
|
@ -858,6 +856,14 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
ComPtr<ID3D12GraphicsCommandList> m_cmdList;
|
ComPtr<ID3D12GraphicsCommandList> m_cmdList;
|
||||||
ComPtr<ID3D12Fence> m_fence;
|
ComPtr<ID3D12Fence> m_fence;
|
||||||
|
|
||||||
|
ComPtr<ID3D12CommandAllocator> m_dynamicCmdAlloc[2];
|
||||||
|
ComPtr<ID3D12CommandQueue> m_dynamicCmdQueue;
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> m_dynamicCmdList;
|
||||||
|
UINT64 m_dynamicBufFenceVal = 0;
|
||||||
|
ComPtr<ID3D12Fence> m_dynamicBufFence;
|
||||||
|
HANDLE m_dynamicBufFenceHandle;
|
||||||
|
bool m_dynamicNeedsReset = false;
|
||||||
|
|
||||||
size_t m_fillBuf = 0;
|
size_t m_fillBuf = 0;
|
||||||
size_t m_drawBuf = 0;
|
size_t m_drawBuf = 0;
|
||||||
|
|
||||||
|
@ -868,6 +874,27 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
|
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetDynamicCommandList()
|
||||||
|
{
|
||||||
|
ThrowIfFailed(m_dynamicCmdAlloc[m_fillBuf]->Reset());
|
||||||
|
ThrowIfFailed(m_dynamicCmdList->Reset(m_dynamicCmdAlloc[m_fillBuf].Get(), nullptr));
|
||||||
|
m_dynamicNeedsReset = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stallDynamicUpload()
|
||||||
|
{
|
||||||
|
if (m_dynamicNeedsReset)
|
||||||
|
{
|
||||||
|
if (m_dynamicBufFence->GetCompletedValue() < m_dynamicBufFenceVal)
|
||||||
|
{
|
||||||
|
ThrowIfFailed(m_dynamicBufFence->SetEventOnCompletion(m_dynamicBufFenceVal,
|
||||||
|
m_dynamicBufFenceHandle));
|
||||||
|
WaitForSingleObject(m_dynamicBufFenceHandle, INFINITE);
|
||||||
|
}
|
||||||
|
resetDynamicCommandList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
D3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent,
|
D3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent,
|
||||||
ID3D12CommandQueue** cmdQueueOut)
|
ID3D12CommandQueue** cmdQueueOut)
|
||||||
: m_ctx(ctx), m_windowCtx(windowCtx), m_parent(parent)
|
: m_ctx(ctx), m_windowCtx(windowCtx), m_parent(parent)
|
||||||
|
@ -890,6 +917,15 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
ThrowIfFailed(ctx->m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, ctx->m_qalloc[0].Get(),
|
ThrowIfFailed(ctx->m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, ctx->m_qalloc[0].Get(),
|
||||||
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_cmdList));
|
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_cmdList));
|
||||||
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
|
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
|
||||||
|
|
||||||
|
ThrowIfFailed(ctx->m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_dynamicBufFence));
|
||||||
|
m_dynamicBufFenceHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
|
ThrowIfFailed(ctx->m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
__uuidof(ID3D12CommandAllocator), &m_dynamicCmdAlloc[0]));
|
||||||
|
ThrowIfFailed(ctx->m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
__uuidof(ID3D12CommandAllocator), &m_dynamicCmdAlloc[1]));
|
||||||
|
ThrowIfFailed(ctx->m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_dynamicCmdAlloc[0].Get(),
|
||||||
|
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_dynamicCmdList));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setShaderDataBinding(IShaderDataBinding* binding)
|
void setShaderDataBinding(IShaderDataBinding* binding)
|
||||||
|
@ -931,8 +967,6 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
int pendingDynamicSlot() {return m_fillBuf;}
|
int pendingDynamicSlot() {return m_fillBuf;}
|
||||||
|
|
||||||
void flushBufferUpdates() {}
|
|
||||||
|
|
||||||
std::unordered_map<D3D12TextureR*, std::pair<size_t, size_t>> m_texResizes;
|
std::unordered_map<D3D12TextureR*, std::pair<size_t, size_t>> m_texResizes;
|
||||||
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
|
void resizeRenderTexture(ITextureR* tex, size_t width, size_t height)
|
||||||
{
|
{
|
||||||
|
@ -1065,12 +1099,23 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
UINT64 m_submittedFenceVal = 0;
|
UINT64 m_submittedFenceVal = 0;
|
||||||
void execute()
|
void execute()
|
||||||
{
|
{
|
||||||
|
/* Perform dynamic uploads */
|
||||||
|
if (!m_dynamicNeedsReset)
|
||||||
|
{
|
||||||
|
m_dynamicCmdList->Close();
|
||||||
|
ID3D12CommandList* dcl[] = {m_dynamicCmdList.Get()};
|
||||||
|
m_ctx->m_q->ExecuteCommandLists(1, dcl);
|
||||||
|
++m_dynamicBufFenceVal;
|
||||||
|
ThrowIfFailed(m_ctx->m_q->Signal(m_dynamicBufFence.Get(), m_dynamicBufFenceVal));
|
||||||
|
}
|
||||||
|
|
||||||
/* Check on fence */
|
/* Check on fence */
|
||||||
if (m_fence->GetCompletedValue() < m_submittedFenceVal)
|
if (m_fence->GetCompletedValue() < m_submittedFenceVal)
|
||||||
{
|
{
|
||||||
/* Abandon this list (renderer too slow) */
|
/* Abandon this list (renderer too slow) */
|
||||||
m_cmdList->Close();
|
m_cmdList->Close();
|
||||||
resetCommandList();
|
resetCommandList();
|
||||||
|
m_dynamicNeedsReset = true;
|
||||||
m_doPresent = false;
|
m_doPresent = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1083,14 +1128,13 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
m_texResizes.clear();
|
m_texResizes.clear();
|
||||||
m_cmdList->Close();
|
m_cmdList->Close();
|
||||||
resetCommandList();
|
resetCommandList();
|
||||||
|
m_dynamicNeedsReset = true;
|
||||||
m_doPresent = false;
|
m_doPresent = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_drawBuf = m_fillBuf;
|
m_drawBuf = m_fillBuf;
|
||||||
++m_fillBuf;
|
m_fillBuf ^= 1;
|
||||||
if (m_fillBuf == 2)
|
|
||||||
m_fillBuf = 0;
|
|
||||||
|
|
||||||
m_cmdList->Close();
|
m_cmdList->Close();
|
||||||
ID3D12CommandList* cl[] = {m_cmdList.Get()};
|
ID3D12CommandList* cl[] = {m_cmdList.Get()};
|
||||||
|
@ -1107,19 +1151,21 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
ThrowIfFailed(m_ctx->m_q->Signal(m_fence.Get(), m_submittedFenceVal));
|
ThrowIfFailed(m_ctx->m_q->Signal(m_fence.Get(), m_submittedFenceVal));
|
||||||
|
|
||||||
resetCommandList();
|
resetCommandList();
|
||||||
|
resetDynamicCommandList();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void D3D12GraphicsBufferD::load(const void* data, size_t sz)
|
void D3D12GraphicsBufferD::load(const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
|
m_q->stallDynamicUpload();
|
||||||
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
||||||
ID3D12Resource* gpuRes = m_gpuBufs[m_q->m_fillBuf].Get();
|
ID3D12Resource* gpuRes = m_gpuBufs[m_q->m_fillBuf].Get();
|
||||||
D3D12_SUBRESOURCE_DATA d = {data, LONG_PTR(sz), LONG_PTR(sz)};
|
D3D12_SUBRESOURCE_DATA d = {data, LONG_PTR(sz), LONG_PTR(sz)};
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
m_state, D3D12_RESOURCE_STATE_COPY_DEST));
|
m_state, D3D12_RESOURCE_STATE_COPY_DEST));
|
||||||
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &d))
|
if (!UpdateSubresources<1>(m_q->m_dynamicCmdList.Get(), gpuRes, res, 0, 0, 1, &d))
|
||||||
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
|
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST, m_state));
|
D3D12_RESOURCE_STATE_COPY_DEST, m_state));
|
||||||
}
|
}
|
||||||
void* D3D12GraphicsBufferD::map(size_t sz)
|
void* D3D12GraphicsBufferD::map(size_t sz)
|
||||||
|
@ -1132,29 +1178,31 @@ void* D3D12GraphicsBufferD::map(size_t sz)
|
||||||
}
|
}
|
||||||
void D3D12GraphicsBufferD::unmap()
|
void D3D12GraphicsBufferD::unmap()
|
||||||
{
|
{
|
||||||
|
m_q->stallDynamicUpload();
|
||||||
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
||||||
ID3D12Resource* gpuRes = m_gpuBufs[m_q->m_fillBuf].Get();
|
ID3D12Resource* gpuRes = m_gpuBufs[m_q->m_fillBuf].Get();
|
||||||
D3D12_SUBRESOURCE_DATA data = {m_mappedBuf, LONG_PTR(m_mappedSz), LONG_PTR(m_mappedSz)};
|
D3D12_SUBRESOURCE_DATA data = {m_mappedBuf, LONG_PTR(m_mappedSz), LONG_PTR(m_mappedSz)};
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
m_state, D3D12_RESOURCE_STATE_COPY_DEST));
|
m_state, D3D12_RESOURCE_STATE_COPY_DEST));
|
||||||
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &data))
|
if (!UpdateSubresources<1>(m_q->m_dynamicCmdList.Get(), gpuRes, res, 0, 0, 1, &data))
|
||||||
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
|
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
|
||||||
free(m_mappedBuf);
|
free(m_mappedBuf);
|
||||||
m_mappedBuf = nullptr;
|
m_mappedBuf = nullptr;
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST, m_state));
|
D3D12_RESOURCE_STATE_COPY_DEST, m_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12TextureD::load(const void* data, size_t sz)
|
void D3D12TextureD::load(const void* data, size_t sz)
|
||||||
{
|
{
|
||||||
|
m_q->stallDynamicUpload();
|
||||||
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
|
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
|
||||||
ID3D12Resource* gpuRes = m_gpuTexs[m_q->m_fillBuf].Get();
|
ID3D12Resource* gpuRes = m_gpuTexs[m_q->m_fillBuf].Get();
|
||||||
D3D12_SUBRESOURCE_DATA d = {data, LONG_PTR(m_width * 4), LONG_PTR(sz)};
|
D3D12_SUBRESOURCE_DATA d = {data, LONG_PTR(m_width * 4), LONG_PTR(sz)};
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
|
||||||
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &d))
|
if (!UpdateSubresources<1>(m_q->m_dynamicCmdList.Get(), gpuRes, res, 0, 0, 1, &d))
|
||||||
Log.report(LogVisor::FatalError, "unable to update dynamic texture data");
|
Log.report(LogVisor::FatalError, "unable to update dynamic texture data");
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||||
}
|
}
|
||||||
void* D3D12TextureD::map(size_t sz)
|
void* D3D12TextureD::map(size_t sz)
|
||||||
|
@ -1167,16 +1215,17 @@ void* D3D12TextureD::map(size_t sz)
|
||||||
}
|
}
|
||||||
void D3D12TextureD::unmap()
|
void D3D12TextureD::unmap()
|
||||||
{
|
{
|
||||||
|
m_q->stallDynamicUpload();
|
||||||
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
|
ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get();
|
||||||
ID3D12Resource* gpuRes = m_gpuTexs[m_q->m_fillBuf].Get();
|
ID3D12Resource* gpuRes = m_gpuTexs[m_q->m_fillBuf].Get();
|
||||||
D3D12_SUBRESOURCE_DATA data = {m_mappedBuf, LONG_PTR(m_width * 4), LONG_PTR(m_mappedSz)};
|
D3D12_SUBRESOURCE_DATA data = {m_mappedBuf, LONG_PTR(m_width * 4), LONG_PTR(m_mappedSz)};
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
|
||||||
if (!UpdateSubresources<1>(m_q->m_cmdList.Get(), gpuRes, res, 0, 0, 1, &data))
|
if (!UpdateSubresources<1>(m_q->m_dynamicCmdList.Get(), gpuRes, res, 0, 0, 1, &data))
|
||||||
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
|
Log.report(LogVisor::FatalError, "unable to update dynamic buffer data");
|
||||||
free(m_mappedBuf);
|
free(m_mappedBuf);
|
||||||
m_mappedBuf = nullptr;
|
m_mappedBuf = nullptr;
|
||||||
m_q->m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
m_q->m_dynamicCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(gpuRes,
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,6 +1479,10 @@ public:
|
||||||
/* Block handle return until data is ready on GPU */
|
/* Block handle return until data is ready on GPU */
|
||||||
WaitForLoadList(m_ctx);
|
WaitForLoadList(m_ctx);
|
||||||
|
|
||||||
|
/* Reset allocator and list */
|
||||||
|
ThrowIfFailed(m_ctx->m_loadqalloc->Reset());
|
||||||
|
ThrowIfFailed(m_ctx->m_loadlist->Reset(m_ctx->m_loadqalloc.Get(), nullptr));
|
||||||
|
|
||||||
/* Delete static upload heaps */
|
/* Delete static upload heaps */
|
||||||
for (std::unique_ptr<D3D12GraphicsBufferS>& buf : retval->m_SBufs)
|
for (std::unique_ptr<D3D12GraphicsBufferS>& buf : retval->m_SBufs)
|
||||||
buf->m_buf.Reset();
|
buf->m_buf.Reset();
|
||||||
|
|
|
@ -924,11 +924,6 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
m_pendingResizes.push_back({texgl, width, height});
|
m_pendingResizes.push_back({texgl, width, height});
|
||||||
}
|
}
|
||||||
|
|
||||||
void flushBufferUpdates()
|
|
||||||
{
|
|
||||||
glFlush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setClearColor(const float rgba[4])
|
void setClearColor(const float rgba[4])
|
||||||
{
|
{
|
||||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||||
|
@ -1027,6 +1022,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void execute()
|
void execute()
|
||||||
{
|
{
|
||||||
|
glFlush();
|
||||||
std::unique_lock<std::mutex> lk(m_mt);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
m_completeBuf = m_fillBuf;
|
m_completeBuf = m_fillBuf;
|
||||||
for (size_t i=0 ; i<3 ; ++i)
|
for (size_t i=0 ; i<3 ; ++i)
|
||||||
|
|
|
@ -57,6 +57,7 @@ static bool FindBestD3DCompile()
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::ApplicationWin32");
|
static LogVisor::LogModule Log("boo::ApplicationWin32");
|
||||||
|
Win32Cursors WIN32_CURSORS;
|
||||||
|
|
||||||
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx);
|
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx);
|
||||||
|
|
||||||
|
@ -92,6 +93,11 @@ public:
|
||||||
m_args(args),
|
m_args(args),
|
||||||
m_singleInstance(singleInstance)
|
m_singleInstance(singleInstance)
|
||||||
{
|
{
|
||||||
|
WIN32_CURSORS.m_arrow = LoadCursor(nullptr, IDC_ARROW);
|
||||||
|
WIN32_CURSORS.m_hResize = LoadCursor(nullptr, IDC_SIZEWE);
|
||||||
|
WIN32_CURSORS.m_vResize = LoadCursor(nullptr, IDC_SIZENS);
|
||||||
|
WIN32_CURSORS.m_wait = LoadCursor(nullptr, IDC_WAIT);
|
||||||
|
|
||||||
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
|
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
|
||||||
if (!dxgilib)
|
if (!dxgilib)
|
||||||
Log.report(LogVisor::FatalError, "unable to load dxgi.dll");
|
Log.report(LogVisor::FatalError, "unable to load dxgi.dll");
|
||||||
|
@ -299,6 +305,10 @@ public:
|
||||||
/* Quit message from client thread */
|
/* Quit message from client thread */
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
continue;
|
continue;
|
||||||
|
case WM_USER+2:
|
||||||
|
/* SetCursor call from client thread */
|
||||||
|
SetCursor(HCURSOR(msg.wParam));
|
||||||
|
continue;
|
||||||
default:
|
default:
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
|
|
|
@ -255,4 +255,16 @@ struct HWNDEvent
|
||||||
: uMsg(m), wParam(w), lParam(l) {}
|
: uMsg(m), wParam(w), lParam(l) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Win32Cursors
|
||||||
|
{
|
||||||
|
HCURSOR m_arrow;
|
||||||
|
HCURSOR m_hResize;
|
||||||
|
HCURSOR m_vResize;
|
||||||
|
HCURSOR m_wait;
|
||||||
|
};
|
||||||
|
namespace boo
|
||||||
|
{
|
||||||
|
extern Win32Cursors WIN32_CURSORS;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BOO_WIN32COMMON_HPP
|
#endif // BOO_WIN32COMMON_HPP
|
||||||
|
|
|
@ -442,6 +442,22 @@ class WindowWin32 : public IWindow
|
||||||
HWND m_hwnd;
|
HWND m_hwnd;
|
||||||
std::unique_ptr<GraphicsContextWin32> m_gfxCtx;
|
std::unique_ptr<GraphicsContextWin32> m_gfxCtx;
|
||||||
IWindowCallback* m_callback = nullptr;
|
IWindowCallback* m_callback = nullptr;
|
||||||
|
EMouseCursor m_cursor = EMouseCursor::None;
|
||||||
|
bool m_cursorWait = false;
|
||||||
|
static HCURSOR GetWin32Cursor(EMouseCursor cur)
|
||||||
|
{
|
||||||
|
switch (cur)
|
||||||
|
{
|
||||||
|
case EMouseCursor::Pointer:
|
||||||
|
return WIN32_CURSORS.m_arrow;
|
||||||
|
case EMouseCursor::HorizontalArrow:
|
||||||
|
return WIN32_CURSORS.m_hResize;
|
||||||
|
case EMouseCursor::VerticalArrow:
|
||||||
|
return WIN32_CURSORS.m_vResize;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return WIN32_CURSORS.m_arrow;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -495,6 +511,33 @@ public:
|
||||||
SetWindowTextW(m_hwnd, title.c_str());
|
SetWindowTextW(m_hwnd, title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _setCursor(HCURSOR cur)
|
||||||
|
{
|
||||||
|
PostThreadMessageW(g_mainThreadId, WM_USER+2, WPARAM(cur), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCursor(EMouseCursor cursor)
|
||||||
|
{
|
||||||
|
if (cursor == m_cursor && !m_cursorWait)
|
||||||
|
return;
|
||||||
|
m_cursor = cursor;
|
||||||
|
_setCursor(GetWin32Cursor(cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWaitCursor(bool wait)
|
||||||
|
{
|
||||||
|
if (wait && !m_cursorWait)
|
||||||
|
{
|
||||||
|
_setCursor(WIN32_CURSORS.m_wait);
|
||||||
|
m_cursorWait = true;
|
||||||
|
}
|
||||||
|
else if (!wait && m_cursorWait)
|
||||||
|
{
|
||||||
|
setCursor(m_cursor);
|
||||||
|
m_cursorWait = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setWindowFrameDefault()
|
void setWindowFrameDefault()
|
||||||
{
|
{
|
||||||
MONITORINFO monInfo;
|
MONITORINFO monInfo;
|
||||||
|
@ -576,9 +619,9 @@ public:
|
||||||
EModifierKey modifierMask = translateModifiers(e.uMsg);
|
EModifierKey modifierMask = translateModifiers(e.uMsg);
|
||||||
SWindowCoord coord =
|
SWindowCoord coord =
|
||||||
{
|
{
|
||||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam))},
|
||||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam))},
|
||||||
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
|
{float(GET_X_LPARAM(e.lParam)) / float(w), float(h-GET_Y_LPARAM(e.lParam)) / float(h)}
|
||||||
};
|
};
|
||||||
m_callback->mouseDown(coord, button, modifierMask);
|
m_callback->mouseDown(coord, button, modifierMask);
|
||||||
}
|
}
|
||||||
|
@ -593,9 +636,9 @@ public:
|
||||||
EModifierKey modifierMask = translateModifiers(e.uMsg);
|
EModifierKey modifierMask = translateModifiers(e.uMsg);
|
||||||
SWindowCoord coord =
|
SWindowCoord coord =
|
||||||
{
|
{
|
||||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam))},
|
||||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam))},
|
||||||
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
|
{float(GET_X_LPARAM(e.lParam)) / float(w), float(h-GET_Y_LPARAM(e.lParam)) / float(h)}
|
||||||
};
|
};
|
||||||
m_callback->mouseUp(coord, button, modifierMask);
|
m_callback->mouseUp(coord, button, modifierMask);
|
||||||
}
|
}
|
||||||
|
@ -732,9 +775,9 @@ public:
|
||||||
getWindowFrame(x, y, w, h);
|
getWindowFrame(x, y, w, h);
|
||||||
SWindowCoord coord =
|
SWindowCoord coord =
|
||||||
{
|
{
|
||||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam))},
|
||||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam))},
|
||||||
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
|
{float(GET_X_LPARAM(e.lParam)) / float(w), float(h-GET_Y_LPARAM(e.lParam)) / float(h)}
|
||||||
};
|
};
|
||||||
if (!mouseTracking)
|
if (!mouseTracking)
|
||||||
{
|
{
|
||||||
|
@ -757,9 +800,9 @@ public:
|
||||||
getWindowFrame(x, y, w, h);
|
getWindowFrame(x, y, w, h);
|
||||||
SWindowCoord coord =
|
SWindowCoord coord =
|
||||||
{
|
{
|
||||||
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
|
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam)) },
|
||||||
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
|
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam)) },
|
||||||
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h) }
|
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(h-GET_Y_LPARAM(e.lParam)) / float(h) }
|
||||||
};
|
};
|
||||||
m_callback->mouseLeave(coord);
|
m_callback->mouseLeave(coord);
|
||||||
mouseTracking = false;
|
mouseTracking = false;
|
||||||
|
@ -775,9 +818,9 @@ public:
|
||||||
getWindowFrame(x, y, w, h);
|
getWindowFrame(x, y, w, h);
|
||||||
SWindowCoord coord =
|
SWindowCoord coord =
|
||||||
{
|
{
|
||||||
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
|
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam)) },
|
||||||
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
|
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)(h-GET_Y_LPARAM(e.lParam)) },
|
||||||
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h) }
|
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(h-GET_Y_LPARAM(e.lParam)) / float(h) }
|
||||||
};
|
};
|
||||||
m_callback->mouseEnter(coord);
|
m_callback->mouseEnter(coord);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue