diff --git a/CMakeLists.txt b/CMakeLists.txt index 07b2420..de12a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,8 +31,7 @@ if(WIN32) lib/graphicsdev/D3D12.cpp) list(APPEND PLAT_HDRS - include/boo/graphicsdev/D3D11.hpp - include/boo/graphicsdev/D3D12.hpp) + include/boo/graphicsdev/D3D.hpp) list(APPEND _BOO_SYS_DEFINES -DUNICODE -D_UNICODE) diff --git a/include/boo/IWindow.hpp b/include/boo/IWindow.hpp index 8fcb0b1..86ebeb1 100644 --- a/include/boo/IWindow.hpp +++ b/include/boo/IWindow.hpp @@ -190,11 +190,12 @@ public: virtual ETouchType getTouchType() const=0; - virtual IGraphicsCommandQueue* getCommandQueue()=0; - virtual IGraphicsDataFactory* getDataFactory()=0; virtual void setStyle(EWindowStyle style)=0; virtual EWindowStyle getStyle() const=0; + virtual IGraphicsCommandQueue* getCommandQueue()=0; + virtual IGraphicsDataFactory* getDataFactory()=0; + /* Creates a new context on current thread!! Call from client loading thread */ virtual IGraphicsDataFactory* getLoadContextDataFactory()=0; diff --git a/include/boo/graphicsdev/D3D.hpp b/include/boo/graphicsdev/D3D.hpp new file mode 100644 index 0000000..880af6a --- /dev/null +++ b/include/boo/graphicsdev/D3D.hpp @@ -0,0 +1,30 @@ +#ifndef GDEV_D3D_HPP +#define GDEV_D3D_HPP + +#if _WIN32 + +#include "IGraphicsDataFactory.hpp" +#include "IGraphicsCommandQueue.hpp" +#include "boo/IGraphicsContext.hpp" +#include "boo/System.hpp" +#include +#include +#include + +namespace boo +{ + +class ID3DDataFactory : public IGraphicsDataFactory +{ +public: + virtual IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, + ComPtr& vertBlobOut, ComPtr& fragBlobOut, + IVertexFormat* vtxFmt, + BlendFactor srcFac, BlendFactor dstFac, + bool depthTest, bool depthWrite, bool backfaceCulling)=0; +}; + +} + +#endif // _WIN32 +#endif // GDEV_D3D_HPP diff --git a/include/boo/graphicsdev/D3D11.hpp b/include/boo/graphicsdev/D3D11.hpp deleted file mode 100644 index f4f15db..0000000 --- a/include/boo/graphicsdev/D3D11.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef GDEV_D3D11_HPP -#define GDEV_D3D11_HPP - -#if _WIN32 -#include -#if _WIN32_WINNT_WIN7 - -#if 0 - -#include "IGraphicsDataFactory.hpp" - -namespace boo -{ - -class D3D11DataFactory : public IGraphicsDataFactory -{ - IGraphicsContext* m_parent; - IGraphicsData* m_deferredData = nullptr; - std::unordered_set m_committedData; -public: - D3D11DataFactory(IGraphicsContext* parent); - ~D3D11DataFactory() {} - - Platform platform() const {return PlatformD3D11;} - const char* platformName() const {return "Direct 3D 11";} - - IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t sz); - IGraphicsBufferD* newDynamicBuffer(BufferUse use); - - ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz); - ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); - - IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); - - IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, - size_t texCount, const char** texNames, - BlendFactor srcFac, BlendFactor dstFac, - bool depthTest, bool depthWrite, bool backfaceCulling); - - IShaderDataBinding* - newShaderDataBinding(const IShaderPipeline* pipeline, - const IVertexFormat* vtxFormat, - const IGraphicsBuffer* vbo, const IGraphicsBuffer* ebo, - size_t ubufCount, const IGraphicsBuffer** ubufs, - size_t texCount, const ITexture** texs); - - void reset(); - IGraphicsData* commit(); - void destroyData(IGraphicsData*); - void destroyAllData(); -}; - -} -#endif -#endif // _WIN32_WINNT_WIN7 -#endif // _WIN32 -#endif // GDEV_D3D11_HPP diff --git a/include/boo/graphicsdev/D3D12.hpp b/include/boo/graphicsdev/D3D12.hpp deleted file mode 100644 index 57361ad..0000000 --- a/include/boo/graphicsdev/D3D12.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef GDEV_D3D12_HPP -#define GDEV_D3D12_HPP - -#if _WIN32 -#include -#if _WIN32_WINNT_WIN10 - -#include "IGraphicsDataFactory.hpp" -#include "IGraphicsCommandQueue.hpp" -#include "boo/IGraphicsContext.hpp" -#include "boo/System.hpp" -#include -#include -#include - -namespace boo -{ - -class D3D12DataFactory : public IGraphicsDataFactory -{ - IGraphicsContext* m_parent; - IGraphicsData* m_deferredData = nullptr; - struct D3D12Context* m_ctx; - std::unordered_set m_committedData; -public: - D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx); - ~D3D12DataFactory() {} - - Platform platform() const {return PlatformD3D12;} - const char* platformName() const {return "Direct 3D 12";} - - IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, 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, - const void* data, size_t sz); - ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt); - ITextureR* newRenderTexture(size_t width, size_t height, size_t samples); - - IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); - - IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, - ComPtr& vertBlobOut, ComPtr& fragBlobOut, - IVertexFormat* vtxFmt, - BlendFactor srcFac, BlendFactor dstFac, - bool depthTest, bool depthWrite, bool backfaceCulling); - - IShaderDataBinding* - newShaderDataBinding(IShaderPipeline* pipeline, - IVertexFormat* vtxFormat, - IGraphicsBuffer* vbo, IGraphicsBuffer* ebo, - size_t ubufCount, IGraphicsBuffer** ubufs, - size_t texCount, ITexture** texs); - - void reset(); - IGraphicsData* commit(); - void destroyData(IGraphicsData* data); - void destroyAllData(); -}; - -} - -#endif // _WIN32_WINNT_WIN10 -#endif // _WIN32 -#endif // GDEV_D3D12_HPP diff --git a/lib/graphicsdev/D3D11.cpp b/lib/graphicsdev/D3D11.cpp index e69de29..b085ce2 100644 --- a/lib/graphicsdev/D3D11.cpp +++ b/lib/graphicsdev/D3D11.cpp @@ -0,0 +1,816 @@ +#include "../win/Win32Common.hpp" +#include +#include "boo/graphicsdev/D3D.hpp" +#include "boo/IGraphicsContext.hpp" +#include +#include +#include +#include +#include +#include + +namespace boo +{ +static LogVisor::LogModule Log("boo::D3D11"); + +static inline void ThrowIfFailed(HRESULT hr) +{ + if (FAILED(hr)) + { + // Set a breakpoint on this line to catch Win32 API errors. + _com_error err(hr); + LPCTSTR errMsg = err.ErrorMessage(); + Log.report(LogVisor::FatalError, errMsg); + } +} + +struct D3D11Data : IGraphicsData +{ + std::vector> m_SPs; + std::vector> m_SBinds; + std::vector> m_SBufs; + std::vector> m_DBufs; + std::vector> m_STexs; + std::vector> m_DTexs; + std::vector> m_RTexs; + std::vector> m_VFmts; +}; + +static const D3D11_BIND_FLAG USE_TABLE[] = +{ + D3D11_BIND_VERTEX_BUFFER, + D3D11_BIND_VERTEX_BUFFER, + D3D11_BIND_INDEX_BUFFER, + D3D11_BIND_CONSTANT_BUFFER +}; + +class D3D11GraphicsBufferS : public IGraphicsBufferS +{ + friend class D3D11DataFactory; + friend struct D3D11CommandQueue; + size_t m_sz; + D3D11GraphicsBufferS(BufferUse use, D3D11Context* ctx, const void* data, size_t stride, size_t count) + : m_stride(stride), m_count(count), m_sz(stride * count) + { + D3D11_SUBRESOURCE_DATA iData = {data}; + ThrowIfFailed(ctx->m_dev->CreateBuffer(&CD3D11_BUFFER_DESC(m_sz, USE_TABLE[use], D3D11_USAGE_IMMUTABLE), &iData, &m_buf)); + } +public: + size_t m_stride; + size_t m_count; + ComPtr m_buf; + ~D3D11GraphicsBufferS() = default; +}; + +class D3D11GraphicsBufferD : public IGraphicsBufferD +{ + friend class D3D11DataFactory; + friend struct D3D11CommandQueue; + D3D11CommandQueue* m_q; + D3D11GraphicsBufferD(D3D11CommandQueue* q, BufferUse use, D3D11Context* ctx, size_t stride, size_t count) + : m_q(q), m_stride(stride), m_count(count) + { + size_t sz = stride * count; + for (int i=0 ; i<3 ; ++i) + ThrowIfFailed(ctx->m_dev->CreateBuffer(&CD3D11_BUFFER_DESC(sz, USE_TABLE[use]), nullptr, &m_bufs[i])); + } +public: + size_t m_stride; + size_t m_count; + ComPtr m_bufs[3]; + ~D3D11GraphicsBufferD() = default; + + void load(const void* data, size_t sz); + void* map(size_t sz); + void unmap(); + + +}; + +class D3D11TextureS : public ITextureS +{ + friend class D3D11DataFactory; + size_t m_sz; + D3D11TextureS(D3D11Context* ctx, size_t width, size_t height, size_t mips, + TextureFormat fmt, const void* data, size_t sz) + : m_sz(sz) + { + CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, mips, + D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE); + + const uint8_t* dataIt = static_cast(data); + D3D11_SUBRESOURCE_DATA upData[16] = {}; + for (size_t i=0 ; im_dev->CreateTexture2D(&desc, upData, &m_tex)); + ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_tex.Get(), + &CD3D11_SHADER_RESOURCE_VIEW_DESC(m_tex.Get(), D3D_SRV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM), &m_srv)); + } +public: + ComPtr m_tex; + ComPtr m_srv; + ~D3D11TextureS() = default; +}; + +class D3D11TextureD : public ITextureD +{ + friend class D3D11DataFactory; + friend struct D3D11CommandQueue; + size_t m_width = 0; + size_t m_height = 0; + D3D11CommandQueue* m_q; + D3D11TextureD(D3D11CommandQueue* q, D3D11Context* ctx, size_t width, size_t height, TextureFormat fmt) + : m_q(q) + { + CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1, + D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, D3D11_CPU_ACCESS_WRITE); + for (int i=0 ; i<3 ; ++i) + { + ThrowIfFailed(ctx->m_dev->CreateTexture2D(&desc, nullptr, &m_texs[i])); + ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_texs[i].Get(), + &CD3D11_SHADER_RESOURCE_VIEW_DESC(m_texs[i].Get(), D3D_SRV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM), &m_srvs[i])); + } + } +public: + ComPtr m_texs[3]; + ComPtr m_srvs[3]; + ~D3D11TextureD() = default; + + void load(const void* data, size_t sz); + void* map(size_t sz); + void unmap(); +}; + +class D3D11TextureR : public ITextureR +{ + friend class D3D11DataFactory; + friend struct D3D11CommandQueue; + size_t m_width = 0; + size_t m_height = 0; + size_t m_samples = 0; + + void Setup(D3D11Context* ctx, size_t width, size_t height, size_t samples) + { + ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, + 1, 1, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, 1), nullptr, &m_tex)); + ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_D24_UNORM_S8_UINT, width, height, + 1, 1, D3D11_BIND_DEPTH_STENCIL, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_depthTex)); + + if (samples > 1) + { + ThrowIfFailed(ctx->m_dev->CreateTexture2D(&CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, + 1, 1, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, samples), nullptr, &m_msaaTex)); + ThrowIfFailed(ctx->m_dev->CreateRenderTargetView(m_msaaTex.Get(), + &CD3D11_RENDER_TARGET_VIEW_DESC(m_msaaTex.Get(), D3D11_RTV_DIMENSION_TEXTURE2DMS), &m_rtv)); + ThrowIfFailed(ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), + &CD3D11_DEPTH_STENCIL_VIEW_DESC(m_depthTex.Get(), D3D11_DSV_DIMENSION_TEXTURE2DMS), &m_dsv)); + } + else + { + ThrowIfFailed(ctx->m_dev->CreateRenderTargetView(m_tex.Get(), + &CD3D11_RENDER_TARGET_VIEW_DESC(m_tex.Get(), D3D11_RTV_DIMENSION_TEXTURE2D), &m_rtv)); + ThrowIfFailed(ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), + &CD3D11_DEPTH_STENCIL_VIEW_DESC(m_depthTex.Get(), D3D11_DSV_DIMENSION_TEXTURE2D), &m_dsv)); + } + + ThrowIfFailed(ctx->m_dev->CreateShaderResourceView(m_tex.Get(), + &CD3D11_SHADER_RESOURCE_VIEW_DESC(m_tex.Get(), D3D11_SRV_DIMENSION_TEXTURE2D), &m_srv)); + } + + D3D11TextureR(D3D11Context* ctx, size_t width, size_t height, size_t samples) + : m_width(width), m_height(height), m_samples(samples) + { + if (samples == 0) m_samples = 1; + Setup(ctx, width, height, samples); + } +public: + size_t samples() const {return m_samples;} + ComPtr m_tex; + ComPtr m_msaaTex; + ComPtr m_depthTex; + ComPtr m_rtv; + ComPtr m_dsv; + ComPtr m_srv; + ~D3D11TextureR() = default; + + void resize(D3D11Context* ctx, size_t width, size_t height) + { + if (width < 1) + width = 1; + if (height < 1) + height = 1; + m_width = width; + m_height = height; + Setup(ctx, width, height, m_samples); + } +}; + +static const size_t SEMANTIC_SIZE_TABLE[] = +{ + 12, + 12, + 4, + 8, + 16 +}; + +static const char* SEMANTIC_NAME_TABLE[] = +{ + "POSITION", + "NORMAL", + "COLOR", + "UV", + "WEIGHT" +}; + +static const DXGI_FORMAT SEMANTIC_TYPE_TABLE[] = +{ + DXGI_FORMAT_R32G32B32_FLOAT, + DXGI_FORMAT_R32G32B32_FLOAT, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT +}; + +struct D3D11VertexFormat : IVertexFormat +{ + size_t m_elementCount; + std::unique_ptr m_elements; + D3D11VertexFormat(size_t elementCount, const VertexElementDescriptor* elements) + : m_elementCount(elementCount), + m_elements(new D3D11_INPUT_ELEMENT_DESC[elementCount]) + { + memset(m_elements.get(), 0, elementCount * sizeof(D3D11_INPUT_ELEMENT_DESC)); + size_t offset = 0; + for (size_t i=0 ; isemantic]; + elem.SemanticIndex = elemin->semanticIdx; + elem.Format = SEMANTIC_TYPE_TABLE[elemin->semantic]; + elem.AlignedByteOffset = offset; + elem.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + offset += SEMANTIC_SIZE_TABLE[elemin->semantic]; + } + } +}; + +static const D3D11_BLEND BLEND_FACTOR_TABLE[] = +{ + D3D11_BLEND_ZERO, + D3D11_BLEND_ONE, + D3D11_BLEND_SRC_COLOR, + D3D11_BLEND_INV_SRC_COLOR, + D3D11_BLEND_DEST_COLOR, + D3D11_BLEND_INV_DEST_COLOR, + D3D11_BLEND_SRC_ALPHA, + D3D11_BLEND_INV_SRC_ALPHA, + D3D11_BLEND_DEST_ALPHA, + D3D11_BLEND_INV_DEST_ALPHA +}; + +class D3D11ShaderPipeline : public IShaderPipeline +{ + friend class D3D11DataFactory; + D3D11ShaderPipeline(D3D11Context* ctx, ID3DBlob* vert, ID3DBlob* pixel, + const D3D11VertexFormat* vtxFmt, + BlendFactor srcFac, BlendFactor dstFac, + bool depthTest, bool depthWrite, bool backfaceCulling) + { + ThrowIfFailed(ctx->m_dev->CreateVertexShader(vert->GetBufferPointer(), vert->GetBufferSize(), nullptr, &m_vShader)); + ThrowIfFailed(ctx->m_dev->CreatePixelShader(pixel->GetBufferPointer(), pixel->GetBufferSize(), nullptr, &m_pShader)); + + CD3D11_RASTERIZER_DESC rasDesc(D3D11_FILL_SOLID, backfaceCulling ? D3D11_CULL_BACK : D3D11_CULL_NONE, true, + D3D11_DEFAULT_DEPTH_BIAS, D3D11_DEFAULT_DEPTH_BIAS_CLAMP, D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + true, false, false, false); + ThrowIfFailed(ctx->m_dev->CreateRasterizerState(&rasDesc, &m_rasState)); + + CD3D11_DEPTH_STENCIL_DESC dsDesc(D3D11_DEFAULT); + dsDesc.DepthEnable = depthTest; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK(depthWrite); + dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + ThrowIfFailed(ctx->m_dev->CreateDepthStencilState(&dsDesc, &m_dsState)); + + CD3D11_BLEND_DESC blDesc(D3D11_DEFAULT); + blDesc.RenderTarget[0].BlendEnable = (dstFac != BlendFactorZero); + blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[srcFac]; + blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[dstFac]; + ThrowIfFailed(ctx->m_dev->CreateBlendState(&blDesc, &m_blState)); + + ThrowIfFailed(ctx->m_dev->CreateInputLayout(vtxFmt->m_elements.get(), vtxFmt->m_elementCount, + vert->GetBufferPointer(), vert->GetBufferSize(), &m_inLayout)); + } +public: + ComPtr m_vShader; + ComPtr m_pShader; + ComPtr m_rasState; + ComPtr m_dsState; + ComPtr m_blState; + ComPtr m_inLayout; + ~D3D11ShaderPipeline() = default; + D3D11ShaderPipeline& operator=(const D3D11ShaderPipeline&) = delete; + D3D11ShaderPipeline(const D3D11ShaderPipeline&) = delete; + + void bind(ID3D11DeviceContext* ctx) + { + ctx->VSSetShader(m_vShader.Get(), nullptr, 0); + ctx->PSSetShader(m_pShader.Get(), nullptr, 0); + ctx->RSSetState(m_rasState.Get()); + ctx->OMSetDepthStencilState(m_dsState.Get(), 0); + ctx->OMSetBlendState(m_blState.Get(), nullptr, 0xffffffff); + ctx->IASetInputLayout(m_inLayout.Get()); + } +}; + +struct D3D11ShaderDataBinding : IShaderDataBinding +{ + D3D11ShaderPipeline* m_pipeline; + IGraphicsBuffer* m_vbuf; + IGraphicsBuffer* m_ibuf; + size_t m_ubufCount; + std::unique_ptr m_ubufs; + size_t m_texCount; + std::unique_ptr m_texs; + D3D11ShaderDataBinding(D3D11Context* ctx, + IShaderPipeline* pipeline, + IGraphicsBuffer* vbuf, IGraphicsBuffer* ibuf, + size_t ubufCount, IGraphicsBuffer** ubufs, + size_t texCount, ITexture** texs) + : m_pipeline(static_cast(pipeline)), + m_vbuf(vbuf), + m_ibuf(ibuf), + m_ubufCount(ubufCount), + m_ubufs(new IGraphicsBuffer*[ubufCount]), + m_texCount(texCount), + m_texs(new ITexture*[texCount]) + { + for (size_t i=0 ; ibind(ctx); + + if (m_vbuf->dynamic()) + { + D3D11GraphicsBufferD* cbuf = static_cast(m_vbuf); + ID3D11Buffer* buf[] = {cbuf->m_bufs[b].Get()}; + UINT strides[] = {cbuf->m_stride}; + UINT offsets[] = {0}; + ctx->IASetVertexBuffers(0, 1, buf, strides, offsets); + } + else + { + D3D11GraphicsBufferS* cbuf = static_cast(m_vbuf); + ID3D11Buffer* buf[] = {cbuf->m_buf.Get()}; + UINT strides[] = {cbuf->m_stride}; + UINT offsets[] = {0}; + ctx->IASetVertexBuffers(0, 1, buf, strides, offsets); + } + + if (m_ibuf) + { + if (m_ibuf->dynamic()) + { + D3D11GraphicsBufferD* cbuf = static_cast(m_ibuf); + ctx->IASetIndexBuffer(cbuf->m_bufs[b].Get(), DXGI_FORMAT_R32_UINT, 0); + } + else + { + D3D11GraphicsBufferS* cbuf = static_cast(m_ibuf); + ctx->IASetIndexBuffer(cbuf->m_buf.Get(), DXGI_FORMAT_R32_UINT, 0); + } + } + + if (m_ubufCount) + { + ID3D11Buffer* constBufs[8]; + for (int i=0 ; i<8 && idynamic()) + { + D3D11GraphicsBufferD* cbuf = static_cast(m_ubufs[i]); + constBufs[i] = cbuf->m_bufs[b].Get(); + } + else + { + D3D11GraphicsBufferS* cbuf = static_cast(m_ubufs[i]); + constBufs[i] = cbuf->m_buf.Get(); + } + } + ctx->VSSetConstantBuffers(0, m_ubufCount, constBufs); + } + + if (m_texCount) + { + ID3D11ShaderResourceView* srvs[8]; + for (int i=0 ; i<8 && itype() == ITexture::TextureDynamic) + { + D3D11TextureD* ctex = static_cast(m_texs[i]); + srvs[i] = ctex->m_srvs[b].Get(); + } + else if (m_texs[i]->type() == ITexture::TextureStatic) + { + D3D11TextureS* ctex = static_cast(m_texs[i]); + srvs[i] = ctex->m_srv.Get(); + } + } + ctx->PSSetShaderResources(0, m_texCount, srvs); + } + } +}; + +struct D3D11CommandQueue : IGraphicsCommandQueue +{ + Platform platform() const {return IGraphicsDataFactory::PlatformD3D11;} + const char* platformName() const {return "Direct3D 11";} + D3D11Context* m_ctx; + D3D11Context::Window* m_windowCtx; + IGraphicsContext* m_parent; + ComPtr m_deferredCtx; + + size_t m_fillBuf = 0; + size_t m_completeBuf = 0; + size_t m_drawBuf = 0; + bool m_running = true; + + std::mutex m_mt; + std::condition_variable m_cv; + std::mutex m_initmt; + std::condition_variable m_initcv; + std::unique_lock m_initlk; + std::thread m_thr; + + ComPtr m_cmdLists[3]; + bool m_needPresent[3]; + + static void RenderingWorker(D3D11CommandQueue* self) + { + { + std::unique_lock lk(self->m_initmt); + } + self->m_initcv.notify_one(); + while (self->m_running) + { + { + std::unique_lock lk(self->m_mt); + self->m_cv.wait(lk); + if (!self->m_running) + break; + self->m_drawBuf = self->m_completeBuf; + } + ID3D11CommandList* list = self->m_cmdLists[self->m_drawBuf].Get(); + self->m_ctx->m_devCtx->ExecuteCommandList(list, false); + self->m_cmdLists[self->m_drawBuf].Reset(); + if (self->m_needPresent[self->m_drawBuf]) + self->m_windowCtx->m_swapChain->Present(1, 0); + } + } + + D3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent) + : m_ctx(ctx), m_windowCtx(windowCtx), m_parent(parent), + m_initlk(m_initmt), + m_thr(RenderingWorker, this) + { + m_initcv.wait(m_initlk); + m_initlk.unlock(); + ThrowIfFailed(ctx->m_dev->CreateDeferredContext1(0, &m_deferredCtx)); + } + + ~D3D11CommandQueue() + { + m_running = false; + m_cv.notify_one(); + m_thr.join(); + } + + void setShaderDataBinding(IShaderDataBinding* binding) + { + D3D11ShaderDataBinding* cbind = static_cast(binding); + cbind->bind(m_deferredCtx.Get(), m_fillBuf); + + ID3D11SamplerState* samp[] = {m_ctx->m_ss.Get()}; + m_deferredCtx->PSSetSamplers(0, 1, samp); + } + + D3D11TextureR* m_boundTarget = nullptr; + void setRenderTarget(ITextureR* target) + { + D3D11TextureR* ctarget = static_cast(target); + ID3D11RenderTargetView* view[] = {ctarget->m_rtv.Get()}; + m_deferredCtx->OMSetRenderTargets(1, view, ctarget->m_dsv.Get()); + m_boundTarget = ctarget; + } + + void setViewport(const SWindowRect& rect) + { + D3D11_VIEWPORT vp = {rect.location[0], rect.location[1], rect.size[0], rect.size[1], 0.0, 1.0}; + m_deferredCtx->RSSetViewports(1, &vp); + } + + void resizeRenderTexture(ITextureR* tex, size_t width, size_t height) + { + D3D11TextureR* ctex = static_cast(tex); + ctex->resize(m_ctx, width, height); + } + + float m_clearColor[4] = {0.0,0.0,0.0,1.0}; + void setClearColor(const float rgba[4]) + { + m_clearColor[0] = rgba[0]; + m_clearColor[1] = rgba[1]; + m_clearColor[2] = rgba[2]; + m_clearColor[3] = rgba[3]; + } + + void clearTarget(bool render=true, bool depth=true) + { + if (!m_boundTarget) + return; + if (render) + m_deferredCtx->ClearRenderTargetView(m_boundTarget->m_rtv.Get(), m_clearColor); + if (depth) + m_deferredCtx->ClearDepthStencilView(m_boundTarget->m_dsv.Get(), D3D11_CLEAR_DEPTH, 1.0, 0); + } + + void setDrawPrimitive(Primitive prim) + { + if (prim == PrimitiveTriangles) + m_deferredCtx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + else if (prim == PrimitiveTriStrips) + m_deferredCtx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + } + + void draw(size_t start, size_t count) + { + m_deferredCtx->DrawInstanced(count, 1, start, 0); + } + + void drawIndexed(size_t start, size_t count) + { + m_deferredCtx->DrawIndexedInstanced(count, 1, start, 0, 0); + } + + void drawInstances(size_t start, size_t count, size_t instCount) + { + m_deferredCtx->DrawInstanced(count, instCount, start, 0); + } + + void drawInstancesIndexed(size_t start, size_t count, size_t instCount) + { + m_deferredCtx->DrawIndexedInstanced(count, instCount, start, 0, 0); + } + + bool m_doPresent = false; + void resolveDisplay(ITextureR* source) + { + D3D11TextureR* csource = static_cast(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 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() + { + ThrowIfFailed(m_deferredCtx->FinishCommandList(false, &m_cmdLists[m_fillBuf])); + m_needPresent[m_fillBuf] = m_doPresent; + m_doPresent = false; + std::unique_lock lk(m_mt); + m_completeBuf = m_fillBuf; + for (size_t i=0 ; i<3 ; ++i) + { + if (i == m_completeBuf || i == m_drawBuf) + continue; + m_fillBuf = i; + break; + } + lk.unlock(); + m_cv.notify_one(); + } +}; + +void D3D11GraphicsBufferD::load(const void* data, size_t sz) +{ + ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get(); + D3D11_MAPPED_SUBRESOURCE d; + m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d); + memcpy(d.pData, data, sz); + m_q->m_deferredCtx->Unmap(res, 0); +} +void* D3D11GraphicsBufferD::map(size_t sz) +{ + ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get(); + D3D11_MAPPED_SUBRESOURCE d; + m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d); + return d.pData; +} +void D3D11GraphicsBufferD::unmap() +{ + ID3D11Buffer* res = m_bufs[m_q->m_fillBuf].Get(); + m_q->m_deferredCtx->Unmap(res, 0); +} + +void D3D11TextureD::load(const void* data, size_t sz) +{ + ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get(); + D3D11_MAPPED_SUBRESOURCE d; + m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d); + memcpy(d.pData, data, sz); + m_q->m_deferredCtx->Unmap(res, 0); +} +void* D3D11TextureD::map(size_t sz) +{ + ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get(); + D3D11_MAPPED_SUBRESOURCE d; + m_q->m_deferredCtx->Map(res, 0, D3D11_MAP_WRITE_DISCARD, 0, &d); + return d.pData; +} +void D3D11TextureD::unmap() +{ + ID3D11Texture2D* res = m_texs[m_q->m_fillBuf].Get(); + m_q->m_deferredCtx->Unmap(res, 0); +} + +class D3D11DataFactory : public ID3DDataFactory +{ + IGraphicsContext* m_parent; + IGraphicsData* m_deferredData = nullptr; + struct D3D11Context* m_ctx; + std::unordered_set m_committedData; +public: + D3D11DataFactory(IGraphicsContext* parent, D3D11Context* ctx) + : m_parent(parent), m_deferredData(new struct D3D11Data()), m_ctx(ctx) + {} + ~D3D11DataFactory() = default; + + Platform platform() const {return PlatformD3D11;} + const char* platformName() const {return "Direct3D 11";} + + IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) + { + D3D11GraphicsBufferS* retval = new D3D11GraphicsBufferS(use, m_ctx, data, stride, count); + static_cast(m_deferredData)->m_SBufs.emplace_back(retval); + return retval; + } + + IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count) + { + D3D11CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D11GraphicsBufferD* retval = new D3D11GraphicsBufferD(q, use, m_ctx, stride, count); + static_cast(m_deferredData)->m_DBufs.emplace_back(retval); + return retval; + } + + ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, + const void* data, size_t sz) + { + D3D11TextureS* retval = new D3D11TextureS(m_ctx, width, height, mips, fmt, data, sz); + static_cast(m_deferredData)->m_STexs.emplace_back(retval); + return retval; + } + + ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt) + { + D3D11CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D11TextureD* retval = new D3D11TextureD(q, m_ctx, width, height, fmt); + static_cast(m_deferredData)->m_DTexs.emplace_back(retval); + return retval; + } + + ITextureR* newRenderTexture(size_t width, size_t height, size_t samples) + { + D3D11CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D11TextureR* retval = new D3D11TextureR(m_ctx, width, height, samples); + static_cast(m_deferredData)->m_RTexs.emplace_back(retval); + return retval; + } + + IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements) + { + D3D11CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D11VertexFormat* retval = new struct D3D11VertexFormat(elementCount, elements); + static_cast(m_deferredData)->m_VFmts.emplace_back(retval); + return retval; + } + +#if _DEBUG +#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 +#else +#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + + IShaderPipeline* newShaderPipeline + (const char* vertSource, const char* fragSource, + ComPtr& vertBlobOut, ComPtr& fragBlobOut, + IVertexFormat* vtxFmt, BlendFactor srcFac, BlendFactor dstFac, + bool depthTest, bool depthWrite, bool backfaceCulling) + { + ComPtr errBlob; + + if (FAILED(D3DCompile(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main", + "vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob))) + { + Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer()); + return nullptr; + } + + if (FAILED(D3DCompile(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main", + "ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob))) + { + Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer()); + return nullptr; + } + + D3D11ShaderPipeline* retval = new D3D11ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), + static_cast(vtxFmt), + srcFac, dstFac, depthTest, depthWrite, backfaceCulling); + static_cast(m_deferredData)->m_SPs.emplace_back(retval); + return retval; + } + + IShaderDataBinding* newShaderDataBinding(IShaderPipeline* pipeline, + IVertexFormat* vtxFormat, + IGraphicsBuffer* vbuf, IGraphicsBuffer* ibuf, + size_t ubufCount, IGraphicsBuffer** ubufs, + size_t texCount, ITexture** texs) + { + D3D11ShaderDataBinding* retval = + new D3D11ShaderDataBinding(m_ctx, pipeline, vbuf, ibuf, ubufCount, ubufs, texCount, texs); + static_cast(m_deferredData)->m_SBinds.emplace_back(retval); + return retval; + } + + void reset() + { + delete static_cast(m_deferredData); + m_deferredData = new struct D3D11Data(); + } + + IGraphicsData* commit() + { + IGraphicsData* retval = m_deferredData; + m_deferredData = new struct D3D11Data(); + m_committedData.insert(retval); + return retval; + } + + void destroyData(IGraphicsData* d) + { + D3D11Data* data = static_cast(d); + m_committedData.erase(data); + delete data; + } + + void destroyAllData() + { + for (IGraphicsData* data : m_committedData) + delete static_cast(data); + m_committedData.clear(); + } +}; + + +IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent) +{ + return new D3D11CommandQueue(ctx, windowCtx, parent); +} + +IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent) +{ + return new D3D11DataFactory(parent, ctx); +} + +} diff --git a/lib/graphicsdev/D3D12.cpp b/lib/graphicsdev/D3D12.cpp index c284321..f6ea31b 100644 --- a/lib/graphicsdev/D3D12.cpp +++ b/lib/graphicsdev/D3D12.cpp @@ -1,13 +1,9 @@ #include "../win/Win32Common.hpp" -#include "boo/graphicsdev/D3D12.hpp" +#if _WIN32_WINNT_WIN10 +#include +#include "boo/graphicsdev/D3D.hpp" #include "boo/IGraphicsContext.hpp" #include -#include -#include -#include - -#include - #include "d3dx12.h" #include #include @@ -64,15 +60,20 @@ class D3D12GraphicsBufferS : public IGraphicsBufferS friend class D3D12DataFactory; friend struct D3D12CommandQueue; D3D12_RESOURCE_STATES m_state; - const void* m_data; size_t m_sz; + D3D12_RESOURCE_DESC m_gpuDesc; D3D12GraphicsBufferS(BufferUse use, D3D12Context* ctx, const void* data, size_t stride, size_t count) - : m_state(USE_TABLE[use]), m_stride(stride), m_count(count), m_data(data), m_sz(stride * count) + : m_state(USE_TABLE[use]), m_stride(stride), m_count(count), m_sz(stride * count) { + m_gpuDesc = CD3DX12_RESOURCE_DESC::Buffer(m_sz); ThrowIfFailed(ctx->m_dev->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(m_sz), + D3D12_HEAP_FLAG_NONE, &m_gpuDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_buf)); + + D3D12_SUBRESOURCE_DATA upData = {data, m_sz, m_sz}; + if (!PrepSubresources<16>(ctx->m_dev.Get(), m_gpuDesc, m_buf.Get(), 0, 0, 1, &upData)) + Log.report(LogVisor::FatalError, "error preparing resource for upload"); } public: size_t m_stride; @@ -83,18 +84,15 @@ public: UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) { - D3D12_RESOURCE_DESC desc = m_buf->GetDesc(); - ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc, m_state, + ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &m_gpuDesc, m_state, nullptr, __uuidof(ID3D12Resource), &m_gpuBuf)); /* Stage resource upload */ - D3D12_SUBRESOURCE_DATA upData = {m_data, m_sz, m_sz}; - if (!UpdateSubresources<16>(ctx->m_loadlist.Get(), m_gpuBuf.Get(), m_buf.Get(), 0, 0, 1, &upData)) - Log.report(LogVisor::FatalError, "error preparing resource for upload"); + CommandSubresourcesTransfer<16>(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuBuf.Get(), m_buf.Get(), 0, 0, 1); ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuBuf.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); - return NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &desc)); + return NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &m_gpuDesc)); } }; @@ -140,48 +138,24 @@ public: } }; -IGraphicsBufferS* -D3D12DataFactory::newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) -{ - D3D12GraphicsBufferS* retval = new D3D12GraphicsBufferS(use, m_ctx, data, stride, count); - static_cast(m_deferredData)->m_SBufs.emplace_back(retval); - return retval; -} - class D3D12TextureS : public ITextureS { friend class D3D12DataFactory; - const void* m_data; size_t m_sz; - D3D12_RESOURCE_DESC m_desc; + D3D12_RESOURCE_DESC m_gpuDesc; D3D12TextureS(D3D12Context* ctx, size_t width, size_t height, size_t mips, TextureFormat fmt, const void* data, size_t sz) - : m_data(data), m_sz(sz) + : m_sz(sz) { - m_desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, mips); + m_gpuDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, mips); ThrowIfFailed(ctx->m_dev->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sz), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), &m_tex)); - } -public: - ComPtr m_tex; - ComPtr m_gpuTex; - ~D3D12TextureS() = default; - UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) - { - ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &m_desc, - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, __uuidof(ID3D12Resource), &m_gpuTex)); - - int width = m_desc.Width; - int height = m_desc.Height; - - /* Stage resource upload */ - const uint8_t* dataIt = static_cast(m_data); + const uint8_t* dataIt = static_cast(data); D3D12_SUBRESOURCE_DATA upData[16] = {}; - for (size_t i=0 ; i(ctx->m_loadlist.Get(), m_gpuTex.Get(), m_tex.Get(), 0, 0, m_desc.MipLevels, upData)) + if (!PrepSubresources<16>(ctx->m_dev.Get(), m_gpuDesc, m_tex.Get(), 0, 0, m_gpuDesc.MipLevels, upData)) Log.report(LogVisor::FatalError, "error preparing resource for upload"); + } +public: + ComPtr m_tex; + ComPtr m_gpuTex; + ~D3D12TextureS() = default; + + UINT64 placeForGPU(D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) + { + ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &m_gpuDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, __uuidof(ID3D12Resource), &m_gpuTex)); + + CommandSubresourcesTransfer<16>(ctx->m_dev.Get(), ctx->m_loadlist.Get(), m_gpuTex.Get(), m_tex.Get(), 0, 0, m_gpuDesc.MipLevels); ctx->m_loadlist->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_gpuTex.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); - return NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &m_desc)); + return NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &m_gpuDesc)); } }; @@ -257,13 +244,7 @@ class D3D12TextureR : public ITextureR 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET); ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &rtvresdesc, D3D12_RESOURCE_STATE_RENDER_TARGET, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_R8G8B8A8_UNORM, BLACK_COLOR), - __uuidof(ID3D12Resource), &m_gpuTexs[0])); - - CD3DX12_RESOURCE_DESC dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, m_width, m_height, 1, 0, 1, - 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); - ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, - &dsvresdesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_D24_UNORM_S8_UINT, 1.0, 0), - __uuidof(ID3D12Resource), &m_gpuTexs[1])); + __uuidof(ID3D12Resource), &m_gpuTex)); D3D12_DESCRIPTOR_HEAP_DESC rtvdesc = {D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&rtvdesc, __uuidof(ID3D12DescriptorHeap), &m_rtvHeap)); @@ -277,27 +258,33 @@ class D3D12TextureR : public ITextureR 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT); ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &rtvresdesc, D3D12_RESOURCE_STATE_RENDER_TARGET, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_R8G8B8A8_UNORM, BLACK_COLOR), - __uuidof(ID3D12Resource), &m_gpuMsaaTexs[0])); + __uuidof(ID3D12Resource), &m_gpuMsaaTex)); CD3DX12_RESOURCE_DESC dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, m_width, m_height, 1, 0, samples, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT); ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &dsvresdesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_D24_UNORM_S8_UINT, 1.0, 0), - __uuidof(ID3D12Resource), &m_gpuMsaaTexs[1])); + __uuidof(ID3D12Resource), &m_depthTex)); D3D12_RENDER_TARGET_VIEW_DESC rtvvdesc = {DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RTV_DIMENSION_TEXTURE2D}; - ctx->m_dev->CreateRenderTargetView(m_gpuMsaaTexs[0].Get(), &rtvvdesc, m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); + ctx->m_dev->CreateRenderTargetView(m_gpuMsaaTex.Get(), &rtvvdesc, m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, D3D12_DSV_DIMENSION_TEXTURE2D}; - ctx->m_dev->CreateDepthStencilView(m_gpuMsaaTexs[1].Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); + ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); } else { + CD3DX12_RESOURCE_DESC dsvresdesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D24_UNORM_S8_UINT, m_width, m_height, 1, 0, 1, + 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); + ThrowIfFailed(ctx->m_dev->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, + &dsvresdesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &CD3DX12_CLEAR_VALUE(DXGI_FORMAT_D24_UNORM_S8_UINT, 1.0, 0), + __uuidof(ID3D12Resource), &m_depthTex)); + D3D12_RENDER_TARGET_VIEW_DESC rtvvdesc = {DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RTV_DIMENSION_TEXTURE2D}; - ctx->m_dev->CreateRenderTargetView(m_gpuTexs[0].Get(), &rtvvdesc, m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); + ctx->m_dev->CreateRenderTargetView(m_gpuTex.Get(), &rtvvdesc, m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, D3D12_DSV_DIMENSION_TEXTURE2D}; - ctx->m_dev->CreateDepthStencilView(m_gpuTexs[1].Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); + ctx->m_dev->CreateDepthStencilView(m_depthTex.Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); } } @@ -309,8 +296,9 @@ class D3D12TextureR : public ITextureR } public: size_t samples() const {return m_samples;} - ComPtr m_gpuTexs[2]; - ComPtr m_gpuMsaaTexs[2]; + ComPtr m_gpuTex; + ComPtr m_gpuMsaaTex; + ComPtr m_depthTex; ComPtr m_rtvHeap; ComPtr m_dsvHeap; ~D3D12TextureR() = default; @@ -325,16 +313,9 @@ public: m_height = height; Setup(ctx, width, height, m_samples); } -}; -ITextureS* -D3D12DataFactory::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, - const void* data, size_t sz) -{ - D3D12TextureS* retval = new D3D12TextureS(m_ctx, width, height, mips, fmt, data, sz); - static_cast(m_deferredData)->m_STexs.emplace_back(retval); - return retval; -} + ID3D12Resource* getRenderColorRes() {if (m_samples > 1) return m_gpuMsaaTex.Get(); return m_gpuTex.Get();} +}; static const size_t SEMANTIC_SIZE_TABLE[] = { @@ -445,41 +426,6 @@ public: D3D12ShaderPipeline(const D3D12ShaderPipeline&) = delete; }; -#if _DEBUG -#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 -#else -#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 -#endif - -IShaderPipeline* D3D12DataFactory::newShaderPipeline -(const char* vertSource, const char* fragSource, - ComPtr& vertBlobOut, ComPtr& fragBlobOut, - IVertexFormat* vtxFmt, BlendFactor srcFac, BlendFactor dstFac, - bool depthTest, bool depthWrite, bool backfaceCulling) -{ - ComPtr errBlob; - - if (FAILED(D3DCompile(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main", - "vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob))) - { - Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer()); - return nullptr; - } - - if (FAILED(D3DCompile(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main", - "ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob))) - { - Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer()); - return nullptr; - } - - D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), - static_cast(vtxFmt), - srcFac, dstFac, depthTest, depthWrite, backfaceCulling); - static_cast(m_deferredData)->m_SPs.emplace_back(retval); - return retval; -} - static UINT64 PlaceBufferForGPU(IGraphicsBuffer* buf, D3D12Context* ctx, ID3D12Heap* gpuHeap, UINT64 offset) { if (buf->dynamic()) @@ -669,47 +615,6 @@ struct D3D12ShaderDataBinding : IShaderDataBinding } }; -IShaderDataBinding* -D3D12DataFactory::newShaderDataBinding(IShaderPipeline* pipeline, - IVertexFormat* vtxFormat, - IGraphicsBuffer* vbuf, IGraphicsBuffer* ibuf, - size_t ubufCount, IGraphicsBuffer** ubufs, - size_t texCount, ITexture** texs) -{ - D3D12ShaderDataBinding* retval = - new D3D12ShaderDataBinding(m_ctx, pipeline, vbuf, ibuf, ubufCount, ubufs, texCount, texs); - static_cast(m_deferredData)->m_SBinds.emplace_back(retval); - return retval; -} - -D3D12DataFactory::D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx) -: m_parent(parent), m_deferredData(new struct D3D12Data()), m_ctx(ctx) -{ - CD3DX12_DESCRIPTOR_RANGE ranges[] = - { - {D3D12_DESCRIPTOR_RANGE_TYPE_CBV, MAX_UNIFORM_COUNT, 0}, - {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, MAX_TEXTURE_COUNT, 0} - }; - CD3DX12_ROOT_PARAMETER rootParms[1]; - rootParms[0].InitAsDescriptorTable(2, ranges); - - ComPtr rsOutBlob; - ComPtr rsErrorBlob; - ThrowIfFailed(D3D12SerializeRootSignaturePROC( - &CD3DX12_ROOT_SIGNATURE_DESC(1, rootParms, 1, &CD3DX12_STATIC_SAMPLER_DESC(0), - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), - D3D_ROOT_SIGNATURE_VERSION_1, &rsOutBlob, &rsErrorBlob)); - - ThrowIfFailed(ctx->m_dev->CreateRootSignature(0, rsOutBlob->GetBufferPointer(), - rsOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), &ctx->m_rs)); -} - -void D3D12DataFactory::reset() -{ - delete static_cast(m_deferredData); - m_deferredData = new struct D3D12Data(); -} - static ID3D12GraphicsCommandList* WaitForLoadList(D3D12Context* ctx) { /* Wait for previous transaction to complete (if in progress) */ @@ -725,92 +630,6 @@ static ID3D12GraphicsCommandList* WaitForLoadList(D3D12Context* ctx) return ctx->m_loadlist.Get(); } -IGraphicsData* D3D12DataFactory::commit() -{ - D3D12Data* retval = static_cast(m_deferredData); - - /* Gather resource descriptions */ - std::vector descs; - descs.reserve(retval->m_SBufs.size() + retval->m_DBufs.size() * 2 + - retval->m_STexs.size() + retval->m_DTexs.size() * 2); - - for (std::unique_ptr& buf : retval->m_SBufs) - descs.push_back(buf->m_buf->GetDesc()); - - for (std::unique_ptr& buf : retval->m_DBufs) - { - descs.push_back(buf->m_bufs[0]->GetDesc()); - descs.push_back(buf->m_bufs[1]->GetDesc()); - } - - for (std::unique_ptr& tex : retval->m_STexs) - descs.push_back(tex->m_tex->GetDesc()); - - for (std::unique_ptr& tex : retval->m_DTexs) - { - descs.push_back(tex->m_texs[0]->GetDesc()); - descs.push_back(tex->m_texs[1]->GetDesc()); - } - - /* Calculate resources allocation */ - D3D12_RESOURCE_ALLOCATION_INFO allocInfo = - m_ctx->m_dev->GetResourceAllocationInfo(0, descs.size(), descs.data()); - - /* Create heap */ - ThrowIfFailed(m_ctx->m_dev->CreateHeap(&CD3DX12_HEAP_DESC(allocInfo, - D3D12_HEAP_TYPE_DEFAULT), __uuidof(ID3D12Heap), &retval->m_gpuHeap)); - ID3D12Heap* gpuHeap = retval->m_gpuHeap.Get(); - - /* Wait for previous transaction to complete */ - WaitForLoadList(m_ctx); - - /* Place resources */ - UINT64 offset = 0; - for (std::unique_ptr& buf : retval->m_SBufs) - offset = PlaceBufferForGPU(buf.get(), m_ctx, gpuHeap, offset); - - for (std::unique_ptr& buf : retval->m_DBufs) - offset = PlaceBufferForGPU(buf.get(), m_ctx, gpuHeap, offset); - - for (std::unique_ptr& tex : retval->m_STexs) - offset = PlaceTextureForGPU(tex.get(), m_ctx, gpuHeap, offset); - - for (std::unique_ptr& tex : retval->m_DTexs) - offset = PlaceTextureForGPU(tex.get(), m_ctx, gpuHeap, offset); - - /* Execute static uploads */ - ThrowIfFailed(m_ctx->m_loadlist->Close()); - ID3D12CommandList* list[] = {m_ctx->m_loadlist.Get()}; - m_ctx->m_loadq->ExecuteCommandLists(1, list); - ++m_ctx->m_loadfenceval; - ThrowIfFailed(m_ctx->m_loadq->Signal(m_ctx->m_loadfence.Get(), m_ctx->m_loadfenceval)); - - WaitForLoadList(m_ctx); - - /* Commit data bindings (create descriptor heaps) */ - for (std::unique_ptr& bind : retval->m_SBinds) - bind->commit(m_ctx); - - /* All set! */ - m_deferredData = new struct D3D12Data(); - m_committedData.insert(retval); - return retval; -} - -void D3D12DataFactory::destroyData(IGraphicsData* d) -{ - D3D12Data* data = static_cast(d); - m_committedData.erase(data); - delete data; -} - -void D3D12DataFactory::destroyAllData() -{ - for (IGraphicsData* data : m_committedData) - delete static_cast(data); - m_committedData.clear(); -} - struct D3D12CommandQueue : IGraphicsCommandQueue { Platform platform() const {return IGraphicsDataFactory::PlatformD3D12;} @@ -867,13 +686,13 @@ struct D3D12CommandQueue : IGraphicsCommandQueue D3D12TextureR* ctarget = static_cast(target); if (m_boundTarget) - m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_boundTarget->m_gpuTexs[0].Get(), + m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_boundTarget->getRenderColorRes(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); m_cmdList->OMSetRenderTargets(1, &ctarget->m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), false, &ctarget->m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); - m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ctarget->m_gpuTexs[0].Get(), + m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ctarget->getRenderColorRes(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); m_boundTarget = ctarget; @@ -966,7 +785,7 @@ struct D3D12CommandQueue : IGraphicsCommandQueue if (csource->m_samples > 1) { - ID3D12Resource* src = csource->m_gpuMsaaTexs[0].Get(); + ID3D12Resource* src = csource->m_gpuMsaaTex.Get(); D3D12_RESOURCE_BARRIER msaaSetup[] = { @@ -990,7 +809,7 @@ struct D3D12CommandQueue : IGraphicsCommandQueue } else { - ID3D12Resource* src = csource->m_gpuTexs[0].Get(); + ID3D12Resource* src = csource->m_gpuTex.Get(); D3D12_RESOURCE_BARRIER copySetup[] = { @@ -1022,6 +841,7 @@ struct D3D12CommandQueue : IGraphicsCommandQueue if (m_fence->GetCompletedValue() < m_submittedFenceVal) { /* Abandon this list (renderer too slow) */ + m_cmdList->Close(); resetCommandList(); m_doPresent = false; return; @@ -1071,15 +891,6 @@ void D3D12GraphicsBufferD::unmap() res->Unmap(0, nullptr); } -IGraphicsBufferD* -D3D12DataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count) -{ - D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); - D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_ctx, stride, count); - static_cast(m_deferredData)->m_DBufs.emplace_back(retval); - return retval; -} - void D3D12TextureD::load(const void* data, size_t sz) { ID3D12Resource* res = m_texs[m_q->m_fillBuf].Get(); @@ -1101,32 +912,225 @@ void D3D12TextureD::unmap() res->Unmap(0, nullptr); } -ITextureD* -D3D12DataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) +class D3D12DataFactory : public ID3DDataFactory { - D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); - D3D12TextureD* retval = new D3D12TextureD(q, m_ctx, width, height, fmt); - static_cast(m_deferredData)->m_DTexs.emplace_back(retval); - return retval; -} + IGraphicsContext* m_parent; + IGraphicsData* m_deferredData = nullptr; + struct D3D12Context* m_ctx; + std::unordered_set m_committedData; +public: + D3D12DataFactory(IGraphicsContext* parent, D3D12Context* ctx) + : m_parent(parent), m_deferredData(new struct D3D12Data()), m_ctx(ctx) + { + CD3DX12_DESCRIPTOR_RANGE ranges[] = + { + {D3D12_DESCRIPTOR_RANGE_TYPE_CBV, MAX_UNIFORM_COUNT, 0}, + {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, MAX_TEXTURE_COUNT, 0} + }; + CD3DX12_ROOT_PARAMETER rootParms[1]; + rootParms[0].InitAsDescriptorTable(2, ranges); -ITextureR* -D3D12DataFactory::newRenderTexture(size_t width, size_t height, size_t samples) -{ - D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); - D3D12TextureR* retval = new D3D12TextureR(m_ctx, width, height, samples); - static_cast(m_deferredData)->m_RTexs.emplace_back(retval); - return retval; -} + ComPtr rsOutBlob; + ComPtr rsErrorBlob; + ThrowIfFailed(D3D12SerializeRootSignaturePROC( + &CD3DX12_ROOT_SIGNATURE_DESC(1, rootParms, 1, &CD3DX12_STATIC_SAMPLER_DESC(0), + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), + D3D_ROOT_SIGNATURE_VERSION_1, &rsOutBlob, &rsErrorBlob)); -IVertexFormat* D3D12DataFactory::newVertexFormat -(size_t elementCount, const VertexElementDescriptor* elements) -{ - D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); - D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements); - static_cast(m_deferredData)->m_VFmts.emplace_back(retval); - return retval; -} + ThrowIfFailed(ctx->m_dev->CreateRootSignature(0, rsOutBlob->GetBufferPointer(), + rsOutBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), &ctx->m_rs)); + } + ~D3D12DataFactory() = default; + + Platform platform() const {return PlatformD3D12;} + const char* platformName() const {return "Direct3D 12";} + + IGraphicsBufferS* newStaticBuffer(BufferUse use, const void* data, size_t stride, size_t count) + { + D3D12GraphicsBufferS* retval = new D3D12GraphicsBufferS(use, m_ctx, data, stride, count); + static_cast(m_deferredData)->m_SBufs.emplace_back(retval); + return retval; + } + + IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count) + { + D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_ctx, stride, count); + static_cast(m_deferredData)->m_DBufs.emplace_back(retval); + return retval; + } + + ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, + const void* data, size_t sz) + { + D3D12TextureS* retval = new D3D12TextureS(m_ctx, width, height, mips, fmt, data, sz); + static_cast(m_deferredData)->m_STexs.emplace_back(retval); + return retval; + } + + ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt) + { + D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D12TextureD* retval = new D3D12TextureD(q, m_ctx, width, height, fmt); + static_cast(m_deferredData)->m_DTexs.emplace_back(retval); + return retval; + } + + ITextureR* newRenderTexture(size_t width, size_t height, size_t samples) + { + D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D12TextureR* retval = new D3D12TextureR(m_ctx, width, height, samples); + static_cast(m_deferredData)->m_RTexs.emplace_back(retval); + return retval; + } + + IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements) + { + D3D12CommandQueue* q = static_cast(m_parent->getCommandQueue()); + D3D12VertexFormat* retval = new struct D3D12VertexFormat(elementCount, elements); + static_cast(m_deferredData)->m_VFmts.emplace_back(retval); + return retval; + } + +#if _DEBUG +#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0 +#else +#define BOO_D3DCOMPILE_FLAG D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + + IShaderPipeline* newShaderPipeline + (const char* vertSource, const char* fragSource, + ComPtr& vertBlobOut, ComPtr& fragBlobOut, + IVertexFormat* vtxFmt, BlendFactor srcFac, BlendFactor dstFac, + bool depthTest, bool depthWrite, bool backfaceCulling) + { + ComPtr errBlob; + + if (FAILED(D3DCompile(vertSource, strlen(vertSource), "HECL Vert Source", nullptr, nullptr, "main", + "vs_5_0", BOO_D3DCOMPILE_FLAG, 0, &vertBlobOut, &errBlob))) + { + Log.report(LogVisor::FatalError, "error compiling vert shader: %s", errBlob->GetBufferPointer()); + return nullptr; + } + + if (FAILED(D3DCompile(fragSource, strlen(fragSource), "HECL Pixel Source", nullptr, nullptr, "main", + "ps_5_0", BOO_D3DCOMPILE_FLAG, 0, &fragBlobOut, &errBlob))) + { + Log.report(LogVisor::FatalError, "error compiling pixel shader: %s", errBlob->GetBufferPointer()); + return nullptr; + } + + D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_ctx, vertBlobOut.Get(), fragBlobOut.Get(), + static_cast(vtxFmt), + srcFac, dstFac, depthTest, depthWrite, backfaceCulling); + static_cast(m_deferredData)->m_SPs.emplace_back(retval); + return retval; + } + + IShaderDataBinding* newShaderDataBinding(IShaderPipeline* pipeline, + IVertexFormat* vtxFormat, + IGraphicsBuffer* vbuf, IGraphicsBuffer* ibuf, + size_t ubufCount, IGraphicsBuffer** ubufs, + size_t texCount, ITexture** texs) + { + D3D12ShaderDataBinding* retval = + new D3D12ShaderDataBinding(m_ctx, pipeline, vbuf, ibuf, ubufCount, ubufs, texCount, texs); + static_cast(m_deferredData)->m_SBinds.emplace_back(retval); + return retval; + } + + void reset() + { + delete static_cast(m_deferredData); + m_deferredData = new struct D3D12Data(); + } + + IGraphicsData* commit() + { + D3D12Data* retval = static_cast(m_deferredData); + + /* Gather resource descriptions */ + std::vector descs; + descs.reserve(retval->m_SBufs.size() + retval->m_DBufs.size() * 2 + + retval->m_STexs.size() + retval->m_DTexs.size() * 2); + + for (std::unique_ptr& buf : retval->m_SBufs) + descs.push_back(buf->m_buf->GetDesc()); + + for (std::unique_ptr& buf : retval->m_DBufs) + { + descs.push_back(buf->m_bufs[0]->GetDesc()); + descs.push_back(buf->m_bufs[1]->GetDesc()); + } + + for (std::unique_ptr& tex : retval->m_STexs) + descs.push_back(tex->m_tex->GetDesc()); + + for (std::unique_ptr& tex : retval->m_DTexs) + { + descs.push_back(tex->m_texs[0]->GetDesc()); + descs.push_back(tex->m_texs[1]->GetDesc()); + } + + /* Calculate resources allocation */ + D3D12_RESOURCE_ALLOCATION_INFO allocInfo = + m_ctx->m_dev->GetResourceAllocationInfo(0, descs.size(), descs.data()); + + /* Create heap */ + ThrowIfFailed(m_ctx->m_dev->CreateHeap(&CD3DX12_HEAP_DESC(allocInfo, + D3D12_HEAP_TYPE_DEFAULT), __uuidof(ID3D12Heap), &retval->m_gpuHeap)); + ID3D12Heap* gpuHeap = retval->m_gpuHeap.Get(); + + /* Wait for previous transaction to complete */ + WaitForLoadList(m_ctx); + + /* Place resources */ + UINT64 offset = 0; + for (std::unique_ptr& buf : retval->m_SBufs) + offset = PlaceBufferForGPU(buf.get(), m_ctx, gpuHeap, offset); + + for (std::unique_ptr& buf : retval->m_DBufs) + offset = PlaceBufferForGPU(buf.get(), m_ctx, gpuHeap, offset); + + for (std::unique_ptr& tex : retval->m_STexs) + offset = PlaceTextureForGPU(tex.get(), m_ctx, gpuHeap, offset); + + for (std::unique_ptr& tex : retval->m_DTexs) + offset = PlaceTextureForGPU(tex.get(), m_ctx, gpuHeap, offset); + + /* Execute static uploads */ + ThrowIfFailed(m_ctx->m_loadlist->Close()); + ID3D12CommandList* list[] = {m_ctx->m_loadlist.Get()}; + m_ctx->m_loadq->ExecuteCommandLists(1, list); + ++m_ctx->m_loadfenceval; + ThrowIfFailed(m_ctx->m_loadq->Signal(m_ctx->m_loadfence.Get(), m_ctx->m_loadfenceval)); + + WaitForLoadList(m_ctx); + + /* Commit data bindings (create descriptor heaps) */ + for (std::unique_ptr& bind : retval->m_SBinds) + bind->commit(m_ctx); + + /* All set! */ + m_deferredData = new struct D3D12Data(); + m_committedData.insert(retval); + return retval; + } + + void destroyData(IGraphicsData* d) + { + D3D12Data* data = static_cast(d); + m_committedData.erase(data); + delete data; + } + + void destroyAllData() + { + for (IGraphicsData* data : m_committedData) + delete static_cast(data); + m_committedData.clear(); + } +}; IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent, ID3D12CommandQueue** cmdQueueOut) @@ -1134,4 +1138,11 @@ IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Wi return new struct D3D12CommandQueue(ctx, windowCtx, parent, cmdQueueOut); } +IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent) +{ + return new D3D12DataFactory(parent, ctx); } + +} + +#endif // _WIN32_WINNT_WIN10 diff --git a/lib/graphicsdev/d3dx12.h b/lib/graphicsdev/d3dx12.h index de0fbdf..d064b67 100644 --- a/lib/graphicsdev/d3dx12.h +++ b/lib/graphicsdev/d3dx12.h @@ -1485,6 +1485,106 @@ inline UINT64 UpdateSubresources( return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); } +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 PrepSubresources( + _In_ ID3D12Device* pDevice, + _In_ D3D12_RESOURCE_DESC& DestinationDesc, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > (SIZE_T)-1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template +inline UINT64 PrepSubresources( + _In_ ID3D12Device* pDevice, + _In_ D3D12_RESOURCE_DESC& DestinationDesc, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + pDevice->GetCopyableFootprints(&DestinationDesc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + + return PrepSubresources(pDevice, DestinationDesc, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +template +inline void CommandSubresourcesTransfer( + _In_ ID3D12Device* pDevice, + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + + if (Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox( UINT( Layouts[0].Offset ), UINT( Layouts[0].Offset + Layouts[0].Footprint.Width ) ); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, Layouts[0].Offset, Layouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, Layouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } +} + //------------------------------------------------------------------------------------------------ inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) { return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } diff --git a/lib/win/ApplicationWin32.cpp b/lib/win/ApplicationWin32.cpp index 4292b09..9fc3dc3 100644 --- a/lib/win/ApplicationWin32.cpp +++ b/lib/win/ApplicationWin32.cpp @@ -19,7 +19,9 @@ #include static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +#if _WIN32_WINNT_WIN10 PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr; +#endif namespace boo { @@ -69,7 +71,7 @@ public: Log.report(LogVisor::FatalError, "unable to find CreateDXGIFactory2 in DXGI.dll\n" "Windows 7 users should install \"Platform Update for Windows 7\" from Microsoft"); -#if WINVER >= _WIN32_WINNT_WIN10 +#if _WIN32_WINNT_WIN10 HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll"); if (d3d12lib) { @@ -154,6 +156,9 @@ public: device->GetParent(__uuidof(IDXGIAdapter), &adapter); adapter->GetParent(__uuidof(IDXGIFactory2), &m_d3dCtx.m_ctx11.m_dxFactory); + /* Build default sampler here */ + m_d3dCtx.m_ctx11.m_dev->CreateSamplerState(&CD3D11_SAMPLER_DESC(D3D11_DEFAULT), &m_d3dCtx.m_ctx11.m_ss); + return; } @@ -178,7 +183,9 @@ public: return DeviceFinder::winDevChangedHandler(wParam, lParam); case WM_SIZE: + case WM_SYSKEYDOWN: case WM_KEYDOWN: + case WM_SYSKEYUP: case WM_KEYUP: case WM_LBUTTONDOWN: case WM_LBUTTONUP: diff --git a/lib/win/Win32Common.hpp b/lib/win/Win32Common.hpp index ed5b87f..9a74f92 100644 --- a/lib/win/Win32Common.hpp +++ b/lib/win/Win32Common.hpp @@ -10,7 +10,7 @@ #include #include -#include "boo/System.hpp" +#include "boo/IWindow.hpp" namespace boo {class IWindow;} @@ -39,7 +39,7 @@ struct D3D12Context bool m_needsResize = false; size_t width, height; }; - std::unordered_map m_windows; + std::unordered_map m_windows; }; #elif _WIN32_WINNT_WIN7 @@ -54,13 +54,14 @@ struct D3D11Context ComPtr m_dxFactory; ComPtr m_dev; ComPtr m_devCtx; + ComPtr m_ss; struct Window { - IDXGISwapChain1* m_swapChain; + ComPtr m_swapChain; bool m_needsResize = false; size_t width, height; }; - std::unordered_map m_windows; + std::unordered_map m_windows; }; struct D3DAppContext @@ -75,16 +76,94 @@ struct D3DAppContext #if _WIN32_WINNT_WIN10 if (m_ctx12.m_dev) { - m_ctx12.m_windows[window].width = width; - m_ctx12.m_windows[window].height = height; - m_ctx12.m_windows[window].m_needsResize = true; + D3D12Context::Window& win = m_ctx12.m_windows[window]; + win.width = width; + win.height = height; + win.m_needsResize = true; } else #endif { - m_ctx11.m_windows[window].width = width; - m_ctx11.m_windows[window].height = height; - m_ctx11.m_windows[window].m_needsResize = true; + D3D11Context::Window& win = m_ctx11.m_windows[window]; + win.width = width; + win.height = height; + win.m_needsResize = true; + } + } + + bool isFullscreen(const boo::IWindow* window) + { +#if _WIN32_WINNT_WIN10 + if (m_ctx12.m_dev) + { + D3D12Context::Window& win = m_ctx12.m_windows[window]; + BOOL isFScr; + win.m_swapChain->GetFullscreenState(&isFScr, nullptr); + return isFScr; + } + else +#endif + { + D3D11Context::Window& win = m_ctx11.m_windows[window]; + BOOL isFScr; + win.m_swapChain->GetFullscreenState(&isFScr, nullptr); + return isFScr; + } + } + + bool setFullscreen(boo::IWindow* window, bool fs) + { +#if _WIN32_WINNT_WIN10 + if (m_ctx12.m_dev) + { + D3D12Context::Window& win = m_ctx12.m_windows[window]; + BOOL isFScr; + win.m_swapChain->GetFullscreenState(&isFScr, nullptr); + if (fs && isFScr) + return false; + else if (!fs && !isFScr) + return false; + + if (fs) + { + ComPtr out; + win.m_swapChain->GetContainingOutput(&out); + DXGI_OUTPUT_DESC outDesc; + out->GetDesc(&outDesc); + + win.m_swapChain->SetFullscreenState(true, nullptr); + DXGI_MODE_DESC mdesc = {outDesc.DesktopCoordinates.right, outDesc.DesktopCoordinates.bottom}; + win.m_swapChain->ResizeTarget(&mdesc); + } + else + win.m_swapChain->SetFullscreenState(false, nullptr); + return true; + } + else +#endif + { + D3D11Context::Window& win = m_ctx11.m_windows[window]; + BOOL isFScr; + win.m_swapChain->GetFullscreenState(&isFScr, nullptr); + if (fs && isFScr) + return false; + else if (!fs && !isFScr) + return false; + + if (fs) + { + ComPtr out; + win.m_swapChain->GetContainingOutput(&out); + DXGI_OUTPUT_DESC outDesc; + out->GetDesc(&outDesc); + + win.m_swapChain->SetFullscreenState(true, nullptr); + DXGI_MODE_DESC mdesc = {outDesc.DesktopCoordinates.right, outDesc.DesktopCoordinates.bottom}; + win.m_swapChain->ResizeTarget(&mdesc); + } + else + win.m_swapChain->SetFullscreenState(false, nullptr); + return true; } } }; diff --git a/lib/win/WindowWin32.cpp b/lib/win/WindowWin32.cpp index 6a6713d..fefb02c 100644 --- a/lib/win/WindowWin32.cpp +++ b/lib/win/WindowWin32.cpp @@ -4,15 +4,18 @@ #include "boo/IGraphicsContext.hpp" #include -#include "boo/graphicsdev/D3D11.hpp" -#include "boo/graphicsdev/D3D12.hpp" +#include "boo/graphicsdev/D3D.hpp" namespace boo { static LogVisor::LogModule Log("WindowWin32"); +#if _WIN32_WINNT_WIN10 IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent, ID3D12CommandQueue** cmdQueueOut); +IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent); +#endif IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent); +IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent); struct GraphicsContextWin32 : IGraphicsContext { @@ -53,14 +56,15 @@ public: D3D12Context::Window& w = insIt.first->second; ID3D12CommandQueue* cmdQueue; - m_dataFactory = new D3D12DataFactory(this, &d3dCtx.m_ctx12); + m_dataFactory = _NewD3D12DataFactory(&d3dCtx.m_ctx12, this); m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, &w, this, &cmdQueue); - scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; HRESULT hr = d3dCtx.m_ctx12.m_dxFactory->CreateSwapChainForHwnd(cmdQueue, hwnd, &scDesc, nullptr, nullptr, &m_swapChain); if (FAILED(hr)) Log.report(LogVisor::FatalError, "unable to create swap chain"); + d3dCtx.m_ctx12.m_dxFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); m_swapChain.As(&w.m_swapChain); ComPtr fb; @@ -73,22 +77,23 @@ public: else #endif { -#if 0 if (FAILED(d3dCtx.m_ctx11.m_dxFactory->CreateSwapChainForHwnd(d3dCtx.m_ctx11.m_dev.Get(), hwnd, &scDesc, nullptr, nullptr, &m_swapChain))) Log.report(LogVisor::FatalError, "unable to create swap chain"); + d3dCtx.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())); D3D11Context::Window& w = insIt.first->second; + + m_swapChain.As(&w.m_swapChain); ComPtr fbRes; m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &fbRes); D3D11_TEXTURE2D_DESC resDesc; fbRes->GetDesc(&resDesc); w.width = resDesc.Width; w.height = resDesc.Height; - m_dataFactory = new D3D11DataFactory(this, &d3dCtx.m_ctx11); + m_dataFactory = _NewD3D11DataFactory(&d3dCtx.m_ctx11, this); m_commandQueue = _NewD3D11CommandQueue(&d3dCtx.m_ctx11, &insIt.first->second, this); -#endif } if (FAILED(m_swapChain->GetContainingOutput(&m_output))) @@ -99,13 +104,10 @@ public: { #if _WIN32_WINNT_WIN10 if (m_d3dCtx.m_ctx12.m_dev) - { m_d3dCtx.m_ctx12.m_windows.erase(m_parentWindow); - } else #endif - { - } + m_d3dCtx.m_ctx11.m_windows.erase(m_parentWindow); } void _setCallback(IWindowCallback* cb) @@ -208,7 +210,7 @@ static uint32_t translateKeysym(WPARAM sym, int& specialSym, int& modifierSym) return 0; } -static int translateModifiers() +static int translateModifiers(UINT msg) { int retval = 0; if (GetKeyState(VK_LSHIFT) & 0x8000 != 0 || GetKeyState(VK_RSHIFT) & 0x8000 != 0) @@ -217,6 +219,8 @@ static int translateModifiers() retval |= MKEY_CTRL; if (GetKeyState(VK_MENU) & 0x8000 != 0) retval |= MKEY_ALT; + if (msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) + retval |= MKEY_ALT; return retval; } @@ -315,12 +319,12 @@ public: bool isFullscreen() const { - return false; + return m_gfxCtx->m_d3dCtx.isFullscreen(this); } void setFullscreen(bool fs) { - + m_gfxCtx->m_d3dCtx.setFullscreen(this, fs); } void waitForRetrace() @@ -339,7 +343,7 @@ public: { int x, y, w, h; getWindowFrame(x, y, w, h); - int modifierMask = translateModifiers(); + int modifierMask = translateModifiers(e.uMsg); SWindowCoord coord = { {(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)}, @@ -356,7 +360,7 @@ public: { int x, y, w, h; getWindowFrame(x, y, w, h); - int modifierMask = translateModifiers(); + int modifierMask = translateModifiers(e.uMsg); SWindowCoord coord = { {(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)}, @@ -384,13 +388,14 @@ public: return; } case WM_KEYDOWN: + case WM_SYSKEYDOWN: { if (m_callback) { int specialKey; int modifierKey; uint32_t charCode = translateKeysym(e.wParam, specialKey, modifierKey); - int modifierMask = translateModifiers(); + int modifierMask = translateModifiers(e.uMsg); if (charCode) m_callback->charKeyDown(charCode, EModifierKey(modifierMask), e.lParam & 0xffff != 0); else if (specialKey) @@ -401,13 +406,14 @@ public: return; } case WM_KEYUP: + case WM_SYSKEYUP: { if (m_callback) { int specialKey; int modifierKey; uint32_t charCode = translateKeysym(e.wParam, specialKey, modifierKey); - int modifierMask = translateModifiers(); + int modifierMask = translateModifiers(e.uMsg); if (charCode) m_callback->charKeyUp(charCode, EModifierKey(modifierMask)); else if (specialKey) @@ -488,6 +494,41 @@ public: return TOUCH_NONE; } + void setStyle(EWindowStyle style) + { + LONG sty = GetWindowLong(m_hwnd, GWL_STYLE); + + if (style & STYLE_TITLEBAR) + sty |= WS_CAPTION; + else + sty &= ~WS_CAPTION; + + if (style & STYLE_RESIZE) + sty |= WS_THICKFRAME; + else + sty &= ~WS_THICKFRAME; + + if (style & STYLE_CLOSE) + sty |= (WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); + else + sty &= ~(WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); + + SetWindowLong(m_hwnd, GWL_STYLE, sty); + } + + EWindowStyle getStyle() const + { + LONG sty = GetWindowLong(m_hwnd, GWL_STYLE); + unsigned retval = STYLE_NONE; + if (sty & WS_CAPTION != 0) + retval |= STYLE_TITLEBAR; + if (sty & WS_THICKFRAME != 0) + retval |= STYLE_RESIZE; + if (sty & WS_SYSMENU) + retval |= STYLE_CLOSE; + return EWindowStyle(retval); + } + IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); diff --git a/test/main.cpp b/test/main.cpp index 5fa6e7a..9e28103 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -7,13 +7,8 @@ #include #include -#if _WIN32_WINNT_WIN10 -#include -#include -#elif _WIN32_WINNT_WIN7 -#include -#elif _WIN32 -#error unsupported windows version +#if _WIN32 +#include #endif namespace boo @@ -310,10 +305,11 @@ struct TestApplicationCallback : IApplicationCallback pipeline = glF->newShaderPipeline(VS, FS, 1, TexNames, BlendFactorOne, BlendFactorZero, true, true, false); } -#if _WIN32_WINNT_WIN10 - else if (factory->platform() == IGraphicsDataFactory::PlatformD3D12) +#if _WIN32 + else if (factory->platform() == IGraphicsDataFactory::PlatformD3D12 || + factory->platform() == IGraphicsDataFactory::PlatformD3D11) { - D3D12DataFactory* d3dF = dynamic_cast(factory); + ID3DDataFactory* d3dF = dynamic_cast(factory); static const char* VS = "struct VertData {float3 in_pos : POSITION; float2 in_uv : UV;};\n" @@ -456,6 +452,16 @@ struct TestApplicationCallback : IApplicationCallback } +int main(int argc, const boo::SystemChar** argv) +{ + LogVisor::RegisterConsoleLogger(); + boo::TestApplicationCallback appCb; + int ret = ApplicationRun(boo::IApplication::PLAT_AUTO, + appCb, _S("rwk"), _S("RWK"), argc, argv); + printf("IM DYING!!\n"); + return ret; +} + #if _WIN32 int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) { @@ -463,23 +469,10 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) const boo::SystemChar** argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc)); LogVisor::CreateWin32Console(); - LogVisor::RegisterConsoleLogger(); - boo::TestApplicationCallback appCb; - int ret = ApplicationRun(boo::IApplication::PLAT_AUTO, - appCb, _S("rwk"), _S("RWK"), argc, argv); - printf("IM DYING!!\n"); - return ret; + return main(argc, argv); } #else -int main(int argc, const char** argv) -{ - LogVisor::RegisterConsoleLogger(); - boo::TestApplicationCallback appCb; - int ret = ApplicationRun(boo::IApplication::PLAT_AUTO, - appCb, _S("rwk"), _S("RWK"), argc, argv); - printf("IM DYING!!\n"); - return ret; -} + #endif