mirror of https://github.com/AxioDL/boo.git
Added Windows OpenGL support. D3D11 stability fixes
This commit is contained in:
parent
0923254b39
commit
8951008cca
|
@ -35,7 +35,7 @@ if(WIN32)
|
||||||
|
|
||||||
list(APPEND _BOO_SYS_DEFINES -DUNICODE -D_UNICODE)
|
list(APPEND _BOO_SYS_DEFINES -DUNICODE -D_UNICODE)
|
||||||
|
|
||||||
list(APPEND _BOO_SYS_LIBS Winusb opengl32 Setupapi D3DCompiler)
|
list(APPEND _BOO_SYS_LIBS Winusb opengl32 Setupapi)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
list(APPEND PLAT_SRCS
|
list(APPEND PLAT_SRCS
|
||||||
lib/mac/ApplicationCocoa.mm
|
lib/mac/ApplicationCocoa.mm
|
||||||
|
|
|
@ -25,9 +25,10 @@ public:
|
||||||
API_OPENGLES_3 = 3,
|
API_OPENGLES_3 = 3,
|
||||||
API_VULKAN = 4,
|
API_VULKAN = 4,
|
||||||
API_D3D11 = 5,
|
API_D3D11 = 5,
|
||||||
API_METAL = 6,
|
API_D3D12 = 6,
|
||||||
API_GX = 7,
|
API_METAL = 7,
|
||||||
API_GX2 = 8
|
API_GX = 8,
|
||||||
|
API_GX2 = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EPixelFormat
|
enum EPixelFormat
|
||||||
|
|
|
@ -24,10 +24,13 @@ public:
|
||||||
const char* platformName() const {return "OpenGL";}
|
const char* platformName() const {return "OpenGL";}
|
||||||
|
|
||||||
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count);
|
||||||
|
IGraphicsBufferS* newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count);
|
||||||
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||||
|
|
||||||
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
const void* data, size_t sz);
|
const void* data, size_t sz);
|
||||||
|
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
|
std::unique_ptr<uint8_t[]>&& data, size_t sz);
|
||||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
||||||
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
|
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
|
||||||
|
|
||||||
|
|
|
@ -171,12 +171,17 @@ struct IGraphicsDataFactory
|
||||||
|
|
||||||
virtual IGraphicsBufferS*
|
virtual IGraphicsBufferS*
|
||||||
newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)=0;
|
newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count)=0;
|
||||||
|
virtual IGraphicsBufferS*
|
||||||
|
newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count)=0;
|
||||||
virtual IGraphicsBufferD*
|
virtual IGraphicsBufferD*
|
||||||
newDynamicBuffer(BufferUse use, size_t stride, size_t count)=0;
|
newDynamicBuffer(BufferUse use, size_t stride, size_t count)=0;
|
||||||
|
|
||||||
virtual ITextureS*
|
virtual ITextureS*
|
||||||
newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
const void* data, size_t sz)=0;
|
const void* data, size_t sz)=0;
|
||||||
|
virtual ITextureS*
|
||||||
|
newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
|
std::unique_ptr<uint8_t[]>&& data, size_t sz)=0;
|
||||||
virtual ITextureD*
|
virtual ITextureD*
|
||||||
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
|
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
|
||||||
virtual ITextureR*
|
virtual ITextureR*
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
#include <comdef.h>
|
#include <comdef.h>
|
||||||
|
|
||||||
|
extern pD3DCompile D3DCompilePROC;
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("boo::D3D11");
|
static LogVisor::LogModule Log("boo::D3D11");
|
||||||
|
@ -456,7 +458,7 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
std::thread m_thr;
|
std::thread m_thr;
|
||||||
|
|
||||||
ComPtr<ID3D11CommandList> m_cmdLists[3];
|
ComPtr<ID3D11CommandList> m_cmdLists[3];
|
||||||
bool m_needPresent[3];
|
D3D11TextureR* m_workDoPresent[3];
|
||||||
|
|
||||||
static void RenderingWorker(D3D11CommandQueue* self)
|
static void RenderingWorker(D3D11CommandQueue* self)
|
||||||
{
|
{
|
||||||
|
@ -472,12 +474,65 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
if (!self->m_running)
|
if (!self->m_running)
|
||||||
break;
|
break;
|
||||||
self->m_drawBuf = self->m_completeBuf;
|
self->m_drawBuf = self->m_completeBuf;
|
||||||
|
|
||||||
|
if (self->m_texResizes.size())
|
||||||
|
{
|
||||||
|
for (const auto& resize : self->m_texResizes)
|
||||||
|
resize.first->resize(self->m_ctx, resize.second.first, resize.second.second);
|
||||||
|
self->m_texResizes.clear();
|
||||||
|
self->m_cmdLists[self->m_drawBuf].Reset();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->m_windowCtx->m_needsFSTransition)
|
||||||
|
{
|
||||||
|
if (self->m_windowCtx->m_fs)
|
||||||
|
{
|
||||||
|
self->m_windowCtx->m_swapChain->SetFullscreenState(true, nullptr);
|
||||||
|
self->m_windowCtx->m_swapChain->ResizeTarget(&self->m_windowCtx->m_fsdesc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
self->m_windowCtx->m_swapChain->SetFullscreenState(false, nullptr);
|
||||||
|
|
||||||
|
self->m_windowCtx->m_needsFSTransition = false;
|
||||||
|
self->m_cmdLists[self->m_drawBuf].Reset();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->m_windowCtx->m_needsResize)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
self->m_windowCtx->m_needsResize = false;
|
||||||
|
self->m_cmdLists[self->m_drawBuf].Reset();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11CommandList* list = self->m_cmdLists[self->m_drawBuf].Get();
|
ID3D11CommandList* list = self->m_cmdLists[self->m_drawBuf].Get();
|
||||||
self->m_ctx->m_devCtx->ExecuteCommandList(list, false);
|
self->m_ctx->m_devCtx->ExecuteCommandList(list, false);
|
||||||
self->m_cmdLists[self->m_drawBuf].Reset();
|
self->m_cmdLists[self->m_drawBuf].Reset();
|
||||||
if (self->m_needPresent[self->m_drawBuf])
|
|
||||||
|
D3D11TextureR* csource = self->m_workDoPresent[self->m_drawBuf];
|
||||||
|
|
||||||
|
if (csource)
|
||||||
|
{
|
||||||
|
ComPtr<ID3D11Texture2D> dest;
|
||||||
|
ThrowIfFailed(self->m_windowCtx->m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &dest));
|
||||||
|
|
||||||
|
if (csource->m_samples > 1)
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* src = csource->m_msaaTex.Get();
|
||||||
|
self->m_ctx->m_devCtx->ResolveSubresource(dest.Get(), 0, src, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* src = csource->m_tex.Get();
|
||||||
|
self->m_ctx->m_devCtx->CopyResource(dest.Get(), src);
|
||||||
|
}
|
||||||
|
|
||||||
self->m_windowCtx->m_swapChain->Present(1, 0);
|
self->m_windowCtx->m_swapChain->Present(1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,10 +577,12 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
m_deferredCtx->RSSetViewports(1, &vp);
|
m_deferredCtx->RSSetViewports(1, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
D3D11TextureR* ctex = static_cast<D3D11TextureR*>(tex);
|
D3D11TextureR* ctex = static_cast<D3D11TextureR*>(tex);
|
||||||
ctex->resize(m_ctx, width, height);
|
std::unique_lock<std::mutex> lk(m_mt);
|
||||||
|
m_texResizes[ctex] = std::make_pair(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
||||||
|
@ -557,12 +614,12 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
|
|
||||||
void draw(size_t start, size_t count)
|
void draw(size_t start, size_t count)
|
||||||
{
|
{
|
||||||
m_deferredCtx->DrawInstanced(count, 1, start, 0);
|
m_deferredCtx->Draw(count, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawIndexed(size_t start, size_t count)
|
void drawIndexed(size_t start, size_t count)
|
||||||
{
|
{
|
||||||
m_deferredCtx->DrawIndexedInstanced(count, 1, start, 0, 0);
|
m_deferredCtx->DrawIndexed(count, start, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawInstances(size_t start, size_t count, size_t instCount)
|
void drawInstances(size_t start, size_t count, size_t instCount)
|
||||||
|
@ -575,39 +632,17 @@ struct D3D11CommandQueue : IGraphicsCommandQueue
|
||||||
m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, 0);
|
m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool m_doPresent = false;
|
D3D11TextureR* m_doPresent = nullptr;
|
||||||
void resolveDisplay(ITextureR* source)
|
void resolveDisplay(ITextureR* source)
|
||||||
{
|
{
|
||||||
D3D11TextureR* csource = static_cast<D3D11TextureR*>(source);
|
m_doPresent = static_cast<D3D11TextureR*>(source);
|
||||||
|
|
||||||
if (m_windowCtx->m_needsResize)
|
|
||||||
{
|
|
||||||
m_windowCtx->m_swapChain->ResizeBuffers(2, m_windowCtx->width, m_windowCtx->height, DXGI_FORMAT_R8G8B8A8_UNORM,
|
|
||||||
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
|
|
||||||
m_windowCtx->m_needsResize = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComPtr<ID3D11Texture2D> dest;
|
|
||||||
ThrowIfFailed(m_windowCtx->m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &dest));
|
|
||||||
|
|
||||||
if (csource->m_samples > 1)
|
|
||||||
{
|
|
||||||
ID3D11Texture2D* src = csource->m_msaaTex.Get();
|
|
||||||
m_deferredCtx->ResolveSubresource(dest.Get(), 0, src, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ID3D11Texture2D* src = csource->m_tex.Get();
|
|
||||||
m_deferredCtx->CopyResource(dest.Get(), src);
|
|
||||||
}
|
|
||||||
m_doPresent = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute()
|
void execute()
|
||||||
{
|
{
|
||||||
ThrowIfFailed(m_deferredCtx->FinishCommandList(false, &m_cmdLists[m_fillBuf]));
|
ThrowIfFailed(m_deferredCtx->FinishCommandList(false, &m_cmdLists[m_fillBuf]));
|
||||||
m_needPresent[m_fillBuf] = m_doPresent;
|
m_workDoPresent[m_fillBuf] = m_doPresent;
|
||||||
m_doPresent = false;
|
m_doPresent = nullptr;
|
||||||
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)
|
||||||
|
@ -686,6 +721,14 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IGraphicsBufferS* newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count)
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
|
D3D11GraphicsBufferS* retval = new D3D11GraphicsBufferS(use, m_ctx, d.get(), stride, count);
|
||||||
|
static_cast<D3D11Data*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
|
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
|
||||||
|
@ -702,6 +745,15 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
|
std::unique_ptr<uint8_t[]>&& data, size_t sz)
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
|
D3D11TextureS* retval = new D3D11TextureS(m_ctx, width, height, mips, fmt, d.get(), sz);
|
||||||
|
static_cast<D3D11Data*>(m_deferredData)->m_STexs.emplace_back(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
||||||
{
|
{
|
||||||
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
|
D3D11CommandQueue* q = static_cast<D3D11CommandQueue*>(m_parent->getCommandQueue());
|
||||||
|
@ -740,14 +792,14 @@ public:
|
||||||
{
|
{
|
||||||
ComPtr<ID3DBlob> errBlob;
|
ComPtr<ID3DBlob> errBlob;
|
||||||
|
|
||||||
if (FAILED(D3DCompile(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
|
if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
|
||||||
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
|
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer());
|
Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(D3DCompile(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
|
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
|
||||||
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
|
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
|
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#define MAX_TEXTURE_COUNT 8
|
#define MAX_TEXTURE_COUNT 8
|
||||||
|
|
||||||
extern PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC;
|
extern PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC;
|
||||||
|
extern pD3DCompile D3DCompilePROC;
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -706,10 +707,11 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
m_cmdList->RSSetScissorRects(1, &r);
|
m_cmdList->RSSetScissorRects(1, &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
D3D12TextureR* ctex = static_cast<D3D12TextureR*>(tex);
|
D3D12TextureR* ctex = static_cast<D3D12TextureR*>(tex);
|
||||||
ctex->resize(m_ctx, width, height);
|
m_texResizes[ctex] = std::make_pair(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
||||||
|
@ -846,6 +848,18 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
||||||
m_doPresent = false;
|
m_doPresent = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform texture resizes */
|
||||||
|
if (m_texResizes.size())
|
||||||
|
{
|
||||||
|
for (const auto& resize : m_texResizes)
|
||||||
|
resize.first->resize(m_ctx, resize.second.first, resize.second.second);
|
||||||
|
m_texResizes.clear();
|
||||||
|
m_cmdList->Close();
|
||||||
|
resetCommandList();
|
||||||
|
m_doPresent = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_drawBuf = m_fillBuf;
|
m_drawBuf = m_fillBuf;
|
||||||
++m_fillBuf;
|
++m_fillBuf;
|
||||||
|
@ -952,6 +966,14 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IGraphicsBufferS* newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count)
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
|
D3D12GraphicsBufferS* retval = new D3D12GraphicsBufferS(use, m_ctx, d.get(), stride, count);
|
||||||
|
static_cast<D3D12Data*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||||
{
|
{
|
||||||
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
|
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
|
||||||
|
@ -968,6 +990,15 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
|
std::unique_ptr<uint8_t[]>&& data, size_t sz)
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
|
D3D12TextureS* retval = new D3D12TextureS(m_ctx, width, height, mips, fmt, d.get(), sz);
|
||||||
|
static_cast<D3D12Data*>(m_deferredData)->m_STexs.emplace_back(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
|
||||||
{
|
{
|
||||||
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
|
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
|
||||||
|
@ -1006,14 +1037,14 @@ public:
|
||||||
{
|
{
|
||||||
ComPtr<ID3DBlob> errBlob;
|
ComPtr<ID3DBlob> errBlob;
|
||||||
|
|
||||||
if (FAILED(D3DCompile(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
|
if (FAILED(D3DCompilePROC(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main",
|
||||||
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
|
"vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob)))
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer());
|
Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(D3DCompile(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
|
if (FAILED(D3DCompilePROC(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main",
|
||||||
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
|
"ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob)))
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
|
Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer());
|
||||||
|
|
|
@ -90,6 +90,15 @@ GLDataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, s
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IGraphicsBufferS*
|
||||||
|
GLDataFactory::newStaticBuffer(BufferUse use, std::unique_ptr<uint8_t[]>&& data, size_t stride, size_t count)
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
|
GLGraphicsBufferS* retval = new GLGraphicsBufferS(use, d.get(), stride * count);
|
||||||
|
static_cast<GLData*>(m_deferredData)->m_SBufs.emplace_back(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
class GLTextureS : public ITextureS
|
class GLTextureS : public ITextureS
|
||||||
{
|
{
|
||||||
friend class GLDataFactory;
|
friend class GLDataFactory;
|
||||||
|
@ -187,6 +196,16 @@ GLDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, Textur
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITextureS*
|
||||||
|
GLDataFactory::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||||
|
std::unique_ptr<uint8_t[]>&& data, size_t sz)
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> d = std::move(data);
|
||||||
|
GLTextureS* retval = new GLTextureS(width, height, mips, fmt, d.get(), sz);
|
||||||
|
static_cast<GLData*>(m_deferredData)->m_STexs.emplace_back(retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
class GLShaderPipeline : public IShaderPipeline
|
class GLShaderPipeline : public IShaderPipeline
|
||||||
{
|
{
|
||||||
friend class GLDataFactory;
|
friend class GLDataFactory;
|
||||||
|
@ -205,7 +224,6 @@ class GLShaderPipeline : public IShaderPipeline
|
||||||
m_prog = glCreateProgram();
|
m_prog = glCreateProgram();
|
||||||
if (!m_vert || !m_frag || !m_prog)
|
if (!m_vert || !m_frag || !m_prog)
|
||||||
{
|
{
|
||||||
|
|
||||||
glDeleteShader(m_vert);
|
glDeleteShader(m_vert);
|
||||||
m_vert = 0;
|
m_vert = 0;
|
||||||
glDeleteShader(m_frag);
|
glDeleteShader(m_frag);
|
||||||
|
@ -1002,7 +1020,7 @@ IVertexFormat* GLDataFactory::newVertexFormat
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphicsCommandQueue* _NewGLES3CommandQueue(IGraphicsContext* parent)
|
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent)
|
||||||
{
|
{
|
||||||
return new struct GLCommandQueue(parent);
|
return new struct GLCommandQueue(parent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,46 @@
|
||||||
#include "boo/inputdev/DeviceFinder.hpp"
|
#include "boo/inputdev/DeviceFinder.hpp"
|
||||||
#include <LogVisor/LogVisor.hpp>
|
#include <LogVisor/LogVisor.hpp>
|
||||||
|
|
||||||
|
DWORD g_mainThreadId = 0;
|
||||||
|
|
||||||
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
|
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
pD3DCompile D3DCompilePROC = nullptr;
|
||||||
|
|
||||||
|
static bool FindBestD3DCompile()
|
||||||
|
{
|
||||||
|
HMODULE d3dCompilelib = LoadLibraryW(L"D3DCompiler_47.dll");
|
||||||
|
if (!d3dCompilelib)
|
||||||
|
{
|
||||||
|
d3dCompilelib = LoadLibraryW(L"D3DCompiler_46.dll");
|
||||||
|
if (!d3dCompilelib)
|
||||||
|
{
|
||||||
|
d3dCompilelib = LoadLibraryW(L"D3DCompiler_45.dll");
|
||||||
|
if (!d3dCompilelib)
|
||||||
|
{
|
||||||
|
d3dCompilelib = LoadLibraryW(L"D3DCompiler_44.dll");
|
||||||
|
if (!d3dCompilelib)
|
||||||
|
{
|
||||||
|
d3dCompilelib = LoadLibraryW(L"D3DCompiler_43.dll");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d3dCompilelib)
|
||||||
|
{
|
||||||
|
D3DCompilePROC = (pD3DCompile)GetProcAddress(d3dCompilelib, "D3DCompile");
|
||||||
|
return D3DCompilePROC != nullptr;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("ApplicationWin32");
|
static LogVisor::LogModule Log("ApplicationWin32");
|
||||||
|
|
||||||
IWindow* _WindowWin32New(const SystemString& title, D3DAppContext& d3dCtx);
|
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx);
|
||||||
|
|
||||||
class ApplicationWin32 final : public IApplication
|
class ApplicationWin32 final : public IApplication
|
||||||
{
|
{
|
||||||
|
@ -39,7 +69,7 @@ class ApplicationWin32 final : public IApplication
|
||||||
std::unordered_map<HWND, IWindow*> m_allWindows;
|
std::unordered_map<HWND, IWindow*> m_allWindows;
|
||||||
bool m_singleInstance;
|
bool m_singleInstance;
|
||||||
|
|
||||||
D3DAppContext m_d3dCtx;
|
Boo3DAppContext m_3dCtx;
|
||||||
|
|
||||||
void _deletedWindow(IWindow* window)
|
void _deletedWindow(IWindow* window)
|
||||||
{
|
{
|
||||||
|
@ -71,9 +101,19 @@ public:
|
||||||
Log.report(LogVisor::FatalError, "unable to find CreateDXGIFactory2 in DXGI.dll\n"
|
Log.report(LogVisor::FatalError, "unable to find CreateDXGIFactory2 in DXGI.dll\n"
|
||||||
"Windows 7 users should install \"Platform Update for Windows 7\" from Microsoft");
|
"Windows 7 users should install \"Platform Update for Windows 7\" from Microsoft");
|
||||||
|
|
||||||
|
bool no12 = false;
|
||||||
|
bool noD3d = false;
|
||||||
|
for (const SystemString& arg : args)
|
||||||
|
{
|
||||||
|
if (!arg.compare(L"--d3d11"))
|
||||||
|
no12 = true;
|
||||||
|
if (!arg.compare(L"--gl"))
|
||||||
|
noD3d = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
|
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
|
||||||
if (d3d12lib)
|
if (!no12 && !noD3d && d3d12lib)
|
||||||
{
|
{
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
{
|
{
|
||||||
|
@ -86,6 +126,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (!FindBestD3DCompile())
|
||||||
|
Log.report(LogVisor::FatalError, "unable to find D3DCompile_[43-47].dll");
|
||||||
|
|
||||||
D3D12SerializeRootSignaturePROC =
|
D3D12SerializeRootSignaturePROC =
|
||||||
(PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(d3d12lib, "D3D12SerializeRootSignature");
|
(PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(d3d12lib, "D3D12SerializeRootSignature");
|
||||||
|
@ -96,18 +138,18 @@ public:
|
||||||
Log.report(LogVisor::FatalError, "unable to find D3D12CreateDevice in D3D12.dll");
|
Log.report(LogVisor::FatalError, "unable to find D3D12CreateDevice in D3D12.dll");
|
||||||
|
|
||||||
/* Create device */
|
/* Create device */
|
||||||
HRESULT hr = MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &m_d3dCtx.m_ctx12.m_dev);
|
HRESULT hr = MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &m_3dCtx.m_ctx12.m_dev);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
Log.report(LogVisor::FatalError, "unable to create D3D12 device");
|
Log.report(LogVisor::FatalError, "unable to create D3D12 device");
|
||||||
|
|
||||||
/* Obtain DXGI Factory */
|
/* Obtain DXGI Factory */
|
||||||
hr = MyCreateDXGIFactory2(DXGI_CREATE_FLAGS, __uuidof(IDXGIFactory4), &m_d3dCtx.m_ctx12.m_dxFactory);
|
hr = MyCreateDXGIFactory2(DXGI_CREATE_FLAGS, __uuidof(IDXGIFactory4), &m_3dCtx.m_ctx12.m_dxFactory);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
Log.report(LogVisor::FatalError, "unable to create DXGI factory");
|
Log.report(LogVisor::FatalError, "unable to create DXGI factory");
|
||||||
|
|
||||||
/* Establish loader objects */
|
/* Establish loader objects */
|
||||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
__uuidof(ID3D12CommandAllocator), &m_d3dCtx.m_ctx12.m_loadqalloc)))
|
__uuidof(ID3D12CommandAllocator), &m_3dCtx.m_ctx12.m_loadqalloc)))
|
||||||
Log.report(LogVisor::FatalError, "unable to create loader allocator");
|
Log.report(LogVisor::FatalError, "unable to create loader allocator");
|
||||||
|
|
||||||
D3D12_COMMAND_QUEUE_DESC desc =
|
D3D12_COMMAND_QUEUE_DESC desc =
|
||||||
|
@ -116,53 +158,66 @@ public:
|
||||||
D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||||
D3D12_COMMAND_QUEUE_FLAG_NONE
|
D3D12_COMMAND_QUEUE_FLAG_NONE
|
||||||
};
|
};
|
||||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &m_d3dCtx.m_ctx12.m_loadq)))
|
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &m_3dCtx.m_ctx12.m_loadq)))
|
||||||
Log.report(LogVisor::FatalError, "unable to create loader queue");
|
Log.report(LogVisor::FatalError, "unable to create loader queue");
|
||||||
|
|
||||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_d3dCtx.m_ctx12.m_loadfence)))
|
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_3dCtx.m_ctx12.m_loadfence)))
|
||||||
Log.report(LogVisor::FatalError, "unable to create loader fence");
|
Log.report(LogVisor::FatalError, "unable to create loader fence");
|
||||||
|
|
||||||
m_d3dCtx.m_ctx12.m_loadfencehandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
m_3dCtx.m_ctx12.m_loadfencehandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
|
|
||||||
if (FAILED(m_d3dCtx.m_ctx12.m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_d3dCtx.m_ctx12.m_loadqalloc.Get(),
|
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_3dCtx.m_ctx12.m_loadqalloc.Get(),
|
||||||
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_d3dCtx.m_ctx12.m_loadlist)))
|
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_3dCtx.m_ctx12.m_loadlist)))
|
||||||
Log.report(LogVisor::FatalError, "unable to create loader list");
|
Log.report(LogVisor::FatalError, "unable to create loader list");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HMODULE d3d11lib = LoadLibraryW(L"D3D11.dll");
|
HMODULE d3d11lib = LoadLibraryW(L"D3D11.dll");
|
||||||
if (d3d11lib)
|
if (d3d11lib && !noD3d)
|
||||||
{
|
{
|
||||||
|
if (!FindBestD3DCompile())
|
||||||
|
Log.report(LogVisor::FatalError, "unable to find D3DCompile_[43-47].dll");
|
||||||
|
|
||||||
/* Create device proc */
|
/* Create device proc */
|
||||||
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11lib, "D3D11CreateDevice");
|
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11lib, "D3D11CreateDevice");
|
||||||
if (!MyD3D11CreateDevice)
|
if (!MyD3D11CreateDevice)
|
||||||
Log.report(LogVisor::FatalError, "unable to find D3D11CreateDevice in D3D11.dll");
|
Log.report(LogVisor::FatalError, "unable to find D3D11CreateDevice in D3D11.dll");
|
||||||
|
|
||||||
/* Create device */
|
/* Create device */
|
||||||
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_1;
|
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
|
||||||
ComPtr<ID3D11Device> tempDev;
|
ComPtr<ID3D11Device> tempDev;
|
||||||
ComPtr<ID3D11DeviceContext> tempCtx;
|
ComPtr<ID3D11DeviceContext> tempCtx;
|
||||||
if (FAILED(MyD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_FLAGS, &level,
|
if (FAILED(MyD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_FLAGS, &level,
|
||||||
1, D3D11_SDK_VERSION, &tempDev, nullptr, &tempCtx)))
|
1, D3D11_SDK_VERSION, &tempDev, nullptr, &tempCtx)))
|
||||||
Log.report(LogVisor::FatalError, "unable to create D3D11.1 device");
|
Log.report(LogVisor::FatalError, "unable to create D3D11 device");
|
||||||
tempDev.As<ID3D11Device1>(&m_d3dCtx.m_ctx11.m_dev);
|
tempDev.As<ID3D11Device1>(&m_3dCtx.m_ctx11.m_dev);
|
||||||
tempCtx.As<ID3D11DeviceContext1>(&m_d3dCtx.m_ctx11.m_devCtx);
|
tempCtx.As<ID3D11DeviceContext1>(&m_3dCtx.m_ctx11.m_devCtx);
|
||||||
|
|
||||||
/* Obtain DXGI Factory */
|
/* Obtain DXGI Factory */
|
||||||
ComPtr<IDXGIDevice2> device;
|
ComPtr<IDXGIDevice2> device;
|
||||||
ComPtr<IDXGIAdapter> adapter;
|
ComPtr<IDXGIAdapter> adapter;
|
||||||
m_d3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device);
|
m_3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device);
|
||||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_ctx11.m_dxFactory);
|
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory);
|
||||||
|
|
||||||
/* Build default sampler here */
|
/* Build default sampler here */
|
||||||
m_d3dCtx.m_ctx11.m_dev->CreateSamplerState(&CD3D11_SAMPLER_DESC(D3D11_DEFAULT), &m_d3dCtx.m_ctx11.m_ss);
|
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&CD3D11_SAMPLER_DESC(D3D11_DEFAULT), &m_3dCtx.m_ctx11.m_ss);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.report(LogVisor::FatalError, "system doesn't support D3D11.1 or D3D12");
|
/* Finally try OpenGL */
|
||||||
|
{
|
||||||
|
/* Obtain DXGI Factory */
|
||||||
|
HRESULT hr = MyCreateDXGIFactory2(DXGI_CREATE_FLAGS, __uuidof(IDXGIFactory4), &m_3dCtx.m_ctxOgl.m_dxFactory);
|
||||||
|
if (FAILED(hr))
|
||||||
|
Log.report(LogVisor::FatalError, "unable to create DXGI factory");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.report(LogVisor::FatalError, "system doesn't support OGL, D3D11 or D3D12");
|
||||||
}
|
}
|
||||||
|
|
||||||
EPlatformType getPlatformType() const
|
EPlatformType getPlatformType() const
|
||||||
|
@ -203,10 +258,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD m_mainThreadId = 0;
|
|
||||||
int run()
|
int run()
|
||||||
{
|
{
|
||||||
m_mainThreadId = GetCurrentThreadId();
|
g_mainThreadId = GetCurrentThreadId();
|
||||||
|
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
int clientReturn = 0;
|
int clientReturn = 0;
|
||||||
|
@ -261,16 +315,16 @@ public:
|
||||||
IWindow* m_mwret = nullptr;
|
IWindow* m_mwret = nullptr;
|
||||||
IWindow* newWindow(const SystemString& title)
|
IWindow* newWindow(const SystemString& title)
|
||||||
{
|
{
|
||||||
if (GetCurrentThreadId() != m_mainThreadId)
|
if (GetCurrentThreadId() != g_mainThreadId)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_nwmt);
|
std::unique_lock<std::mutex> lk(m_nwmt);
|
||||||
if (!PostThreadMessage(m_mainThreadId, WM_USER, WPARAM(&title), 0))
|
if (!PostThreadMessage(g_mainThreadId, WM_USER, WPARAM(&title), 0))
|
||||||
Log.report(LogVisor::FatalError, "PostThreadMessage error");
|
Log.report(LogVisor::FatalError, "PostThreadMessage error");
|
||||||
m_nwcv.wait(lk);
|
m_nwcv.wait(lk);
|
||||||
return m_mwret;
|
return m_mwret;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWindow* window = _WindowWin32New(title, m_d3dCtx);
|
IWindow* window = _WindowWin32New(title, m_3dCtx);
|
||||||
HWND hwnd = HWND(window->getPlatformHandle());
|
HWND hwnd = HWND(window->getPlatformHandle());
|
||||||
m_allWindows[hwnd] = window;
|
m_allWindows[hwnd] = window;
|
||||||
return window;
|
return window;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
extern DWORD g_mainThreadId;
|
||||||
|
|
||||||
#include "boo/IWindow.hpp"
|
#include "boo/IWindow.hpp"
|
||||||
|
|
||||||
namespace boo {class IWindow;}
|
namespace boo {class IWindow;}
|
||||||
|
@ -18,6 +20,8 @@ namespace boo {class IWindow;}
|
||||||
#include <dxgi1_4.h>
|
#include <dxgi1_4.h>
|
||||||
#include <d3d12.h>
|
#include <d3d12.h>
|
||||||
#include <d3d11_1.h>
|
#include <d3d11_1.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#include <wingdi.h>
|
||||||
|
|
||||||
struct D3D12Context
|
struct D3D12Context
|
||||||
{
|
{
|
||||||
|
@ -45,6 +49,8 @@ struct D3D12Context
|
||||||
#elif _WIN32_WINNT_WIN7
|
#elif _WIN32_WINNT_WIN7
|
||||||
#include <dxgi1_2.h>
|
#include <dxgi1_2.h>
|
||||||
#include <d3d11_1.h>
|
#include <d3d11_1.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#include <wingdi.h>
|
||||||
#else
|
#else
|
||||||
#error Unsupported Windows target
|
#error Unsupported Windows target
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,16 +66,43 @@ struct D3D11Context
|
||||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||||
bool m_needsResize = false;
|
bool m_needsResize = false;
|
||||||
size_t width, height;
|
size_t width, height;
|
||||||
|
|
||||||
|
bool m_needsFSTransition = false;
|
||||||
|
bool m_fs = false;
|
||||||
|
DXGI_MODE_DESC m_fsdesc = {};
|
||||||
};
|
};
|
||||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D3DAppContext
|
struct OGLContext
|
||||||
|
{
|
||||||
|
ComPtr<IDXGIFactory4> m_dxFactory;
|
||||||
|
HGLRC m_lastContext = 0;
|
||||||
|
struct Window
|
||||||
|
{
|
||||||
|
HWND m_hwnd;
|
||||||
|
HDC m_deviceContext;
|
||||||
|
HGLRC m_mainContext;
|
||||||
|
HGLRC m_renderContext;
|
||||||
|
bool m_needsResize = false;
|
||||||
|
size_t width, height;
|
||||||
|
|
||||||
|
bool m_fs = false;
|
||||||
|
LONG m_fsStyle;
|
||||||
|
LONG m_fsExStyle;
|
||||||
|
RECT m_fsRect;
|
||||||
|
int m_fsCountDown = 0;
|
||||||
|
};
|
||||||
|
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Boo3DAppContext
|
||||||
{
|
{
|
||||||
D3D11Context m_ctx11;
|
D3D11Context m_ctx11;
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
D3D12Context m_ctx12;
|
D3D12Context m_ctx12;
|
||||||
#endif
|
#endif
|
||||||
|
OGLContext m_ctxOgl;
|
||||||
|
|
||||||
void resize(boo::IWindow* window, size_t width, size_t height)
|
void resize(boo::IWindow* window, size_t width, size_t height)
|
||||||
{
|
{
|
||||||
|
@ -101,14 +134,16 @@ struct D3DAppContext
|
||||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||||
return isFScr;
|
return isFScr;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
|
if (m_ctx11.m_dev)
|
||||||
{
|
{
|
||||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||||
BOOL isFScr;
|
BOOL isFScr;
|
||||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||||
return isFScr;
|
return isFScr;
|
||||||
}
|
}
|
||||||
|
OGLContext::Window& win = m_ctxOgl.m_windows[window];
|
||||||
|
return win.m_fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setFullscreen(boo::IWindow* window, bool fs)
|
bool setFullscreen(boo::IWindow* window, bool fs)
|
||||||
|
@ -139,8 +174,8 @@ struct D3DAppContext
|
||||||
win.m_swapChain->SetFullscreenState(false, nullptr);
|
win.m_swapChain->SetFullscreenState(false, nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
|
if (m_ctx11.m_dev)
|
||||||
{
|
{
|
||||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||||
BOOL isFScr;
|
BOOL isFScr;
|
||||||
|
@ -156,15 +191,57 @@ struct D3DAppContext
|
||||||
win.m_swapChain->GetContainingOutput(&out);
|
win.m_swapChain->GetContainingOutput(&out);
|
||||||
DXGI_OUTPUT_DESC outDesc;
|
DXGI_OUTPUT_DESC outDesc;
|
||||||
out->GetDesc(&outDesc);
|
out->GetDesc(&outDesc);
|
||||||
|
|
||||||
win.m_swapChain->SetFullscreenState(true, nullptr);
|
win.m_fsdesc.Width = outDesc.DesktopCoordinates.right;
|
||||||
DXGI_MODE_DESC mdesc = {outDesc.DesktopCoordinates.right, outDesc.DesktopCoordinates.bottom};
|
win.m_fsdesc.Height = outDesc.DesktopCoordinates.bottom;
|
||||||
win.m_swapChain->ResizeTarget(&mdesc);
|
|
||||||
}
|
}
|
||||||
else
|
win.m_fs = fs;
|
||||||
win.m_swapChain->SetFullscreenState(false, nullptr);
|
win.m_needsFSTransition = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OGLContext::Window& win = m_ctxOgl.m_windows[window];
|
||||||
|
if (fs && win.m_fs)
|
||||||
|
return false;
|
||||||
|
else if (!fs && !win.m_fs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fs)
|
||||||
|
{
|
||||||
|
win.m_fsStyle = GetWindowLong(win.m_hwnd, GWL_STYLE);
|
||||||
|
win.m_fsExStyle = GetWindowLong(win.m_hwnd, GWL_EXSTYLE);
|
||||||
|
GetWindowRect(win.m_hwnd, &win.m_fsRect);
|
||||||
|
|
||||||
|
SetWindowLong(win.m_hwnd, GWL_STYLE,
|
||||||
|
win.m_fsStyle & ~(WS_CAPTION | WS_THICKFRAME));
|
||||||
|
SetWindowLong(win.m_hwnd, GWL_EXSTYLE,
|
||||||
|
win.m_fsExStyle & ~(WS_EX_DLGMODALFRAME |
|
||||||
|
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
|
||||||
|
|
||||||
|
MONITORINFO monitor_info;
|
||||||
|
monitor_info.cbSize = sizeof(monitor_info);
|
||||||
|
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST),
|
||||||
|
&monitor_info);
|
||||||
|
SetWindowPos(win.m_hwnd, NULL, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
|
||||||
|
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
|
||||||
|
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
|
||||||
|
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS);
|
||||||
|
|
||||||
|
win.m_fs = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
|
||||||
|
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
|
||||||
|
|
||||||
|
SetWindowPos(win.m_hwnd, NULL, win.m_fsRect.left, win.m_fsRect.top,
|
||||||
|
win.m_fsRect.right - win.m_fsRect.left, win.m_fsRect.bottom - win.m_fsRect.top,
|
||||||
|
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS);
|
||||||
|
|
||||||
|
win.m_fs = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,18 @@
|
||||||
#include <LogVisor/LogVisor.hpp>
|
#include <LogVisor/LogVisor.hpp>
|
||||||
|
|
||||||
#include "boo/graphicsdev/D3D.hpp"
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
|
#include "boo/graphicsdev/wglew.h"
|
||||||
|
|
||||||
|
static const int ContextAttribs[] =
|
||||||
|
{
|
||||||
|
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||||
|
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||||
|
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
//WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
||||||
|
//WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -16,17 +28,25 @@ IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext*
|
||||||
#endif
|
#endif
|
||||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
||||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent);
|
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent);
|
||||||
|
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent);
|
||||||
|
|
||||||
struct GraphicsContextWin32 : IGraphicsContext
|
struct GraphicsContextWin32 : IGraphicsContext
|
||||||
{
|
{
|
||||||
|
|
||||||
EGraphicsAPI m_api;
|
EGraphicsAPI m_api;
|
||||||
EPixelFormat m_pf;
|
EPixelFormat m_pf;
|
||||||
IWindow* m_parentWindow;
|
IWindow* m_parentWindow;
|
||||||
D3DAppContext& m_d3dCtx;
|
Boo3DAppContext& m_3dCtx;
|
||||||
|
|
||||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
|
||||||
ComPtr<IDXGIOutput> m_output;
|
ComPtr<IDXGIOutput> m_output;
|
||||||
|
GraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow, Boo3DAppContext& b3dCtx)
|
||||||
|
: m_api(api),
|
||||||
|
m_pf(PF_RGBA8),
|
||||||
|
m_parentWindow(parentWindow),
|
||||||
|
m_3dCtx(b3dCtx) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GraphicsContextWin32D3D : GraphicsContextWin32
|
||||||
|
{
|
||||||
|
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||||
|
|
||||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||||
|
@ -34,11 +54,8 @@ struct GraphicsContextWin32 : IGraphicsContext
|
||||||
public:
|
public:
|
||||||
IWindowCallback* m_callback;
|
IWindowCallback* m_callback;
|
||||||
|
|
||||||
GraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd, D3DAppContext& d3dCtx)
|
GraphicsContextWin32D3D(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd, Boo3DAppContext& b3dCtx)
|
||||||
: m_api(api),
|
: GraphicsContextWin32(api, parentWindow, b3dCtx)
|
||||||
m_pf(PF_RGBA8),
|
|
||||||
m_parentWindow(parentWindow),
|
|
||||||
m_d3dCtx(d3dCtx)
|
|
||||||
{
|
{
|
||||||
/* Create Swap Chain */
|
/* Create Swap Chain */
|
||||||
DXGI_SWAP_CHAIN_DESC1 scDesc = {};
|
DXGI_SWAP_CHAIN_DESC1 scDesc = {};
|
||||||
|
@ -50,21 +67,21 @@ public:
|
||||||
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||||
|
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
if (d3dCtx.m_ctx12.m_dev)
|
if (b3dCtx.m_ctx12.m_dev)
|
||||||
{
|
{
|
||||||
auto insIt = d3dCtx.m_ctx12.m_windows.emplace(std::make_pair(parentWindow, D3D12Context::Window()));
|
auto insIt = b3dCtx.m_ctx12.m_windows.emplace(std::make_pair(parentWindow, D3D12Context::Window()));
|
||||||
D3D12Context::Window& w = insIt.first->second;
|
D3D12Context::Window& w = insIt.first->second;
|
||||||
|
|
||||||
ID3D12CommandQueue* cmdQueue;
|
ID3D12CommandQueue* cmdQueue;
|
||||||
m_dataFactory = _NewD3D12DataFactory(&d3dCtx.m_ctx12, this);
|
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this);
|
||||||
m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, &w, this, &cmdQueue);
|
m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
|
||||||
|
|
||||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
HRESULT hr = d3dCtx.m_ctx12.m_dxFactory->CreateSwapChainForHwnd(cmdQueue,
|
HRESULT hr = b3dCtx.m_ctx12.m_dxFactory->CreateSwapChainForHwnd(cmdQueue,
|
||||||
hwnd, &scDesc, nullptr, nullptr, &m_swapChain);
|
hwnd, &scDesc, nullptr, nullptr, &m_swapChain);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
||||||
d3dCtx.m_ctx12.m_dxFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
b3dCtx.m_ctx12.m_dxFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
m_swapChain.As<IDXGISwapChain3>(&w.m_swapChain);
|
m_swapChain.As<IDXGISwapChain3>(&w.m_swapChain);
|
||||||
ComPtr<ID3D12Resource> fb;
|
ComPtr<ID3D12Resource> fb;
|
||||||
|
@ -73,16 +90,19 @@ public:
|
||||||
D3D12_RESOURCE_DESC resDesc = fb->GetDesc();
|
D3D12_RESOURCE_DESC resDesc = fb->GetDesc();
|
||||||
w.width = resDesc.Width;
|
w.width = resDesc.Width;
|
||||||
w.height = resDesc.Height;
|
w.height = resDesc.Height;
|
||||||
|
|
||||||
|
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||||
|
Log.report(LogVisor::FatalError, "unable to get DXGI output");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (FAILED(d3dCtx.m_ctx11.m_dxFactory->CreateSwapChainForHwnd(d3dCtx.m_ctx11.m_dev.Get(),
|
if (FAILED(b3dCtx.m_ctx11.m_dxFactory->CreateSwapChainForHwnd(b3dCtx.m_ctx11.m_dev.Get(),
|
||||||
hwnd, &scDesc, nullptr, nullptr, &m_swapChain)))
|
hwnd, &scDesc, nullptr, nullptr, &m_swapChain)))
|
||||||
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
||||||
d3dCtx.m_ctx11.m_dxFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
b3dCtx.m_ctx11.m_dxFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
auto insIt = d3dCtx.m_ctx11.m_windows.emplace(std::make_pair(parentWindow, D3D11Context::Window()));
|
auto insIt = b3dCtx.m_ctx11.m_windows.emplace(std::make_pair(parentWindow, D3D11Context::Window()));
|
||||||
D3D11Context::Window& w = insIt.first->second;
|
D3D11Context::Window& w = insIt.first->second;
|
||||||
|
|
||||||
m_swapChain.As<IDXGISwapChain1>(&w.m_swapChain);
|
m_swapChain.As<IDXGISwapChain1>(&w.m_swapChain);
|
||||||
|
@ -92,22 +112,22 @@ public:
|
||||||
fbRes->GetDesc(&resDesc);
|
fbRes->GetDesc(&resDesc);
|
||||||
w.width = resDesc.Width;
|
w.width = resDesc.Width;
|
||||||
w.height = resDesc.Height;
|
w.height = resDesc.Height;
|
||||||
m_dataFactory = _NewD3D11DataFactory(&d3dCtx.m_ctx11, this);
|
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this);
|
||||||
m_commandQueue = _NewD3D11CommandQueue(&d3dCtx.m_ctx11, &insIt.first->second, this);
|
m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||||
Log.report(LogVisor::FatalError, "unable to get DXGI output");
|
Log.report(LogVisor::FatalError, "unable to get DXGI output");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GraphicsContextWin32()
|
~GraphicsContextWin32D3D()
|
||||||
{
|
{
|
||||||
#if _WIN32_WINNT_WIN10
|
#if _WIN32_WINNT_WIN10
|
||||||
if (m_d3dCtx.m_ctx12.m_dev)
|
if (m_3dCtx.m_ctx12.m_dev)
|
||||||
m_d3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
|
m_3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
m_d3dCtx.m_ctx11.m_windows.erase(m_parentWindow);
|
m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCallback(IWindowCallback* cb)
|
void _setCallback(IWindowCallback* cb)
|
||||||
|
@ -150,13 +170,183 @@ public:
|
||||||
return m_dataFactory;
|
return m_dataFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates a new context on current thread!! Call from client loading thread */
|
|
||||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
{
|
{
|
||||||
return m_dataFactory;
|
return m_dataFactory;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GraphicsContextWin32GL : GraphicsContextWin32
|
||||||
|
{
|
||||||
|
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||||
|
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
IWindowCallback* m_callback;
|
||||||
|
|
||||||
|
GraphicsContextWin32GL(EGraphicsAPI api, IWindow* parentWindow, HWND hwnd, Boo3DAppContext& b3dCtx)
|
||||||
|
: GraphicsContextWin32(api, parentWindow, b3dCtx)
|
||||||
|
{
|
||||||
|
|
||||||
|
HMONITOR testMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
ComPtr<IDXGIAdapter1> adapter;
|
||||||
|
ComPtr<IDXGIOutput> foundOut;
|
||||||
|
int i=0;
|
||||||
|
while (b3dCtx.m_ctxOgl.m_dxFactory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND)
|
||||||
|
{
|
||||||
|
int j=0;
|
||||||
|
ComPtr<IDXGIOutput> out;
|
||||||
|
while (adapter->EnumOutputs(j, &out) != DXGI_ERROR_NOT_FOUND)
|
||||||
|
{
|
||||||
|
DXGI_OUTPUT_DESC desc;
|
||||||
|
out->GetDesc(&desc);
|
||||||
|
if (desc.Monitor == testMon)
|
||||||
|
{
|
||||||
|
out.As<IDXGIOutput>(&m_output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
if (m_output)
|
||||||
|
break;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_output)
|
||||||
|
Log.report(LogVisor::FatalError, "unable to find window's IDXGIOutput");
|
||||||
|
|
||||||
|
auto insIt = b3dCtx.m_ctxOgl.m_windows.emplace(std::make_pair(parentWindow, OGLContext::Window()));
|
||||||
|
OGLContext::Window& w = insIt.first->second;
|
||||||
|
w.m_hwnd = hwnd;
|
||||||
|
w.m_deviceContext = GetDC(hwnd);
|
||||||
|
if (!w.m_deviceContext)
|
||||||
|
Log.report(LogVisor::FatalError, "unable to create window's device context");
|
||||||
|
|
||||||
|
if (!m_3dCtx.m_ctxOgl.m_lastContext)
|
||||||
|
{
|
||||||
|
PIXELFORMATDESCRIPTOR pfd =
|
||||||
|
{
|
||||||
|
sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
|
1,
|
||||||
|
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
|
||||||
|
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
|
||||||
|
32, //Colordepth of the framebuffer.
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
24, //Number of bits for the depthbuffer
|
||||||
|
8, //Number of bits for the stencilbuffer
|
||||||
|
0, //Number of Aux buffers in the framebuffer.
|
||||||
|
PFD_MAIN_PLANE,
|
||||||
|
0,
|
||||||
|
0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
int pf = ChoosePixelFormat(w.m_deviceContext, &pfd);
|
||||||
|
SetPixelFormat(w.m_deviceContext, pf, &pfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
w.m_mainContext = wglCreateContext(w.m_deviceContext);
|
||||||
|
if (!w.m_mainContext)
|
||||||
|
Log.report(LogVisor::FatalError, "unable to create window's main context");
|
||||||
|
if (m_3dCtx.m_ctxOgl.m_lastContext)
|
||||||
|
if (!wglShareLists(w.m_mainContext, m_3dCtx.m_ctxOgl.m_lastContext))
|
||||||
|
Log.report(LogVisor::FatalError, "unable to share contexts");
|
||||||
|
m_3dCtx.m_ctxOgl.m_lastContext = w.m_mainContext;
|
||||||
|
|
||||||
|
m_dataFactory = new GLDataFactory(this);
|
||||||
|
m_commandQueue = _NewGLCommandQueue(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~GraphicsContextWin32GL()
|
||||||
|
{
|
||||||
|
m_3dCtx.m_ctxOgl.m_windows.erase(m_parentWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setCallback(IWindowCallback* cb)
|
||||||
|
{
|
||||||
|
m_callback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGraphicsAPI getAPI() const
|
||||||
|
{
|
||||||
|
return m_api;
|
||||||
|
}
|
||||||
|
|
||||||
|
EPixelFormat getPixelFormat() const
|
||||||
|
{
|
||||||
|
return m_pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPixelFormat(EPixelFormat pf)
|
||||||
|
{
|
||||||
|
if (pf > PF_RGBAF32_Z24)
|
||||||
|
return;
|
||||||
|
m_pf = pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeContext() {}
|
||||||
|
|
||||||
|
void makeCurrent()
|
||||||
|
{
|
||||||
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
|
if (!wglMakeCurrent(w.m_deviceContext, w.m_mainContext))
|
||||||
|
Log.report(LogVisor::FatalError, "unable to make WGL context current");
|
||||||
|
}
|
||||||
|
|
||||||
|
void postInit()
|
||||||
|
{
|
||||||
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
|
|
||||||
|
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||||
|
wglGetProcAddress("wglCreateContextAttribsARB");
|
||||||
|
w.m_renderContext = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
|
||||||
|
if (!w.m_renderContext)
|
||||||
|
Log.report(LogVisor::FatalError, "unable to make new WGL context");
|
||||||
|
if (!wglMakeCurrent(w.m_deviceContext, w.m_renderContext))
|
||||||
|
Log.report(LogVisor::FatalError, "unable to make WGL context current");
|
||||||
|
|
||||||
|
if (!WGLEW_EXT_swap_control)
|
||||||
|
Log.report(LogVisor::FatalError, "WGL_EXT_swap_control not available");
|
||||||
|
wglSwapIntervalEXT(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void present()
|
||||||
|
{
|
||||||
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
|
if (!SwapBuffers(w.m_deviceContext))
|
||||||
|
Log.report(LogVisor::FatalError, "SwapBuffers err");
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphicsCommandQueue* getCommandQueue()
|
||||||
|
{
|
||||||
|
return m_commandQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphicsDataFactory* getDataFactory()
|
||||||
|
{
|
||||||
|
return m_dataFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates a new context on current thread!! Call from client loading thread */
|
||||||
|
HGLRC m_loadCtx = 0;
|
||||||
|
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||||
|
{
|
||||||
|
OGLContext::Window& w = m_3dCtx.m_ctxOgl.m_windows[m_parentWindow];
|
||||||
|
if (!m_loadCtx)
|
||||||
|
{
|
||||||
|
m_loadCtx = wglCreateContextAttribsARB(w.m_deviceContext, w.m_mainContext, ContextAttribs);
|
||||||
|
if (!m_loadCtx)
|
||||||
|
Log.report(LogVisor::FatalError, "unable to make load WGL context");
|
||||||
|
}
|
||||||
|
if (!wglMakeCurrent(w.m_deviceContext, m_loadCtx))
|
||||||
|
Log.report(LogVisor::FatalError, "unable to make load WGL context current");
|
||||||
|
return m_dataFactory;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void genFrameDefault(MONITORINFO* screen, int& xOut, int& yOut, int& wOut, int& hOut)
|
static void genFrameDefault(MONITORINFO* screen, int& xOut, int& yOut, int& wOut, int& hOut)
|
||||||
{
|
{
|
||||||
float width = screen->rcMonitor.right * 2.0 / 3.0;
|
float width = screen->rcMonitor.right * 2.0 / 3.0;
|
||||||
|
@ -233,12 +423,20 @@ class WindowWin32 : public IWindow
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WindowWin32(const SystemString& title, D3DAppContext& d3dCtx)
|
WindowWin32(const SystemString& title, Boo3DAppContext& b3dCtx)
|
||||||
{
|
{
|
||||||
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
|
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
m_gfxCtx.reset(new GraphicsContextWin32(IGraphicsContext::API_D3D11, this, m_hwnd, d3dCtx));
|
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::API_D3D11;
|
||||||
|
if (b3dCtx.m_ctx12.m_dev)
|
||||||
|
api = IGraphicsContext::API_D3D12;
|
||||||
|
else if (b3dCtx.m_ctxOgl.m_dxFactory)
|
||||||
|
{
|
||||||
|
m_gfxCtx.reset(new GraphicsContextWin32GL(IGraphicsContext::API_OPENGL_3_3, this, m_hwnd, b3dCtx));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowWin32()
|
~WindowWin32()
|
||||||
|
@ -319,12 +517,12 @@ public:
|
||||||
|
|
||||||
bool isFullscreen() const
|
bool isFullscreen() const
|
||||||
{
|
{
|
||||||
return m_gfxCtx->m_d3dCtx.isFullscreen(this);
|
return m_gfxCtx->m_3dCtx.isFullscreen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFullscreen(bool fs)
|
void setFullscreen(bool fs)
|
||||||
{
|
{
|
||||||
m_gfxCtx->m_d3dCtx.setFullscreen(this, fs);
|
m_gfxCtx->m_3dCtx.setFullscreen(this, fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForRetrace()
|
void waitForRetrace()
|
||||||
|
@ -382,7 +580,7 @@ public:
|
||||||
getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
|
getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
|
||||||
if (!rect.size[0] || !rect.size[1])
|
if (!rect.size[0] || !rect.size[1])
|
||||||
return;
|
return;
|
||||||
m_gfxCtx->m_d3dCtx.resize(this, rect.size[0], rect.size[1]);
|
m_gfxCtx->m_3dCtx.resize(this, rect.size[0], rect.size[1]);
|
||||||
if (m_callback)
|
if (m_callback)
|
||||||
m_callback->resized(rect);
|
m_callback->resized(rect);
|
||||||
return;
|
return;
|
||||||
|
@ -546,7 +744,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IWindow* _WindowWin32New(const SystemString& title, D3DAppContext& d3dCtx)
|
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx)
|
||||||
{
|
{
|
||||||
return new WindowWin32(title, d3dCtx);
|
return new WindowWin32(title, d3dCtx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -467,10 +467,15 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
||||||
{
|
{
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
const boo::SystemChar** argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc));
|
const boo::SystemChar** argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc));
|
||||||
|
static boo::SystemChar selfPath[1024];
|
||||||
|
GetModuleFileNameW(nullptr, selfPath, 1024);
|
||||||
|
static const boo::SystemChar* booArgv[32] = {};
|
||||||
|
booArgv[0] = selfPath;
|
||||||
|
for (int i=0 ; i<argc ; ++i)
|
||||||
|
booArgv[i+1] = argv[i];
|
||||||
|
|
||||||
LogVisor::CreateWin32Console();
|
LogVisor::CreateWin32Console();
|
||||||
return main(argc, argv);
|
return main(argc+1, booArgv);
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue