diff options
| author | Yong He <yonghe@outlook.com> | 2021-03-10 10:58:15 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-10 10:58:15 -0800 |
| commit | 6ef4054f8a8aea4ec61481057fa7e16aaecde6d7 (patch) | |
| tree | 66edcae112faff7276c2595865463698bde277fd /tools | |
| parent | 2765861cdc104e6104a31cf9e20800b8d1dfae26 (diff) | |
Swapchain resize and rename to `IDevice` (#1741)
* Swapchain resize
* Fix.
Diffstat (limited to 'tools')
30 files changed, 1244 insertions, 1261 deletions
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index 47738068e..ec7edf00a 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -435,20 +435,20 @@ public: List<RefPtr<CUDAResourceView>> resources; virtual SLANG_NO_THROW Result SLANG_MCALL - init(IRenderer* renderer, CUDAShaderObjectLayout* typeLayout); + init(IDevice* device, CUDAShaderObjectLayout* typeLayout); CUDAShaderObjectLayout* getLayout() { return static_cast<CUDAShaderObjectLayout*>(m_layout.Ptr()); } - virtual SLANG_NO_THROW Result SLANG_MCALL initBuffer(IRenderer* renderer, size_t bufferSize) + virtual SLANG_NO_THROW Result SLANG_MCALL initBuffer(IDevice* device, size_t bufferSize) { BufferResource::Desc bufferDesc; bufferDesc.init(bufferSize); bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; ComPtr<IBufferResource> constantBuffer; - SLANG_RETURN_ON_FAIL(renderer->createBufferResource( + SLANG_RETURN_ON_FAIL(device->createBufferResource( IResource::Usage::ConstantBuffer, bufferDesc, nullptr, constantBuffer.writeRef())); bufferResource = dynamic_cast<MemoryCUDAResource*>(constantBuffer.get()); return SLANG_OK; @@ -737,8 +737,9 @@ public: void* hostBuffer = nullptr; size_t uniformBufferSize = 0; // Override buffer allocation so we store all uniform data on host memory instead of device memory. - virtual SLANG_NO_THROW Result SLANG_MCALL initBuffer(IRenderer* renderer, size_t bufferSize) override + virtual SLANG_NO_THROW Result SLANG_MCALL initBuffer(IDevice* device, size_t bufferSize) override { + SLANG_UNUSED(device); uniformBufferSize = bufferSize; hostBuffer = malloc(bufferSize); return SLANG_OK; @@ -789,7 +790,7 @@ class CUDARootShaderObject : public CUDAShaderObject public: List<RefPtr<CUDAEntryPointShaderObject>> entryPointObjects; virtual SLANG_NO_THROW Result SLANG_MCALL - init(IRenderer* renderer, CUDAShaderObjectLayout* typeLayout) override; + init(IDevice* device, CUDAShaderObjectLayout* typeLayout) override; virtual SLANG_NO_THROW UInt SLANG_MCALL getEntryPointCount() override { return entryPointObjects.getCount(); } virtual SLANG_NO_THROW Result SLANG_MCALL getEntryPoint(UInt index, IShaderObject** outEntryPoint) override @@ -836,7 +837,7 @@ public: } }; -class CUDARenderer : public RendererBase +class CUDADevice : public RendererBase { private: static const CUDAReportStyle reportType = CUDAReportStyle::Normal; @@ -956,6 +957,8 @@ private: int m_deviceIndex = -1; CUdevice m_device = 0; CUcontext m_context = nullptr; + DeviceInfo m_info; + String m_adapterName; public: class CommandQueueImpl; @@ -1117,11 +1120,11 @@ public: public: RefPtr<CUDAPipelineState> currentPipeline; RefPtr<CUDARootShaderObject> currentRootObject; - RefPtr<CUDARenderer> renderer; + RefPtr<CUDADevice> renderer; CUstream stream; Desc m_desc; public: - void init(CUDARenderer* inRenderer) + void init(CUDADevice* inRenderer) { renderer = inRenderer; m_desc.type = ICommandQueue::QueueType::Graphics; @@ -1314,7 +1317,7 @@ public: }; public: - ~CUDARenderer() + ~CUDADevice() { if (m_context) { @@ -1341,6 +1344,21 @@ public: SLANG_CUDA_RETURN_ON_FAIL(cuDeviceGet(&m_device, m_deviceIndex)); SLANG_CUDA_RETURN_WITH_REPORT_ON_FAIL(cuCtxCreate(&m_context, 0, m_device), reportType); + + // Initialize DeviceInfo + { + m_info.deviceType = DeviceType::CUDA; + m_info.bindingStyle = BindingStyle::CUDA; + m_info.projectionStyle = ProjectionStyle::DirectX; + m_info.apiName = "CUDA"; + static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + ::memcpy(m_info.identityProjectionMatrix, kIdentity, sizeof(kIdentity)); + cudaDeviceProp deviceProperties; + cudaGetDeviceProperties(&deviceProperties, m_deviceIndex); + m_adapterName = deviceProperties.name; + m_info.adapterName = m_adapterName.begin(); + } + return SLANG_OK; } @@ -1883,7 +1901,7 @@ public: void* map(IBufferResource* buffer) { - return dynamic_cast<MemoryCUDAResource*>(buffer)->m_cudaMemory; + return static_cast<MemoryCUDAResource*>(buffer)->m_cudaMemory; } void unmap(IBufferResource* buffer) @@ -1891,9 +1909,9 @@ public: SLANG_UNUSED(buffer); } - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const override + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { - return RendererType::CUDA; + return m_info; } public: @@ -2021,7 +2039,7 @@ public: } }; -SlangResult CUDAShaderObject::init(IRenderer* renderer, CUDAShaderObjectLayout* typeLayout) +SlangResult CUDAShaderObject::init(IDevice* device, CUDAShaderObjectLayout* typeLayout) { m_layout = typeLayout; @@ -2038,7 +2056,7 @@ SlangResult CUDAShaderObject::init(IRenderer* renderer, CUDAShaderObjectLayout* size_t uniformSize = slangLayout->getSize(); if (uniformSize) { - initBuffer(renderer, uniformSize); + initBuffer(device, uniformSize); } // If the layout specifies that we have any sub-objects, then @@ -2068,7 +2086,7 @@ SlangResult CUDAShaderObject::init(IRenderer* renderer, CUDAShaderObjectLayout* for (Index i = 0; i < bindingRangeInfo.count; ++i) { RefPtr<CUDAShaderObject> subObject = new CUDAShaderObject(); - SLANG_RETURN_ON_FAIL(subObject->init(renderer, subObjectLayout)); + SLANG_RETURN_ON_FAIL(subObject->init(device, subObjectLayout)); objects[bindingRangeInfo.baseIndex + i] = subObject; ShaderOffset offset; offset.uniformOffset = bindingRangeInfo.uniformOffset + sizeof(void*) * i; @@ -2079,31 +2097,31 @@ SlangResult CUDAShaderObject::init(IRenderer* renderer, CUDAShaderObjectLayout* return SLANG_OK; } -SlangResult CUDARootShaderObject::init(IRenderer* renderer, CUDAShaderObjectLayout* typeLayout) +SlangResult CUDARootShaderObject::init(IDevice* device, CUDAShaderObjectLayout* typeLayout) { - SLANG_RETURN_ON_FAIL(CUDAShaderObject::init(renderer, typeLayout)); + SLANG_RETURN_ON_FAIL(CUDAShaderObject::init(device, typeLayout)); auto programLayout = dynamic_cast<CUDAProgramLayout*>(typeLayout); for (auto& entryPoint : programLayout->entryPointLayouts) { RefPtr<CUDAEntryPointShaderObject> object = new CUDAEntryPointShaderObject(); - SLANG_RETURN_ON_FAIL(object->init(renderer, entryPoint)); + SLANG_RETURN_ON_FAIL(object->init(device, entryPoint)); entryPointObjects.add(object); } return SLANG_OK; } -SlangResult SLANG_MCALL createCUDARenderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +SlangResult SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice) { - RefPtr<CUDARenderer> result = new CUDARenderer(); + RefPtr<CUDADevice> result = new CUDADevice(); SLANG_RETURN_ON_FAIL(result->initialize(*desc)); - *outRenderer = result.detach(); + *outDevice = result.detach(); return SLANG_OK; } #else -SlangResult SLANG_MCALL createCUDARenderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +SlangResult SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice) { SLANG_UNUSED(desc); - *outRenderer = nullptr; + *outDevice = nullptr; return SLANG_OK; } #endif diff --git a/tools/gfx/cuda/render-cuda.h b/tools/gfx/cuda/render-cuda.h index cd8482e37..5c477f513 100644 --- a/tools/gfx/cuda/render-cuda.h +++ b/tools/gfx/cuda/render-cuda.h @@ -5,5 +5,5 @@ namespace gfx { -SlangResult SLANG_MCALL createCUDARenderer(const IRenderer::Desc* desc, IRenderer** outRenderer); +SlangResult SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice); } diff --git a/tools/gfx/d3d/d3d-swapchain.cpp b/tools/gfx/d3d/d3d-swapchain.cpp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tools/gfx/d3d/d3d-swapchain.cpp diff --git a/tools/gfx/d3d/d3d-swapchain.h b/tools/gfx/d3d/d3d-swapchain.h new file mode 100644 index 000000000..5a9ead876 --- /dev/null +++ b/tools/gfx/d3d/d3d-swapchain.h @@ -0,0 +1,154 @@ +#pragma once + +#include "slang-gfx.h" +#include "core/slang-basic.h" +#include <dxgi1_4.h> +#include "../renderer-shared.h" +#include "d3d-util.h" + +namespace gfx +{ +class D3DSwapchainBase + : public ISwapchain + , public Slang::RefObject +{ +public: + SLANG_REF_OBJECT_IUNKNOWN_ALL + ISwapchain* getInterface(const Slang::Guid& guid) + { + if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISwapchain) + return static_cast<ISwapchain*>(this); + return nullptr; + } + +public: + Result init(const ISwapchain::Desc& desc, WindowHandle window, DXGI_SWAP_EFFECT swapEffect) + { + // Return fail on non-supported platforms. + switch (window.type) + { + case WindowHandle::Type::Win32Handle: + break; + default: + return SLANG_FAIL; + } + + m_desc = desc; + + // Describe the swap chain. + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = desc.imageCount; + swapChainDesc.BufferDesc.Width = desc.width; + swapChainDesc.BufferDesc.Height = desc.height; + swapChainDesc.BufferDesc.Format = D3DUtil::getMapFormat(desc.format); + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SwapEffect = swapEffect; + swapChainDesc.OutputWindow = (HWND)window.handleValues[0]; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.Windowed = TRUE; + + if (!desc.enableVSync) + { + swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + } + + // Swap chain needs the queue so that it can force a flush on it. + ComPtr<IDXGISwapChain> swapChain; + SLANG_RETURN_ON_FAIL( + getDXGIFactory()->CreateSwapChain(getOwningDevice(), &swapChainDesc, swapChain.writeRef())); + SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(m_swapChain.writeRef())); + + if (!desc.enableVSync) + { + m_swapChainWaitableObject = m_swapChain->GetFrameLatencyWaitableObject(); + + int maxLatency = desc.imageCount - 2; + + // Make sure the maximum latency is in the range required by dx runtime + maxLatency = (maxLatency < 1) ? 1 : maxLatency; + maxLatency = (maxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS) ? DXGI_MAX_SWAP_CHAIN_BUFFERS + : maxLatency; + + m_swapChain->SetMaximumFrameLatency(maxLatency); + } + + SLANG_RETURN_ON_FAIL(getDXGIFactory()->MakeWindowAssociation( + (HWND)window.handleValues[0], DXGI_MWA_NO_ALT_ENTER)); + + createSwapchainBufferImages(); + return SLANG_OK; + } + virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() override { return m_desc; } + virtual SLANG_NO_THROW Result SLANG_MCALL + getImage(uint32_t index, ITextureResource** outResource) override + { + m_images[index]->addRef(); + *outResource = m_images[index].get(); + return SLANG_OK; + } + virtual SLANG_NO_THROW Result SLANG_MCALL present() override + { + if (m_swapChainWaitableObject) + { + // check if now is good time to present + // This doesn't wait - because the wait time is 0. If it returns WAIT_TIMEOUT it + // means that no frame is waiting to be be displayed so there is no point doing a + // present. + const bool shouldPresent = + (WaitForSingleObjectEx(m_swapChainWaitableObject, 0, TRUE) != WAIT_TIMEOUT); + if (shouldPresent) + { + m_swapChain->Present(0, 0); + } + } + else + { + if (SLANG_FAILED(m_swapChain->Present(1, 0))) + { + return SLANG_FAIL; + } + } + return SLANG_OK; + } + + virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() override + { + uint32_t count; + m_swapChain->GetLastPresentCount(&count); + return (int)(count % m_desc.imageCount); + } + + + virtual SLANG_NO_THROW Result SLANG_MCALL resize(uint32_t width, uint32_t height) override + { + if (width == m_desc.width && height == m_desc.height) + return SLANG_OK; + + m_desc.width = width; + m_desc.height = height; + for (auto& image : m_images) + image = nullptr; + m_images.clear(); + auto result = m_swapChain->ResizeBuffers( + m_desc.imageCount, + width, + height, + D3DUtil::getMapFormat(m_desc.format), + m_desc.enableVSync ? 0 : DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT); + if (result != 0) + return SLANG_FAIL; + createSwapchainBufferImages(); + return SLANG_OK; + } + +public: + virtual void createSwapchainBufferImages() = 0; + virtual IDXGIFactory* getDXGIFactory() = 0; + virtual IUnknown* getOwningDevice() = 0; + ISwapchain::Desc m_desc; + HANDLE m_swapChainWaitableObject = nullptr; + ComPtr<IDXGISwapChain2> m_swapChain; + Slang::ShortList<ComPtr<ITextureResource>> m_images; +}; + +} diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index cf743fd72..b41169df2 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -8,6 +8,7 @@ //WORKING: #include "options.h" #include "../immediate-renderer-base.h" #include "../d3d/d3d-util.h" +#include "../d3d/d3d-swapchain.h" #include "../nvapi/nvapi-util.h" // In order to use the Slang API, we need to include its header @@ -50,7 +51,7 @@ using namespace Slang; namespace gfx { -class D3D11Renderer : public ImmediateRendererBase +class D3D11Device : public ImmediateRendererBase { public: enum @@ -59,7 +60,7 @@ public: kMaxRTVs = 8, }; - ~D3D11Renderer() {} + ~D3D11Device() {} // Renderer implementation virtual SLANG_NO_THROW SlangResult SLANG_MCALL initialize(const Desc& desc) override; @@ -152,9 +153,9 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) override; virtual SLANG_NO_THROW void SLANG_MCALL submitGpuWork() override {} virtual SLANG_NO_THROW void SLANG_MCALL waitForGpu() override {} - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const override + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { - return RendererType::DirectX11; + return m_info; } protected: @@ -163,11 +164,11 @@ protected: { public: ScopeNVAPI() : m_renderer(nullptr) {} - SlangResult init(D3D11Renderer* renderer, Index regIndex); + SlangResult init(D3D11Device* renderer, Index regIndex); ~ScopeNVAPI(); protected: - D3D11Renderer* m_renderer; + D3D11Device* m_renderer; }; #if 0 @@ -331,7 +332,7 @@ protected: UInt size, void const* data) override; - D3D11Renderer* m_renderer = nullptr; + D3D11Device* m_renderer = nullptr; RefPtr<DescriptorSetLayoutImpl> m_layout; @@ -481,134 +482,47 @@ protected: ID3D11DepthStencilView* d3dDepthStencilView; }; - class SwapchainImpl - : public ISwapchain - , public RefObject + class SwapchainImpl : public D3DSwapchainBase { public: - SLANG_REF_OBJECT_IUNKNOWN_ALL - ISwapchain* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISwapchain) - return static_cast<ISwapchain*>(this); - return nullptr; - } - - public: - Result init(D3D11Renderer* renderer, const ISwapchain::Desc& desc, WindowHandle window) + ComPtr<ID3D11Device> m_device; + ComPtr<IDXGIFactory> m_dxgiFactory; + D3D11Device* m_renderer; + Result init(D3D11Device* renderer, const ISwapchain::Desc& swapchainDesc, WindowHandle window) { - // Return fail on non-supported platforms. - switch (window.type) - { - case WindowHandle::Type::Win32Handle: - break; - default: - return SLANG_FAIL; - } - m_renderer = renderer; - m_desc = desc; - - // Describe the swap chain. - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferCount = desc.imageCount; - swapChainDesc.BufferDesc.Width = desc.width; - swapChainDesc.BufferDesc.Height = desc.height; - swapChainDesc.BufferDesc.Format = D3DUtil::getMapFormat(desc.format); - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - swapChainDesc.OutputWindow = (HWND)window.handleValues[0]; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.Windowed = TRUE; - - if (!desc.enableVSync) - { - swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - } - - // Swap chain needs the queue so that it can force a flush on it. - ComPtr<IDXGISwapChain> swapChain; - SLANG_RETURN_ON_FAIL(m_renderer->m_dxgiFactory->CreateSwapChain( - m_renderer->m_device, &swapChainDesc, swapChain.writeRef())); - SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(m_swapChain.writeRef())); - - if (!desc.enableVSync) - { - m_swapChainWaitableObject = m_swapChain->GetFrameLatencyWaitableObject(); - - int maxLatency = desc.imageCount - 2; - - // Make sure the maximum latency is in the range required by dx12 runtime - maxLatency = (maxLatency < 1) ? 1 : maxLatency; - maxLatency = (maxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS) - ? DXGI_MAX_SWAP_CHAIN_BUFFERS - : maxLatency; - - m_swapChain->SetMaximumFrameLatency(maxLatency); - } - - SLANG_RETURN_ON_FAIL(m_renderer->m_dxgiFactory->MakeWindowAssociation( - (HWND)window.handleValues[0], DXGI_MWA_NO_ALT_ENTER)); - - for (uint32_t i = 0; i < desc.imageCount; i++) - { - ComPtr<ID3D11Resource> d3dResource; - m_swapChain->GetBuffer(0, IID_PPV_ARGS(d3dResource.writeRef())); - ITextureResource::Desc imageDesc = {}; - imageDesc.init2D( - IResource::Type::Texture2D, desc.format, desc.width, desc.height, 0); - RefPtr<TextureResourceImpl> image = new TextureResourceImpl(imageDesc, IResource::Usage::RenderTarget); - image->m_resource = d3dResource; - m_images.add(image); - } - return SLANG_OK; - } - virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() override { return m_desc; } - virtual SLANG_NO_THROW Result - getImage(uint32_t index, ITextureResource** outResource) override - { - m_images[index]->addRef(); - *outResource = m_images[index].Ptr(); - return SLANG_OK; + m_device = renderer->m_device; + m_dxgiFactory = renderer->m_dxgiFactory; + return D3DSwapchainBase::init(swapchainDesc, window, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL); } - virtual SLANG_NO_THROW Result present() override + virtual void createSwapchainBufferImages() override { - if (m_swapChainWaitableObject) - { - // check if now is good time to present - // This doesn't wait - because the wait time is 0. If it returns WAIT_TIMEOUT it - // means that no frame is waiting to be be displayed so there is no point doing a - // present. - const bool shouldPresent = - (WaitForSingleObjectEx(m_swapChainWaitableObject, 0, TRUE) != WAIT_TIMEOUT); - if (shouldPresent) - { - m_swapChain->Present(0, 0); - } - } - else + m_images.clear(); + // D3D11 implements automatic back buffer rotation, so the application + // always render to buffer 0. + ComPtr<ID3D11Resource> d3dResource; + m_swapChain->GetBuffer(0, IID_PPV_ARGS(d3dResource.writeRef())); + ITextureResource::Desc imageDesc = {}; + imageDesc.init2D( + IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 0); + RefPtr<TextureResourceImpl> image = + new TextureResourceImpl(imageDesc, IResource::Usage::RenderTarget); + image->m_resource = d3dResource; + ComPtr<ITextureResource> imageResourcePtr; + imageResourcePtr = image.Ptr(); + for (uint32_t i = 0; i < m_desc.imageCount; i++) { - if (SLANG_FAILED(m_swapChain->Present(1, 0))) - { - return SLANG_FAIL; - } + m_images.add(imageResourcePtr); } - return SLANG_OK; } - - virtual SLANG_NO_THROW uint32_t acquireNextImage() override + virtual IDXGIFactory* getDXGIFactory() override { return m_dxgiFactory; } + virtual IUnknown* getOwningDevice() override { return m_device; } + virtual SLANG_NO_THROW Result SLANG_MCALL resize(uint32_t width, uint32_t height) override { - uint32_t count; - m_swapChain->GetLastPresentCount(&count); - return count % m_images.getCount(); + m_renderer->m_currentFramebuffer = nullptr; + m_renderer->m_immediateContext->ClearState(); + return D3DSwapchainBase::resize(width, height); } - - public: - D3D11Renderer* m_renderer = nullptr; - ISwapchain::Desc m_desc; - HANDLE m_swapChainWaitableObject = nullptr; - ComPtr<IDXGISwapChain2> m_swapChain; - ShortList<RefPtr<TextureResourceImpl>> m_images; }; class InputLayoutImpl: public IInputLayout, public RefObject @@ -668,6 +582,11 @@ protected: void _flushGraphicsState(); void _flushComputeState(); + // D3D11Device members. + + DeviceInfo m_info; + String m_adapterName; + ComPtr<IDXGISwapChain> m_swapChain; ComPtr<ID3D11Device> m_device; ComPtr<ID3D11DeviceContext> m_immediateContext; @@ -693,19 +612,19 @@ protected: bool m_nvapi = false; }; -SlangResult SLANG_MCALL createD3D11Renderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +SlangResult SLANG_MCALL createD3D11Device(const IDevice::Desc* desc, IDevice** outDevice) { - RefPtr<D3D11Renderer> result = new D3D11Renderer(); + RefPtr<D3D11Device> result = new D3D11Device(); SLANG_RETURN_ON_FAIL(result->initialize(*desc)); - *outRenderer = result.detach(); + *outDevice = result.detach(); return SLANG_OK; } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ScopeNVAPI !!!!!!!!!!!!!!!!!!!!!!!!!!!!! -SlangResult D3D11Renderer::ScopeNVAPI::init(D3D11Renderer* renderer, Index regIndex) +SlangResult D3D11Device::ScopeNVAPI::init(D3D11Device* device, Index regIndex) { - if (!renderer->m_nvapi) + if (!device->m_nvapi) { // There is nothing to set as nvapi is not set return SLANG_OK; @@ -720,11 +639,11 @@ SlangResult D3D11Renderer::ScopeNVAPI::init(D3D11Renderer* renderer, Index regIn #endif // Record the renderer so it can be freed - m_renderer = renderer; + m_renderer = device; return SLANG_OK; } -D3D11Renderer::ScopeNVAPI::~ScopeNVAPI() +D3D11Device::ScopeNVAPI::~ScopeNVAPI() { // If the m_renderer is not set, it must not have been set up if (m_renderer) @@ -737,7 +656,7 @@ D3D11Renderer::ScopeNVAPI::~ScopeNVAPI() } } -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!D3D11Renderer !!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!D3D11Device !!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!! @@ -754,12 +673,22 @@ static bool _isSupportedNVAPIOp(IUnknown* dev, uint32_t op) #endif } -SlangResult D3D11Renderer::initialize(const Desc& desc) +SlangResult D3D11Device::initialize(const Desc& desc) { SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_DXBC, "sm_5_0")); SLANG_RETURN_ON_FAIL(GraphicsAPIRenderer::initialize(desc)); + // Initialize DeviceInfo + { + m_info.deviceType = DeviceType::DirectX11; + m_info.bindingStyle = BindingStyle::DirectX; + m_info.projectionStyle = ProjectionStyle::DirectX; + m_info.apiName = "Direct3D 11"; + static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + ::memcpy(m_info.identityProjectionMatrix, kIdentity, sizeof(kIdentity)); + } + m_desc = desc; // Rather than statically link against D3D, we load it dynamically. @@ -877,6 +806,17 @@ SlangResult D3D11Renderer::initialize(const Desc& desc) } // Check we have a swap chain, context and device SLANG_ASSERT(m_immediateContext && m_device); + + ComPtr<IDXGIDevice> dxgiDevice; + if (m_device->QueryInterface(dxgiDevice.writeRef()) == 0) + { + ComPtr<IDXGIAdapter> dxgiAdapter; + dxgiDevice->GetAdapter(dxgiAdapter.writeRef()); + DXGI_ADAPTER_DESC adapterDesc; + dxgiAdapter->GetDesc(&adapterDesc); + m_adapterName = String::fromWString(adapterDesc.Description); + m_info.adapterName = m_adapterName.begin(); + } } // NVAPI @@ -908,7 +848,7 @@ SlangResult D3D11Renderer::initialize(const Desc& desc) return SLANG_OK; } -void D3D11Renderer::clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) +void D3D11Device::clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) { uint32_t mask = 1; for (auto rtv : m_currentFramebuffer->renderTargetViews) @@ -936,7 +876,7 @@ void D3D11Renderer::clearFrame(uint32_t colorBufferMask, bool clearDepth, bool c } } -Result D3D11Renderer::createSwapchain( +Result D3D11Device::createSwapchain( const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) { RefPtr<SwapchainImpl> swapchain = new SwapchainImpl(); @@ -945,7 +885,7 @@ Result D3D11Renderer::createSwapchain( return SLANG_OK; } -Result D3D11Renderer::createFramebufferLayout( +Result D3D11Device::createFramebufferLayout( const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) { RefPtr<FramebufferLayoutImpl> layout = new FramebufferLayoutImpl(); @@ -968,7 +908,7 @@ Result D3D11Renderer::createFramebufferLayout( return SLANG_OK; } -Result D3D11Renderer::createFramebuffer( +Result D3D11Device::createFramebuffer( const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) { RefPtr<FramebufferImpl> framebuffer = new FramebufferImpl(); @@ -985,19 +925,19 @@ Result D3D11Renderer::createFramebuffer( return SLANG_OK; } -void D3D11Renderer::setFramebuffer(IFramebuffer* frameBuffer) +void D3D11Device::setFramebuffer(IFramebuffer* frameBuffer) { m_framebufferBindingDirty = true; m_currentFramebuffer = static_cast<FramebufferImpl*>(frameBuffer); } -void D3D11Renderer::setStencilReference(uint32_t referenceValue) +void D3D11Device::setStencilReference(uint32_t referenceValue) { m_stencilRef = referenceValue; m_depthStencilStateDirty = true; } -SlangResult D3D11Renderer::readTextureResource( +SlangResult D3D11Device::readTextureResource( ITextureResource* resource, ResourceState state, ISlangBlob** outBlob, @@ -1117,7 +1057,7 @@ static int _calcResourceAccessFlags(int accessFlags) } } -Result D3D11Renderer::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) +Result D3D11Device::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) { TextureResource::Desc srcDesc(descIn); srcDesc.setDefaults(initialUsage); @@ -1244,7 +1184,7 @@ Result D3D11Renderer::createTextureResource(IResource::Usage initialUsage, const return SLANG_OK; } -Result D3D11Renderer::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result D3D11Device::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { IBufferResource::Desc srcDesc(descIn); srcDesc.setDefaults(initialUsage); @@ -1414,7 +1354,7 @@ static D3D11_COMPARISON_FUNC translateComparisonFunc(ComparisonFunc func) } } -Result D3D11Renderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) +Result D3D11Device::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) { D3D11_FILTER_REDUCTION_TYPE dxReduction = translateFilterReduction(desc.reductionOp); D3D11_FILTER dxFilter; @@ -1455,7 +1395,7 @@ Result D3D11Renderer::createSamplerState(ISamplerState::Desc const& desc, ISampl return SLANG_OK; } -Result D3D11Renderer::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) +Result D3D11Device::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (TextureResourceImpl*) texture; @@ -1523,7 +1463,7 @@ Result D3D11Renderer::createTextureView(ITextureResource* texture, IResourceView } } -Result D3D11Renderer::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) +Result D3D11Device::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (BufferResourceImpl*) buffer; auto resourceDesc = *resourceImpl->getDesc(); @@ -1613,7 +1553,7 @@ Result D3D11Renderer::createBufferView(IBufferResource* buffer, IResourceView::D } } -Result D3D11Renderer::createInputLayout(const InputElementDesc* inputElementsIn, UInt inputElementCount, IInputLayout** outLayout) +Result D3D11Device::createInputLayout(const InputElementDesc* inputElementsIn, UInt inputElementCount, IInputLayout** outLayout) { D3D11_INPUT_ELEMENT_DESC inputElements[16] = {}; @@ -1680,7 +1620,7 @@ Result D3D11Renderer::createInputLayout(const InputElementDesc* inputElementsIn, return SLANG_OK; } -void* D3D11Renderer::map(IBufferResource* bufferIn, MapFlavor flavor) +void* D3D11Device::map(IBufferResource* bufferIn, MapFlavor flavor) { BufferResourceImpl* bufferResource = static_cast<BufferResourceImpl*>(bufferIn); @@ -1723,7 +1663,7 @@ void* D3D11Renderer::map(IBufferResource* bufferIn, MapFlavor flavor) return mappedSub.pData; } -void D3D11Renderer::unmap(IBufferResource* bufferIn) +void D3D11Device::unmap(IBufferResource* bufferIn) { BufferResourceImpl* bufferResource = static_cast<BufferResourceImpl*>(bufferIn); ID3D11Buffer* buffer = (bufferResource->m_mapFlavor == MapFlavor::HostRead) ? bufferResource->m_staging : bufferResource->m_buffer; @@ -1731,19 +1671,19 @@ void D3D11Renderer::unmap(IBufferResource* bufferIn) } #if 0 -void D3D11Renderer::setInputLayout(InputLayout* inputLayoutIn) +void D3D11Device::setInputLayout(InputLayout* inputLayoutIn) { auto inputLayout = static_cast<InputLayoutImpl*>(inputLayoutIn); m_immediateContext->IASetInputLayout(inputLayout->m_layout); } #endif -void D3D11Renderer::setPrimitiveTopology(PrimitiveTopology topology) +void D3D11Device::setPrimitiveTopology(PrimitiveTopology topology) { m_immediateContext->IASetPrimitiveTopology(D3DUtil::getPrimitiveTopology(topology)); } -void D3D11Renderer::setVertexBuffers(UInt startSlot, UInt slotCount, IBufferResource*const* buffersIn, const UInt* stridesIn, const UInt* offsetsIn) +void D3D11Device::setVertexBuffers(UInt startSlot, UInt slotCount, IBufferResource*const* buffersIn, const UInt* stridesIn, const UInt* offsetsIn) { static const int kMaxVertexBuffers = 16; assert(slotCount <= kMaxVertexBuffers); @@ -1764,13 +1704,13 @@ void D3D11Renderer::setVertexBuffers(UInt startSlot, UInt slotCount, IBufferReso m_immediateContext->IASetVertexBuffers((UINT)startSlot, (UINT)slotCount, dxBuffers, &vertexStrides[0], &vertexOffsets[0]); } -void D3D11Renderer::setIndexBuffer(IBufferResource* buffer, Format indexFormat, UInt offset) +void D3D11Device::setIndexBuffer(IBufferResource* buffer, Format indexFormat, UInt offset) { DXGI_FORMAT dxFormat = D3DUtil::getMapFormat(indexFormat); m_immediateContext->IASetIndexBuffer(((BufferResourceImpl*)buffer)->m_buffer, dxFormat, UINT(offset)); } -void D3D11Renderer::setViewports(UInt count, Viewport const* viewports) +void D3D11Device::setViewports(UInt count, Viewport const* viewports) { static const int kMaxViewports = D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1; assert(count <= kMaxViewports); @@ -1792,7 +1732,7 @@ void D3D11Renderer::setViewports(UInt count, Viewport const* viewports) m_immediateContext->RSSetViewports(UINT(count), dxViewports); } -void D3D11Renderer::setScissorRects(UInt count, ScissorRect const* rects) +void D3D11Device::setScissorRects(UInt count, ScissorRect const* rects) { static const int kMaxScissorRects = D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1; assert(count <= kMaxScissorRects); @@ -1813,7 +1753,7 @@ void D3D11Renderer::setScissorRects(UInt count, ScissorRect const* rects) } -void D3D11Renderer::setPipelineState(IPipelineState* state) +void D3D11Device::setPipelineState(IPipelineState* state) { auto pipelineType = static_cast<PipelineStateBase*>(state)->desc.type; @@ -1882,19 +1822,19 @@ void D3D11Renderer::setPipelineState(IPipelineState* state) /// ... } -void D3D11Renderer::draw(UInt vertexCount, UInt startVertex) +void D3D11Device::draw(UInt vertexCount, UInt startVertex) { _flushGraphicsState(); m_immediateContext->Draw((UINT)vertexCount, (UINT)startVertex); } -void D3D11Renderer::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) +void D3D11Device::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) { _flushGraphicsState(); m_immediateContext->DrawIndexed((UINT)indexCount, (UINT)startIndex, (INT)baseVertex); } -Result D3D11Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) +Result D3D11Device::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) { @@ -2082,7 +2022,7 @@ D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask(RenderTargetWriteMaskT m return D3D11_COLOR_WRITE_ENABLE(result); } -Result D3D11Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) +Result D3D11Device::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) { GraphicsPipelineStateDesc desc = inDesc; preparePipelineDesc(desc); @@ -2212,7 +2152,7 @@ Result D3D11Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDes return SLANG_OK; } -Result D3D11Renderer::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) +Result D3D11Device::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) { ComputePipelineStateDesc desc = inDesc; preparePipelineDesc(desc); @@ -2223,7 +2163,7 @@ Result D3D11Renderer::createComputePipelineState(const ComputePipelineStateDesc& return SLANG_OK; } -void D3D11Renderer::copyBuffer( +void D3D11Device::copyBuffer( IBufferResource* dst, size_t dstOffset, IBufferResource* src, @@ -2240,13 +2180,13 @@ void D3D11Renderer::copyBuffer( dstImpl->m_buffer, 0, (UINT)dstOffset, 0, 0, srcImpl->m_buffer, 0, &srcBox); } -void D3D11Renderer::dispatchCompute(int x, int y, int z) +void D3D11Device::dispatchCompute(int x, int y, int z) { _flushComputeState(); m_immediateContext->Dispatch(x, y, z); } -Result D3D11Renderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) +Result D3D11Device::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) { RefPtr<DescriptorSetLayoutImpl> descriptorSetLayoutImpl = new DescriptorSetLayoutImpl(); @@ -2343,7 +2283,7 @@ Result D3D11Renderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc return SLANG_OK; } -Result D3D11Renderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) +Result D3D11Device::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) { RefPtr<PipelineLayoutImpl> pipelineLayoutImpl = new PipelineLayoutImpl(); @@ -2372,7 +2312,7 @@ Result D3D11Renderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IP return SLANG_OK; } -Result D3D11Renderer::createDescriptorSet(IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) +Result D3D11Device::createDescriptorSet(IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) { SLANG_UNUSED(flag); @@ -2434,7 +2374,7 @@ Result D3D11Renderer::createDescriptorSet(IDescriptorSetLayout* layout, IDescrip } -void D3D11Renderer::_flushGraphicsState() +void D3D11Device::_flushGraphicsState() { auto pipelineType = int(PipelineType::Graphics); if (m_framebufferBindingDirty || m_shaderBindingDirty) @@ -2465,7 +2405,7 @@ void D3D11Renderer::_flushGraphicsState() } } -void D3D11Renderer::_flushComputeState() +void D3D11Device::_flushComputeState() { auto pipelineType = int(PipelineType::Compute); if (m_shaderBindingDirty) @@ -2486,7 +2426,7 @@ void D3D11Renderer::_flushComputeState() } } -void D3D11Renderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) +void D3D11Device::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) { auto bufferImpl = (BufferResourceImpl*) buffer; auto& rangeInfo = m_layout->m_ranges[range]; @@ -2496,7 +2436,7 @@ void D3D11Renderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, m_cbs[rangeInfo.arrayIndex + index] = bufferImpl->m_buffer; } -void D3D11Renderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) +void D3D11Device::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) { auto viewImpl = (ResourceViewImpl*)view; auto& rangeInfo = m_layout->m_ranges[range]; @@ -2540,7 +2480,7 @@ void D3D11Renderer::DescriptorSetImpl::setResource(UInt range, UInt index, IReso } } -void D3D11Renderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) +void D3D11Device::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) { auto samplerImpl = (SamplerStateImpl*) sampler; auto& rangeInfo = m_layout->m_ranges[range]; @@ -2550,7 +2490,7 @@ void D3D11Renderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISampl m_samplers[rangeInfo.arrayIndex + index] = samplerImpl->m_sampler; } -void D3D11Renderer::DescriptorSetImpl::setCombinedTextureSampler( +void D3D11Device::DescriptorSetImpl::setCombinedTextureSampler( UInt range, UInt index, IResourceView* textureView, @@ -2572,7 +2512,7 @@ void D3D11Renderer::DescriptorSetImpl::setCombinedTextureSampler( m_srvs[rangeInfo.pairedSamplerArrayIndex + index] = srvImpl->m_srv; } -void D3D11Renderer::DescriptorSetImpl::setRootConstants( +void D3D11Device::DescriptorSetImpl::setRootConstants( UInt range, UInt offset, UInt size, @@ -2610,7 +2550,7 @@ void D3D11Renderer::DescriptorSetImpl::setRootConstants( dxContext->Unmap(dxBuffer, 0); } -void D3D11Renderer::setDescriptorSet(PipelineType pipelineType, IPipelineLayout* layout, UInt index, IDescriptorSet* descriptorSet) +void D3D11Device::setDescriptorSet(PipelineType pipelineType, IPipelineLayout* layout, UInt index, IDescriptorSet* descriptorSet) { auto pipelineLayoutImpl = (PipelineLayoutImpl*)layout; auto descriptorSetImpl = (DescriptorSetImpl*) descriptorSet; diff --git a/tools/gfx/d3d11/render-d3d11.h b/tools/gfx/d3d11/render-d3d11.h index 42887ed1b..f593ea424 100644 --- a/tools/gfx/d3d11/render-d3d11.h +++ b/tools/gfx/d3d11/render-d3d11.h @@ -6,6 +6,6 @@ namespace gfx { -SlangResult SLANG_MCALL createD3D11Renderer(const IRenderer::Desc* desc, IRenderer** outRenderer); +SlangResult SLANG_MCALL createD3D11Device(const IDevice::Desc* desc, IDevice** outDevice); } // gfx diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 374a78cdd..f39baf4cc 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -7,6 +7,7 @@ #include "../renderer-shared.h" #include "../render-graphics-common.h" #include "../simple-render-pass-layout.h" +#include "../d3d/d3d-swapchain.h" #include "core/slang-blob.h" #include "core/slang-basic.h" @@ -65,7 +66,7 @@ using namespace Slang; static D3D12_RESOURCE_STATES _calcResourceState(IResource::Usage usage); -class D3D12Renderer : public GraphicsAPIRenderer +class D3D12Device : public GraphicsAPIRenderer { public: // Renderer implementation @@ -141,12 +142,12 @@ public: size_t size, ISlangBlob** outBlob) override; - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const override + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { - return RendererType::DirectX12; + return m_info; } - ~D3D12Renderer(); + ~D3D12Device(); protected: @@ -267,7 +268,7 @@ protected: } public: D3D12HostVisibleDescriptor m_descriptor; - D3D12Renderer* m_renderer; + D3D12Device* m_renderer; ~SamplerStateImpl() { m_renderer->m_samplerAllocator.free(m_descriptor); @@ -287,6 +288,11 @@ protected: public: RefPtr<Resource> m_resource; D3D12HostVisibleDescriptor m_descriptor; + D3D12HostVisibleDescriptorAllocator* m_allocator; + ~ResourceViewImpl() + { + m_allocator->free(m_descriptor); + } }; class FramebufferLayoutImpl @@ -504,7 +510,7 @@ protected: UInt size, void const* data) override; - D3D12Renderer* m_renderer = nullptr; ///< Weak pointer - must be because if set on Renderer, will have a circular reference + D3D12Device* m_renderer = nullptr; ///< Weak pointer - must be because if set on Renderer, will have a circular reference RefPtr<DescriptorSetLayoutImpl> m_layout; D3D12HostVisibleDescriptorAllocator* m_resourceHeap = nullptr; @@ -761,8 +767,8 @@ protected: public: ComPtr<ID3D12GraphicsCommandList> m_cmdList; ExecutionFrameResources* m_frame; - D3D12Renderer* m_renderer; - void init(D3D12Renderer* renderer, ExecutionFrameResources* frame) + D3D12Device* m_renderer; + void init(D3D12Device* renderer, ExecutionFrameResources* frame) { m_frame = frame; m_renderer = renderer; @@ -900,7 +906,7 @@ protected: D3D12_PRIMITIVE_TOPOLOGY m_primitiveTopology; void init( - D3D12Renderer* renderer, + D3D12Device* renderer, ExecutionFrameResources* frame, CommandBufferImpl* cmdBuffer, RenderPassLayoutImpl* renderPass, @@ -1236,6 +1242,7 @@ protected: m_renderPass->m_depthStencilAccess.finalState), submitter); } + m_framebuffer = nullptr; } virtual SLANG_NO_THROW void SLANG_MCALL @@ -1286,7 +1293,7 @@ protected: PipelineCommandEncoder::endEncodingImpl(); } void init( - D3D12Renderer* renderer, + D3D12Device* renderer, ExecutionFrameResources* frame, CommandBufferImpl* cmdBuffer) { @@ -1360,7 +1367,7 @@ protected: public: CommandBufferImpl* m_commandBuffer; - void init(D3D12Renderer* renderer, CommandBufferImpl* commandBuffer) + void init(D3D12Device* renderer, CommandBufferImpl* commandBuffer) { m_commandBuffer = commandBuffer; } @@ -1423,7 +1430,7 @@ protected: { List<RefPtr<CommandBufferImpl>> pool; uint32_t allocIndex = 0; - RefPtr<CommandBufferImpl> allocCommandBuffer(D3D12Renderer* renderer, ExecutionFrameResources* frame) + RefPtr<CommandBufferImpl> allocCommandBuffer(D3D12Device* renderer, ExecutionFrameResources* frame) { if ((Index)allocIndex < pool.getCount()) { @@ -1445,7 +1452,7 @@ protected: List<CommandBufferPool> m_commandBufferPools; List<ExecutionFrameResources> m_frames; uint32_t m_frameIndex = 0; - D3D12Renderer* m_renderer; + D3D12Device* m_renderer; ComPtr<ID3D12Device> m_device; ComPtr<ID3D12CommandQueue> m_d3dQueue; ComPtr<ID3D12Fence> m_fence; @@ -1453,7 +1460,7 @@ protected: HANDLE globalWaitHandle; Desc m_desc; Result init( - D3D12Renderer* renderer, + D3D12Device* renderer, uint32_t frameCount, uint32_t viewHeapSize, uint32_t samplerHeapSize) @@ -1535,142 +1542,52 @@ protected: } }; - class SwapchainImpl - : public ISwapchain - , public RefObject + class SwapchainImpl : public D3DSwapchainBase { public: - SLANG_REF_OBJECT_IUNKNOWN_ALL - ISwapchain* getInterface(const Guid& guid) + ComPtr<ID3D12CommandQueue> m_queue; + ComPtr<IDXGIFactory> m_dxgiFactory; + ComPtr<IDXGISwapChain3> m_swapChain3; + + Result init( + D3D12Device* renderer, + const ISwapchain::Desc& swapchainDesc, + WindowHandle window) { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISwapchain) - return static_cast<ISwapchain*>(this); - return nullptr; + m_queue = static_cast<CommandQueueImpl*>(swapchainDesc.queue)->m_d3dQueue; + m_dxgiFactory = renderer->m_deviceInfo.m_dxgiFactory; + SLANG_RETURN_ON_FAIL( + D3DSwapchainBase::init(swapchainDesc, window, DXGI_SWAP_EFFECT_FLIP_DISCARD)); + SLANG_RETURN_ON_FAIL(m_swapChain->QueryInterface(m_swapChain3.writeRef())); + return SLANG_OK; } - public: - Result init(D3D12Renderer* renderer, const ISwapchain::Desc& desc, WindowHandle window) + virtual void createSwapchainBufferImages() override { - // Return fail on non-supported platforms. - switch (window.type) - { - case WindowHandle::Type::Win32Handle: - break; - default: - return SLANG_FAIL; - } - - m_renderer = renderer; - m_desc = desc; - m_queue = static_cast<CommandQueueImpl*>(desc.queue); - - // Describe the swap chain. - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferCount = desc.imageCount; - swapChainDesc.BufferDesc.Width = desc.width; - swapChainDesc.BufferDesc.Height = desc.height; - swapChainDesc.BufferDesc.Format = D3DUtil::getMapFormat(desc.format); - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = (HWND)window.handleValues[0]; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.Windowed = TRUE; - - if (!desc.enableVSync) - { - swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - } - - // Swap chain needs the queue so that it can force a flush on it. - ComPtr<IDXGISwapChain> swapChain; - SLANG_RETURN_ON_FAIL(m_renderer->m_deviceInfo.m_dxgiFactory->CreateSwapChain( - m_queue->m_d3dQueue, &swapChainDesc, swapChain.writeRef())); - SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(m_swapChain.writeRef())); - - if (!desc.enableVSync) - { - m_swapChainWaitableObject = m_swapChain->GetFrameLatencyWaitableObject(); - - int maxLatency = desc.imageCount - 2; - - // Make sure the maximum latency is in the range required by dx12 runtime - maxLatency = (maxLatency < 1) ? 1 : maxLatency; - maxLatency = (maxLatency > DXGI_MAX_SWAP_CHAIN_BUFFERS) - ? DXGI_MAX_SWAP_CHAIN_BUFFERS - : maxLatency; - - m_swapChain->SetMaximumFrameLatency(maxLatency); - } - - // This sample does not support fullscreen transitions. - SLANG_RETURN_ON_FAIL(m_renderer->m_deviceInfo.m_dxgiFactory->MakeWindowAssociation( - (HWND)window.handleValues[0], DXGI_MWA_NO_ALT_ENTER)); - - m_renderTargetIndex = m_swapChain->GetCurrentBackBufferIndex(); - - for (uint32_t i = 0; i < desc.imageCount; i++) + m_images.clear(); + + for (uint32_t i = 0; i < m_desc.imageCount; i++) { ComPtr<ID3D12Resource> d3dResource; m_swapChain->GetBuffer(i, IID_PPV_ARGS(d3dResource.writeRef())); ITextureResource::Desc imageDesc = {}; imageDesc.setDefaults(IResource::Usage::RenderTarget); imageDesc.init2D( - IResource::Type::Texture2D, desc.format, desc.width, desc.height, 0); + IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 0); RefPtr<TextureResourceImpl> image = new TextureResourceImpl(imageDesc); image->m_resource.setResource(d3dResource.get()); image->m_defaultState = D3D12_RESOURCE_STATE_PRESENT; - m_images.add(image); + ComPtr<ITextureResource> imageResourcePtr; + imageResourcePtr = image.Ptr(); + m_images.add(imageResourcePtr); } - return SLANG_OK; } - virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() override { return m_desc; } - virtual SLANG_NO_THROW Result - getImage(uint32_t index, ITextureResource** outResource) override + virtual IDXGIFactory* getDXGIFactory() override { return m_dxgiFactory; } + virtual IUnknown* getOwningDevice() override { return m_queue; } + virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() override { - m_images[index]->addRef(); - *outResource = m_images[index].Ptr(); - return SLANG_OK; + return (int)m_swapChain3->GetCurrentBackBufferIndex(); } - virtual SLANG_NO_THROW Result present() override - { - if (m_swapChainWaitableObject) - { - // check if now is good time to present - // This doesn't wait - because the wait time is 0. If it returns WAIT_TIMEOUT it - // means that no frame is waiting to be be displayed so there is no point doing a - // present. - const bool shouldPresent = - (WaitForSingleObjectEx(m_swapChainWaitableObject, 0, TRUE) != WAIT_TIMEOUT); - if (shouldPresent) - { - m_swapChain->Present(0, 0); - } - } - else - { - if (SLANG_FAILED(m_swapChain->Present(1, 0))) - { - return SLANG_FAIL; - } - } - // Update the render target index. - m_renderTargetIndex = m_swapChain->GetCurrentBackBufferIndex(); - return SLANG_OK; - } - - virtual SLANG_NO_THROW uint32_t acquireNextImage() override - { - return m_renderTargetIndex; - } - - public: - D3D12Renderer* m_renderer = nullptr; - ISwapchain::Desc m_desc; - HANDLE m_swapChainWaitableObject = nullptr; - ComPtr<IDXGISwapChain3> m_swapChain; - RefPtr<CommandQueueImpl> m_queue; - uint32_t m_renderTargetIndex; - ShortList<RefPtr<TextureResourceImpl>> m_images; }; static PROC loadProc(HMODULE module, char const* name); @@ -1722,8 +1639,13 @@ protected: m_resourceCommandQueue->wait(); } + // D3D12Device members. + Desc m_desc; + gfx::DeviceInfo m_info; + String m_adapterName; + bool m_isInitialized = false; ComPtr<ID3D12Debug> m_dxDebug; @@ -1742,7 +1664,7 @@ protected: }; -Result D3D12Renderer::CommandBufferImpl::PipelineCommandEncoder::_bindRenderState( +Result D3D12Device::CommandBufferImpl::PipelineCommandEncoder::_bindRenderState( PipelineStateImpl* pipelineStateImpl, Submitter* submitter) { @@ -1832,27 +1754,27 @@ Result D3D12Renderer::CommandBufferImpl::PipelineCommandEncoder::_bindRenderStat return SLANG_OK; } -Result D3D12Renderer::createCommandQueueImpl( +Result D3D12Device::createCommandQueueImpl( uint32_t frameCount, uint32_t viewHeapSize, uint32_t samplerHeapSize, - D3D12Renderer::CommandQueueImpl** outQueue) + D3D12Device::CommandQueueImpl** outQueue) { - RefPtr<D3D12Renderer::CommandQueueImpl> queue = new D3D12Renderer::CommandQueueImpl(); + RefPtr<D3D12Device::CommandQueueImpl> queue = new D3D12Device::CommandQueueImpl(); SLANG_RETURN_ON_FAIL(queue->init(this, frameCount, viewHeapSize, samplerHeapSize)); *outQueue = queue.detach(); return SLANG_OK; } -SlangResult SLANG_MCALL createD3D12Renderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +SlangResult SLANG_MCALL createD3D12Device(const IDevice::Desc* desc, IDevice** outDevice) { - RefPtr<D3D12Renderer> result = new D3D12Renderer(); + RefPtr<D3D12Device> result = new D3D12Device(); SLANG_RETURN_ON_FAIL(result->initialize(*desc)); - *outRenderer = result.detach(); + *outDevice = result.detach(); return SLANG_OK; } -/* static */PROC D3D12Renderer::loadProc(HMODULE module, char const* name) +/* static */PROC D3D12Device::loadProc(HMODULE module, char const* name) { PROC proc = ::GetProcAddress(module, name); if (!proc) @@ -1863,7 +1785,7 @@ SlangResult SLANG_MCALL createD3D12Renderer(const IRenderer::Desc* desc, IRender return proc; } -D3D12Renderer::~D3D12Renderer() +D3D12Device::~D3D12Device() { } @@ -1949,7 +1871,7 @@ static void _initBufferResourceDesc(size_t bufferSize, D3D12_RESOURCE_DESC& out) out.Flags = D3D12_RESOURCE_FLAG_NONE; } -Result D3D12Renderer::createBuffer(const D3D12_RESOURCE_DESC& resourceDesc, const void* srcData, size_t srcDataSize, D3D12Resource& uploadResource, D3D12_RESOURCE_STATES finalState, D3D12Resource& resourceOut) +Result D3D12Device::createBuffer(const D3D12_RESOURCE_DESC& resourceDesc, const void* srcData, size_t srcDataSize, D3D12Resource& uploadResource, D3D12_RESOURCE_STATES finalState, D3D12Resource& resourceOut) { const size_t bufferSize = size_t(resourceDesc.Width); @@ -2001,7 +1923,7 @@ Result D3D12Renderer::createBuffer(const D3D12_RESOURCE_DESC& resourceDesc, cons return SLANG_OK; } -Result D3D12Renderer::captureTextureToSurface( +Result D3D12Device::captureTextureToSurface( D3D12Resource& resource, ResourceState state, ISlangBlob** outBlob, @@ -2097,7 +2019,7 @@ Result D3D12Renderer::captureTextureToSurface( // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!! -Result D3D12Renderer::_createDevice(DeviceCheckFlags deviceCheckFlags, const UnownedStringSlice& nameMatch, D3D_FEATURE_LEVEL featureLevel, DeviceInfo& outDeviceInfo) +Result D3D12Device::_createDevice(DeviceCheckFlags deviceCheckFlags, const UnownedStringSlice& nameMatch, D3D_FEATURE_LEVEL featureLevel, DeviceInfo& outDeviceInfo) { outDeviceInfo.clear(); @@ -2203,12 +2125,22 @@ static bool _isSupportedNVAPIOp(ID3D12Device* dev, uint32_t op) #endif } -Result D3D12Renderer::initialize(const Desc& desc) +Result D3D12Device::initialize(const Desc& desc) { SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_DXBC, "sm_5_1")); SLANG_RETURN_ON_FAIL(GraphicsAPIRenderer::initialize(desc)); + // Initialize DeviceInfo + { + m_info.deviceType = DeviceType::DirectX12; + m_info.bindingStyle = BindingStyle::DirectX; + m_info.projectionStyle = ProjectionStyle::DirectX; + m_info.apiName = "Direct3D 12"; + static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + ::memcpy(m_info.identityProjectionMatrix, kIdentity, sizeof(kIdentity)); + } + // Rather than statically link against D3D, we load it dynamically. HMODULE d3dModule = LoadLibraryA("d3d12.dll"); @@ -2362,11 +2294,20 @@ Result D3D12Renderer::initialize(const Desc& desc) SLANG_RETURN_ON_FAIL(m_viewAllocator.init (m_device, 64, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); SLANG_RETURN_ON_FAIL(m_samplerAllocator.init(m_device, 16, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)); + ComPtr<IDXGIDevice> dxgiDevice; + if (m_deviceInfo.m_adapter) + { + DXGI_ADAPTER_DESC adapterDesc; + m_deviceInfo.m_adapter->GetDesc(&adapterDesc); + m_adapterName = String::fromWString(adapterDesc.Description); + m_info.adapterName = m_adapterName.begin(); + } + m_isInitialized = true; return SLANG_OK; } -Result D3D12Renderer::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) +Result D3D12Device::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) { RefPtr<CommandQueueImpl> queue; SLANG_RETURN_ON_FAIL(createCommandQueueImpl(8, 4096, 1024, queue.writeRef())); @@ -2374,7 +2315,7 @@ Result D3D12Renderer::createCommandQueue(const ICommandQueue::Desc& desc, IComma return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL D3D12Renderer::createSwapchain( +SLANG_NO_THROW Result SLANG_MCALL D3D12Device::createSwapchain( const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) { RefPtr<SwapchainImpl> swapchain = new SwapchainImpl(); @@ -2383,7 +2324,7 @@ SLANG_NO_THROW Result SLANG_MCALL D3D12Renderer::createSwapchain( return SLANG_OK; } -SlangResult D3D12Renderer::readTextureResource( +SlangResult D3D12Device::readTextureResource( ITextureResource* resource, ResourceState state, ISlangBlob** outBlob, @@ -2461,7 +2402,7 @@ static D3D12_RESOURCE_DIMENSION _calcResourceDimension(IResource::Type type) } } -Result D3D12Renderer::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) +Result D3D12Device::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) { // Description of uploading on Dx12 // https://msdn.microsoft.com/en-us/library/windows/desktop/dn899215%28v=vs.85%29.aspx @@ -2678,7 +2619,7 @@ Result D3D12Renderer::createTextureResource(IResource::Usage initialUsage, const return SLANG_OK; } -Result D3D12Renderer::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result D3D12Device::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { BufferResource::Desc srcDesc(descIn); srcDesc.setDefaults(initialUsage); @@ -2782,7 +2723,7 @@ static D3D12_COMPARISON_FUNC translateComparisonFunc(ComparisonFunc func) } } -Result D3D12Renderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) +Result D3D12Device::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) { D3D12_FILTER_REDUCTION_TYPE dxReduction = translateFilterReduction(desc.reductionOp); D3D12_FILTER dxFilter; @@ -2829,7 +2770,7 @@ Result D3D12Renderer::createSamplerState(ISamplerState::Desc const& desc, ISampl return SLANG_OK; } -Result D3D12Renderer::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) +Result D3D12Device::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (TextureResourceImpl*) texture; @@ -2844,6 +2785,7 @@ Result D3D12Renderer::createTextureView(ITextureResource* texture, IResourceView case IResourceView::Type::RenderTarget: { SLANG_RETURN_ON_FAIL(m_rtvAllocator.allocate(&viewImpl->m_descriptor)); + viewImpl->m_allocator = &m_rtvAllocator; D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; rtvDesc.Format = D3DUtil::getMapFormat(desc.format); switch (desc.renderTarget.shape) @@ -2874,6 +2816,7 @@ Result D3D12Renderer::createTextureView(ITextureResource* texture, IResourceView case IResourceView::Type::DepthStencil: { SLANG_RETURN_ON_FAIL(m_dsvAllocator.allocate(&viewImpl->m_descriptor)); + viewImpl->m_allocator = &m_dsvAllocator; D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; dsvDesc.Format = D3DUtil::getMapFormat(desc.format); switch (desc.renderTarget.shape) @@ -2900,6 +2843,7 @@ Result D3D12Renderer::createTextureView(ITextureResource* texture, IResourceView // of append/consume buffers with attached counters. SLANG_RETURN_ON_FAIL(m_viewAllocator.allocate(&viewImpl->m_descriptor)); + viewImpl->m_allocator = &m_viewAllocator; m_device->CreateUnorderedAccessView(resourceImpl->m_resource, nullptr, nullptr, viewImpl->m_descriptor.cpuHandle); } break; @@ -2907,6 +2851,7 @@ Result D3D12Renderer::createTextureView(ITextureResource* texture, IResourceView case IResourceView::Type::ShaderResource: { SLANG_RETURN_ON_FAIL(m_viewAllocator.allocate(&viewImpl->m_descriptor)); + viewImpl->m_allocator = &m_viewAllocator; // Need to construct the D3D12_SHADER_RESOURCE_VIEW_DESC because otherwise TextureCube is not accessed // appropriately (rather than just passing nullptr to CreateShaderResourceView) @@ -2925,7 +2870,7 @@ Result D3D12Renderer::createTextureView(ITextureResource* texture, IResourceView return SLANG_OK; } -Result D3D12Renderer::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) +Result D3D12Device::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (BufferResourceImpl*) buffer; auto resourceDesc = *resourceImpl->getDesc(); @@ -2966,6 +2911,7 @@ Result D3D12Renderer::createBufferView(IBufferResource* buffer, IResourceView::D // of append/consume buffers with attached counters. SLANG_RETURN_ON_FAIL(m_viewAllocator.allocate(&viewImpl->m_descriptor)); + viewImpl->m_allocator = &m_viewAllocator; m_device->CreateUnorderedAccessView(resourceImpl->m_resource, nullptr, &uavDesc, viewImpl->m_descriptor.cpuHandle); } break; @@ -2995,6 +2941,7 @@ Result D3D12Renderer::createBufferView(IBufferResource* buffer, IResourceView::D } SLANG_RETURN_ON_FAIL(m_viewAllocator.allocate(&viewImpl->m_descriptor)); + viewImpl->m_allocator = &m_viewAllocator; m_device->CreateShaderResourceView(resourceImpl->m_resource, &srvDesc, viewImpl->m_descriptor.cpuHandle); } break; @@ -3004,7 +2951,7 @@ Result D3D12Renderer::createBufferView(IBufferResource* buffer, IResourceView::D return SLANG_OK; } -Result D3D12Renderer::createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFb) +Result D3D12Device::createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFb) { RefPtr<FramebufferImpl> framebuffer = new FramebufferImpl(); framebuffer->renderTargetViews.setCount(desc.renderTargetCount); @@ -3041,7 +2988,7 @@ Result D3D12Renderer::createFramebuffer(IFramebuffer::Desc const& desc, IFramebu return SLANG_OK; } -Result D3D12Renderer::createFramebufferLayout( +Result D3D12Device::createFramebufferLayout( IFramebufferLayout::Desc const& desc, IFramebufferLayout** outLayout) { RefPtr<FramebufferLayoutImpl> layout = new FramebufferLayoutImpl(); @@ -3064,7 +3011,7 @@ Result D3D12Renderer::createFramebufferLayout( return SLANG_OK; } -Result D3D12Renderer::createRenderPassLayout( +Result D3D12Device::createRenderPassLayout( const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) { @@ -3074,7 +3021,7 @@ Result D3D12Renderer::createRenderPassLayout( return SLANG_OK; } -Result D3D12Renderer::createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount, IInputLayout** outLayout) +Result D3D12Device::createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount, IInputLayout** outLayout) { RefPtr<InputLayoutImpl> layout(new InputLayoutImpl); @@ -3121,7 +3068,7 @@ Result D3D12Renderer::createInputLayout(const InputElementDesc* inputElements, U return SLANG_OK; } -Result D3D12Renderer::readBufferResource( +Result D3D12Device::readBufferResource( IBufferResource* bufferIn, size_t offset, size_t size, @@ -3175,7 +3122,7 @@ Result D3D12Renderer::readBufferResource( return SLANG_OK; } -void D3D12Renderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) +void D3D12Device::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) { auto dxDevice = m_renderer->m_device; @@ -3213,7 +3160,7 @@ void D3D12Renderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, m_resourceHeap->getCpuHandle(int(descriptorIndex))); } -void D3D12Renderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) +void D3D12Device::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) { auto dxDevice = m_renderer->m_device; @@ -3234,7 +3181,7 @@ void D3D12Renderer::DescriptorSetImpl::setResource(UInt range, UInt index, IReso D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } -void D3D12Renderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) +void D3D12Device::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) { auto dxDevice = m_renderer->m_device; @@ -3265,7 +3212,7 @@ void D3D12Renderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISampl D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } -void D3D12Renderer::DescriptorSetImpl::setCombinedTextureSampler( +void D3D12Device::DescriptorSetImpl::setCombinedTextureSampler( UInt range, UInt index, IResourceView* textureView, @@ -3309,7 +3256,7 @@ void D3D12Renderer::DescriptorSetImpl::setCombinedTextureSampler( D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } -void D3D12Renderer::DescriptorSetImpl::setRootConstants( +void D3D12Device::DescriptorSetImpl::setRootConstants( UInt range, UInt offset, UInt size, @@ -3338,7 +3285,7 @@ void D3D12Renderer::DescriptorSetImpl::setRootConstants( memcpy((char*)m_rootConstantData.getBuffer() + rootConstantRangeInfo.offset + offset, data, size); } -Result D3D12Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) +Result D3D12Device::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) { @@ -3376,7 +3323,7 @@ Result D3D12Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderPro return SLANG_OK; } -Result D3D12Renderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) +Result D3D12Device::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) { Int rangeCount = desc.slotRangeCount; @@ -3822,7 +3769,7 @@ Result D3D12Renderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc return SLANG_OK; } -Result D3D12Renderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) +Result D3D12Device::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) { static const UInt kMaxRanges = 16; static const UInt kMaxRootParameters = 32; @@ -3982,7 +3929,7 @@ Result D3D12Renderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IP return SLANG_OK; } -Result D3D12Renderer::createDescriptorSet( +Result D3D12Device::createDescriptorSet( IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) @@ -4023,7 +3970,7 @@ Result D3D12Renderer::createDescriptorSet( return SLANG_OK; } -Result D3D12Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) +Result D3D12Device::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) { GraphicsPipelineStateDesc desc = inDesc; preparePipelineDesc(desc); @@ -4128,7 +4075,7 @@ Result D3D12Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDes return SLANG_OK; } -Result D3D12Renderer::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) +Result D3D12Device::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) { ComputePipelineStateDesc desc = inDesc; preparePipelineDesc(desc); diff --git a/tools/gfx/d3d12/render-d3d12.h b/tools/gfx/d3d12/render-d3d12.h index 4e9dc3f78..457fc1db6 100644 --- a/tools/gfx/d3d12/render-d3d12.h +++ b/tools/gfx/d3d12/render-d3d12.h @@ -6,6 +6,6 @@ namespace gfx { -SlangResult SLANG_MCALL createD3D12Renderer(const IRenderer::Desc* desc, IRenderer** outRenderer); +SlangResult SLANG_MCALL createD3D12Device(const IDevice::Desc* desc, IDevice** outDevice); } // gfx diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index 01f285f65..cd17aee78 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -88,7 +88,7 @@ using namespace Slang; namespace gfx { -class GLRenderer : public ImmediateRendererBase +class GLDevice : public ImmediateRendererBase { public: // Renderer implementation @@ -179,13 +179,14 @@ public: virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) override; virtual SLANG_NO_THROW void SLANG_MCALL submitGpuWork() override {} virtual SLANG_NO_THROW void SLANG_MCALL waitForGpu() override {} - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const override + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { - return RendererType::OpenGl; + return m_info; } + HGLRC createGLContext(HDC hdc); - GLRenderer(); - ~GLRenderer(); + GLDevice(); + ~GLDevice(); protected: enum @@ -227,7 +228,7 @@ public: public: typedef BufferResource Parent; - BufferResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLRenderer>* renderer, GLuint id, GLenum target): + BufferResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLDevice>* renderer, GLuint id, GLenum target): Parent(desc), m_renderer(renderer), m_handle(id), @@ -243,7 +244,7 @@ public: } Usage m_initialUsage; - RefPtr<WeakSink<GLRenderer> > m_renderer; + RefPtr<WeakSink<GLDevice> > m_renderer; GLuint m_handle; GLenum m_target; }; @@ -253,7 +254,7 @@ public: public: typedef TextureResource Parent; - TextureResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLRenderer>* renderer): + TextureResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLDevice>* renderer): Parent(desc), m_initialUsage(initialUsage), m_renderer(renderer) @@ -271,7 +272,7 @@ public: } Usage m_initialUsage; - RefPtr<WeakSink<GLRenderer> > m_renderer; + RefPtr<WeakSink<GLDevice> > m_renderer; GLenum m_target; GLuint m_handle; }; @@ -351,14 +352,14 @@ public: public: GLuint m_framebuffer; ShortList<GLenum> m_drawBuffers; - WeakSink<GLRenderer>* m_renderer; + WeakSink<GLDevice>* m_renderer; ShortList<RefPtr<TextureViewImpl>> renderTargetViews; RefPtr<TextureViewImpl> depthStencilView; ShortList<ColorClearValue> m_colorClearValues; bool m_sameClearValues = true; DepthStencilClearValue m_depthStencilClearValue; - FramebufferImpl(WeakSink<GLRenderer>* renderer) :m_renderer(renderer) {} + FramebufferImpl(WeakSink<GLDevice>* renderer) :m_renderer(renderer) {} ~FramebufferImpl() { if (auto renderer = m_renderer->get()) @@ -429,73 +430,92 @@ public: public: ~SwapchainImpl() { - for (auto image : m_images) - image->m_handle = 0; - if (auto rendererRef = m_renderer->get()) + destroyBackBufferAndFBO(); + wglDeleteContext(m_glrc); + ::ReleaseDC(m_hwnd, m_hdc); + } + void destroyBackBufferAndFBO() + { + if (m_images.getCount()) { - rendererRef->glDeleteFramebuffers(1, &m_framebuffer); + wglMakeCurrent(m_rendererHDC, m_rendererRC); + if (auto rendererRef = m_renderer->get()) + { + rendererRef->glDeleteFramebuffers(1, &m_framebuffer); + } + wglMakeCurrent(m_hdc, m_glrc); glDeleteTextures(1, &m_backBuffer); + for (auto image : m_images) + image->m_handle = 0; + m_images.clear(); } - wglMakeCurrent(m_hdc, 0); - wglDeleteContext(m_glrc); - ::ReleaseDC(m_hwnd, m_hdc); } - Result init(GLRenderer* renderer, const ISwapchain::Desc& desc, WindowHandle window) + void createBackBufferAndFBO() + { + if (m_desc.width > 0 && m_desc.height > 0) + { + wglMakeCurrent(m_rendererHDC, m_rendererRC); + + glGenTextures(1, &m_backBuffer); + glBindTexture(GL_TEXTURE_2D, m_backBuffer); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA8, + m_desc.width, + m_desc.height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + nullptr); + + wglMakeCurrent(m_hdc, m_glrc); + m_renderer->get()->glGenFramebuffers(1, &m_framebuffer); + m_renderer->get()->glBindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer); + m_renderer->get()->glFramebufferTexture2D( + GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer, 0); + + m_images.clear(); + for (uint32_t i = 0; i < m_desc.imageCount; i++) + { + ITextureResource::Desc texDesc = {}; + texDesc.init2D( + IResource::Type::Texture2D, + gfx::Format::RGBA_Unorm_UInt8, + m_desc.width, + m_desc.height, + 1); + RefPtr<TextureResourceImpl> tex = new TextureResourceImpl( + IResource::Usage::RenderTarget, texDesc, m_renderer); + tex->m_handle = m_backBuffer; + m_images.add(tex); + } + wglMakeCurrent(m_rendererHDC, m_rendererRC); + } + } + Result init(GLDevice* renderer, const ISwapchain::Desc& desc, WindowHandle window) { m_renderer = renderer->m_weakRenderer.Ptr(); + m_rendererHDC = renderer->m_hdc; + m_rendererRC = renderer->m_glContext; m_hwnd = (HWND)window.handleValues[0]; m_hdc = ::GetDC(m_hwnd); m_glrc = renderer->createGLContext(m_hdc); - wglMakeCurrent(renderer->m_hdc, renderer->m_glContext); - m_desc = desc; - glGenTextures(1, &m_backBuffer); - glBindTexture(GL_TEXTURE_2D, m_backBuffer); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGBA8, - desc.width, - desc.height, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - nullptr); - - wglMakeCurrent(m_hdc, m_glrc); - renderer->glGenFramebuffers(1, &m_framebuffer); - renderer->glBindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer); - renderer->glFramebufferTexture2D( - GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer, 0); - - for (uint32_t i = 0; i < desc.imageCount; i++) - { - ITextureResource::Desc texDesc = {}; - texDesc.init2D( - IResource::Type::Texture2D, - gfx::Format::RGBA_Unorm_UInt8, - desc.width, - desc.height, - 1); - RefPtr<TextureResourceImpl> tex = - new TextureResourceImpl(IResource::Usage::RenderTarget, texDesc, m_renderer); - tex->m_handle = m_backBuffer; - m_images.add(tex); - } - wglMakeCurrent(renderer->m_hdc, renderer->m_glContext); + createBackBufferAndFBO(); return SLANG_OK; } virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() override { return m_desc; } - virtual SLANG_NO_THROW Result + virtual SLANG_NO_THROW Result SLANG_MCALL getImage(uint32_t index, ITextureResource** outResource) override { m_images[index]->addRef(); *outResource = m_images[index].Ptr(); return SLANG_OK; } - virtual SLANG_NO_THROW Result present() override + virtual SLANG_NO_THROW Result SLANG_MCALL present() override { glFlush(); wglMakeCurrent(m_hdc, m_glrc); @@ -518,18 +538,35 @@ public: return SLANG_OK; } - virtual SLANG_NO_THROW uint32_t acquireNextImage() override + virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() override + { + if (m_desc.width > 0 && m_desc.height > 0) + return 0; + return -1; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL resize(uint32_t width, uint32_t height) override { - return 0; + if (width > 0 && height > 0 && (width != m_desc.width || height != m_desc.height)) + { + m_desc.width = width; + m_desc.height = height; + destroyBackBufferAndFBO(); + createBackBufferAndFBO(); + } + return SLANG_OK; } public: - WeakSink<GLRenderer>* m_renderer = nullptr; + WeakSink<GLDevice>* m_renderer = nullptr; GLuint m_framebuffer; GLuint m_backBuffer; HGLRC m_glrc; HWND m_hwnd; HDC m_hdc; + + HDC m_rendererHDC; + HGLRC m_rendererRC; ISwapchain::Desc m_desc; ShortList<RefPtr<TextureResourceImpl>> m_images; }; @@ -623,7 +660,7 @@ public: class ShaderProgramImpl : public GraphicsCommonShaderProgram { public: - ShaderProgramImpl(WeakSink<GLRenderer>* renderer, GLuint id): + ShaderProgramImpl(WeakSink<GLDevice>* renderer, GLuint id): m_renderer(renderer), m_id(id) { @@ -637,7 +674,7 @@ public: } GLuint m_id; - RefPtr<WeakSink<GLRenderer> > m_renderer; + RefPtr<WeakSink<GLDevice> > m_renderer; }; class PipelineStateImpl : public PipelineStateBase @@ -691,6 +728,11 @@ public: static void compileTimeAsserts(); + // GLDevice members. + + DeviceInfo m_info; + String m_adapterName; + HDC m_hdc; HGLRC m_glContext = 0; uint32_t m_stencilRef = 0; @@ -698,7 +740,7 @@ public: GLuint m_vao; RefPtr<PipelineStateImpl> m_currentPipelineState; RefPtr<FramebufferImpl> m_currentFramebuffer; - RefPtr<WeakSink<GLRenderer> > m_weakRenderer; + RefPtr<WeakSink<GLDevice> > m_weakRenderer; RefPtr<DescriptorSetImpl> m_boundDescriptorSets[kMaxDescriptorSetCount]; @@ -719,7 +761,7 @@ public: static const GlPixelFormatInfo s_pixelFormatInfos[]; /// Maps GlPixelFormat to a format info }; -/* static */GLRenderer::GlPixelFormat GLRenderer::_getGlPixelFormat(Format format) +/* static */GLDevice::GlPixelFormat GLDevice::_getGlPixelFormat(Format format) { switch (format) { @@ -731,7 +773,7 @@ public: } } -/* static */ const GLRenderer::GlPixelFormatInfo GLRenderer::s_pixelFormatInfos[] = +/* static */ const GLDevice::GlPixelFormatInfo GLDevice::s_pixelFormatInfos[] = { // internalType, format, formatType { 0, 0, 0}, // GlPixelFormat::Unknown @@ -741,20 +783,20 @@ public: }; -/* static */void GLRenderer::compileTimeAsserts() +/* static */void GLDevice::compileTimeAsserts() { SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(s_pixelFormatInfos) == int(GlPixelFormat::CountOf)); } -SlangResult SLANG_MCALL createGLRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +SlangResult SLANG_MCALL createGLDevice(const IDevice::Desc* desc, IDevice** outRenderer) { - RefPtr<GLRenderer> result = new GLRenderer(); + RefPtr<GLDevice> result = new GLDevice(); SLANG_RETURN_ON_FAIL(result->initialize(*desc)); *outRenderer = result.detach(); return SLANG_OK; } -void GLRenderer::debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message) +void GLDevice::debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message) { ::OutputDebugStringA("GL: "); ::OutputDebugStringA(message); @@ -769,12 +811,12 @@ void GLRenderer::debugCallback(GLenum source, GLenum type, GLuint id, GLenum sev } } -/* static */void APIENTRY GLRenderer::staticDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) +/* static */void APIENTRY GLDevice::staticDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { - ((GLRenderer*)userParam)->debugCallback(source, type, id, severity, length, message); + ((GLDevice*)userParam)->debugCallback(source, type, id, severity, length, message); } -/* static */GLRenderer::VertexAttributeFormat GLRenderer::getVertexAttributeFormat(Format format) +/* static */GLDevice::VertexAttributeFormat GLDevice::getVertexAttributeFormat(Format format) { switch (format) { @@ -791,7 +833,7 @@ void GLRenderer::debugCallback(GLenum source, GLenum type, GLuint id, GLenum sev } } -void GLRenderer::bindBufferImpl(int target, UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets) +void GLDevice::bindBufferImpl(int target, UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets) { for (UInt ii = 0; ii < slotCount; ++ii) { @@ -806,7 +848,7 @@ void GLRenderer::bindBufferImpl(int target, UInt startSlot, UInt slotCount, Buff } } -void GLRenderer::flushStateForDraw() +void GLDevice::flushStateForDraw() { if (m_currentFramebuffer) { @@ -907,7 +949,7 @@ void GLRenderer::flushStateForDraw() } } -GLuint GLRenderer::loadShader(GLenum stage, const char* source) +GLuint GLDevice::loadShader(GLenum stage, const char* source) { // GLSL is monumentally stupid. It officially requires the `#version` directive // to be the first thing in the file, which wouldn't be so bad but the API @@ -1076,9 +1118,9 @@ void destroyWindow(WindowHandle window) #endif } -GLRenderer::GLRenderer() { m_weakRenderer = new WeakSink<GLRenderer>(this); } +GLDevice::GLDevice() { m_weakRenderer = new WeakSink<GLDevice>(this); } -GLRenderer::~GLRenderer() +GLDevice::~GLDevice() { // We can destroy things whilst in this state m_currentPipelineState.setNull(); @@ -1093,7 +1135,7 @@ GLRenderer::~GLRenderer() } destroyWindow(m_windowHandle); - // By resetting the weak pointer, other objects accessing through WeakSink<GLRenderer> will no + // By resetting the weak pointer, other objects accessing through WeakSink<GLDevice> will no // longer be able to access this object which is entering a 'being destroyed' to 'destroyed' // state if (m_weakRenderer) @@ -1103,7 +1145,7 @@ GLRenderer::~GLRenderer() } } -HGLRC GLRenderer::createGLContext(HDC hdc) +HGLRC GLDevice::createGLContext(HDC hdc) { PIXELFORMATDESCRIPTOR pixelFormatDesc = {sizeof(PIXELFORMATDESCRIPTOR)}; pixelFormatDesc.nVersion = 1; @@ -1128,12 +1170,22 @@ HGLRC GLRenderer::createGLContext(HDC hdc) return newGLContext; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::initialize(const Desc& desc) +SLANG_NO_THROW Result SLANG_MCALL GLDevice::initialize(const Desc& desc) { SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_GLSL, "glsl_440")); SLANG_RETURN_ON_FAIL(GraphicsAPIRenderer::initialize(desc)); + // Initialize DeviceInfo + { + m_info.deviceType = DeviceType::OpenGl; + m_info.bindingStyle = BindingStyle::OpenGl; + m_info.projectionStyle = ProjectionStyle::OpenGl; + m_info.apiName = "OpenGL"; + static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + ::memcpy(m_info.identityProjectionMatrix, kIdentity, sizeof(kIdentity)); + } + m_windowHandle = createWindow(); m_desc = desc; @@ -1154,6 +1206,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::initialize(const Desc& desc) wglMakeCurrent(m_hdc, m_glContext); auto renderer = glGetString(GL_RENDERER); + m_info.adapterName = (char*)renderer; if (renderer && desc.adapter) { @@ -1175,6 +1228,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::initialize(const Desc& desc) } } + auto extensions = glGetString(GL_EXTENSIONS); // Load each of our extension functions by name @@ -1214,11 +1268,12 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::initialize(const Desc& desc) glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(staticDebugCallback, this); } + return SLANG_OK; } SLANG_NO_THROW void SLANG_MCALL - GLRenderer::clearFrame(uint32_t mask, bool clearDepth, bool clearStencil) + GLDevice::clearFrame(uint32_t mask, bool clearDepth, bool clearStencil) { uint32_t clearMask = 0; if (clearDepth) @@ -1284,7 +1339,7 @@ SLANG_NO_THROW void SLANG_MCALL } } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createSwapchain( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createSwapchain( const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) { RefPtr<SwapchainImpl> swapchain = new SwapchainImpl(); @@ -1294,7 +1349,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createSwapchain( return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createFramebufferLayout( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createFramebufferLayout( const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) { RefPtr<FramebufferLayoutImpl> layout = new FramebufferLayoutImpl(); @@ -1318,7 +1373,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createFramebufferLayout( } SLANG_NO_THROW Result SLANG_MCALL - GLRenderer::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) + GLDevice::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) { RefPtr<FramebufferImpl> framebuffer = new FramebufferImpl(m_weakRenderer); framebuffer->renderTargetViews.setCount(desc.renderTargetCount); @@ -1333,18 +1388,18 @@ SLANG_NO_THROW Result SLANG_MCALL return SLANG_OK; } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setFramebuffer(IFramebuffer* frameBuffer) +SLANG_NO_THROW void SLANG_MCALL GLDevice::setFramebuffer(IFramebuffer* frameBuffer) { m_currentFramebuffer = static_cast<FramebufferImpl*>(frameBuffer); } -void GLRenderer::setStencilReference(uint32_t referenceValue) +void GLDevice::setStencilReference(uint32_t referenceValue) { m_stencilRef = referenceValue; // TODO: actually set the stencil state. } -void GLRenderer::copyBuffer( +void GLDevice::copyBuffer( IBufferResource* dst, size_t dstOffset, IBufferResource* src, @@ -1358,7 +1413,7 @@ void GLRenderer::copyBuffer( glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, size); } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::readTextureResource( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::readTextureResource( ITextureResource* texture, ResourceState state, ISlangBlob** outBlob, size_t* outRowPitch, size_t* outPixelSize) { SLANG_UNUSED(state); @@ -1392,7 +1447,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::readTextureResource( return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createTextureResource( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createTextureResource( IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, @@ -1610,7 +1665,7 @@ static GLenum _calcTarget(IResource::Usage usage) } } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createBufferResource( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createBufferResource( IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, @@ -1635,7 +1690,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createBufferResource( } SLANG_NO_THROW Result SLANG_MCALL - GLRenderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) + GLDevice::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) { GLuint samplerID; glCreateSamplers(1, &samplerID); @@ -1646,7 +1701,7 @@ SLANG_NO_THROW Result SLANG_MCALL return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createTextureView( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createTextureView( ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = static_cast<TextureResourceImpl*>(texture); @@ -1660,7 +1715,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createTextureView( return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createBufferView( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createBufferView( IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (BufferResourceImpl*) buffer; @@ -1674,7 +1729,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createBufferView( return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createInputLayout( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createInputLayout( const InputElementDesc* inputElements, UInt inputElementCount, IInputLayout** outLayout) { RefPtr<InputLayoutImpl> inputLayout = new InputLayoutImpl; @@ -1694,7 +1749,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createInputLayout( return SLANG_OK; } -void* GLRenderer::map(IBufferResource* bufferIn, MapFlavor flavor) +void* GLDevice::map(IBufferResource* bufferIn, MapFlavor flavor) { BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(bufferIn); @@ -1717,13 +1772,13 @@ void* GLRenderer::map(IBufferResource* bufferIn, MapFlavor flavor) return glMapBuffer(buffer->m_target, access); } -void GLRenderer::unmap(IBufferResource* bufferIn) +void GLDevice::unmap(IBufferResource* bufferIn) { BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(bufferIn); glUnmapBuffer(buffer->m_target); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setPrimitiveTopology(PrimitiveTopology topology) +SLANG_NO_THROW void SLANG_MCALL GLDevice::setPrimitiveTopology(PrimitiveTopology topology) { GLenum glTopology = 0; switch (topology) @@ -1737,7 +1792,7 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::setPrimitiveTopology(PrimitiveTopolo m_boundPrimitiveTopology = glTopology; } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setVertexBuffers( +SLANG_NO_THROW void SLANG_MCALL GLDevice::setVertexBuffers( UInt startSlot, UInt slotCount, IBufferResource* const* buffers, @@ -1758,11 +1813,11 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::setVertexBuffers( } SLANG_NO_THROW void SLANG_MCALL - GLRenderer::setIndexBuffer(IBufferResource* buffer, Format indexFormat, UInt offset) + GLDevice::setIndexBuffer(IBufferResource* buffer, Format indexFormat, UInt offset) { } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setViewports(UInt count, Viewport const* viewports) +SLANG_NO_THROW void SLANG_MCALL GLDevice::setViewports(UInt count, Viewport const* viewports) { assert(count == 1); auto viewport = viewports[0]; @@ -1774,7 +1829,7 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::setViewports(UInt count, Viewport co glDepthRange(viewport.minZ, viewport.maxZ); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setScissorRects(UInt count, ScissorRect const* rects) +SLANG_NO_THROW void SLANG_MCALL GLDevice::setScissorRects(UInt count, ScissorRect const* rects) { assert(count <= 1); if( count ) @@ -1802,7 +1857,7 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::setScissorRects(UInt count, ScissorR } } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setPipelineState(IPipelineState* state) +SLANG_NO_THROW void SLANG_MCALL GLDevice::setPipelineState(IPipelineState* state) { auto pipelineStateImpl = static_cast<PipelineStateImpl*>(state); @@ -1813,7 +1868,7 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::setPipelineState(IPipelineState* sta glUseProgram(programID); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::draw(UInt vertexCount, UInt startVertex = 0) +SLANG_NO_THROW void SLANG_MCALL GLDevice::draw(UInt vertexCount, UInt startVertex = 0) { flushStateForDraw(); @@ -1821,17 +1876,17 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::draw(UInt vertexCount, UInt startVer } SLANG_NO_THROW void SLANG_MCALL - GLRenderer::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) + GLDevice::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) { assert(!"unimplemented"); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::dispatchCompute(int x, int y, int z) +SLANG_NO_THROW void SLANG_MCALL GLDevice::dispatchCompute(int x, int y, int z) { glDispatchCompute(x, y, z); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::DescriptorSetImpl::setConstantBuffer( +SLANG_NO_THROW void SLANG_MCALL GLDevice::DescriptorSetImpl::setConstantBuffer( UInt range, UInt index, IBufferResource* buffer) { auto resourceImpl = (BufferResourceImpl*) buffer; @@ -1844,7 +1899,7 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::DescriptorSetImpl::setConstantBuffer } SLANG_NO_THROW void SLANG_MCALL - GLRenderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) + GLDevice::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) { auto viewImpl = static_cast<ResourceViewImpl*>(view); @@ -1864,12 +1919,12 @@ SLANG_NO_THROW void SLANG_MCALL } SLANG_NO_THROW void SLANG_MCALL - GLRenderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) + GLDevice::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) { assert(!"unsupported"); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::DescriptorSetImpl::setCombinedTextureSampler( +SLANG_NO_THROW void SLANG_MCALL GLDevice::DescriptorSetImpl::setCombinedTextureSampler( UInt range, UInt index, IResourceView* textureView, @@ -1886,16 +1941,16 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::DescriptorSetImpl::setCombinedTextur m_samplers[arrayIndex] = samplerImpl; } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::DescriptorSetImpl::setRootConstants( +SLANG_NO_THROW void SLANG_MCALL GLDevice::DescriptorSetImpl::setRootConstants( UInt range, UInt offset, UInt size, void const* data) { - SLANG_UNEXPECTED("unimplemented: setRootConstants for GlRenderer"); + SLANG_UNEXPECTED("unimplemented: setRootConstants for GLDevice"); } -SLANG_NO_THROW void SLANG_MCALL GLRenderer::setDescriptorSet( +SLANG_NO_THROW void SLANG_MCALL GLDevice::setDescriptorSet( PipelineType pipelineType, IPipelineLayout* layout, UInt index, IDescriptorSet* descriptorSet) { auto descriptorSetImpl = (DescriptorSetImpl*)descriptorSet; @@ -1905,7 +1960,7 @@ SLANG_NO_THROW void SLANG_MCALL GLRenderer::setDescriptorSet( m_boundDescriptorSets[index] = descriptorSetImpl; } -SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createDescriptorSetLayout( +SLANG_NO_THROW Result SLANG_MCALL GLDevice::createDescriptorSetLayout( const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) { RefPtr<DescriptorSetLayoutImpl> layoutImpl = new DescriptorSetLayoutImpl(); @@ -1957,7 +2012,7 @@ SLANG_NO_THROW Result SLANG_MCALL GLRenderer::createDescriptorSetLayout( } SLANG_NO_THROW Result SLANG_MCALL - GLRenderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) + GLDevice::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) { RefPtr<PipelineLayoutImpl> layoutImpl = new PipelineLayoutImpl(); @@ -1986,7 +2041,7 @@ SLANG_NO_THROW Result SLANG_MCALL } SLANG_NO_THROW Result SLANG_MCALL - GLRenderer::createDescriptorSet(IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) + GLDevice::createDescriptorSet(IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) { SLANG_UNUSED(flag); @@ -2022,7 +2077,7 @@ SLANG_NO_THROW Result SLANG_MCALL return SLANG_OK; } -Result GLRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) +Result GLDevice::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) { @@ -2093,7 +2148,7 @@ Result GLRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgra return SLANG_OK; } -Result GLRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) +Result GLDevice::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) { GraphicsPipelineStateDesc desc = inDesc; preparePipelineDesc(desc); @@ -2108,7 +2163,7 @@ Result GLRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& return SLANG_OK; } -Result GLRenderer::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) +Result GLDevice::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) { ComputePipelineStateDesc desc = inDesc; preparePipelineDesc(desc); diff --git a/tools/gfx/open-gl/render-gl.h b/tools/gfx/open-gl/render-gl.h index 7d0d0f3dd..8595e95d3 100644 --- a/tools/gfx/open-gl/render-gl.h +++ b/tools/gfx/open-gl/render-gl.h @@ -5,6 +5,6 @@ namespace gfx { -SlangResult SLANG_MCALL createGLRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer); +SlangResult SLANG_MCALL createGLDevice(const IDevice::Desc* desc, IDevice** outDevice); } // gfx diff --git a/tools/gfx/render-graphics-common.cpp b/tools/gfx/render-graphics-common.cpp index 2e460982e..10713e92b 100644 --- a/tools/gfx/render-graphics-common.cpp +++ b/tools/gfx/render-graphics-common.cpp @@ -414,7 +414,7 @@ public: struct Builder : Super::Builder { - Builder(IRenderer* renderer) + Builder(IDevice* renderer) : Super::Builder(static_cast<RendererBase*>(renderer)) {} @@ -712,18 +712,18 @@ class GraphicsCommonShaderObject : public ShaderObjectBase { public: static Result create( - IRenderer* renderer, + IDevice* device, GraphicsCommonShaderObjectLayout* layout, GraphicsCommonShaderObject** outShaderObject) { auto object = ComPtr<GraphicsCommonShaderObject>(new GraphicsCommonShaderObject()); - SLANG_RETURN_ON_FAIL(object->init(renderer, layout)); + SLANG_RETURN_ON_FAIL(object->init(device, layout)); *outShaderObject = object.detach(); return SLANG_OK; } - RendererBase* getRenderer() { return m_layout->getRenderer(); } + RendererBase* getDevice() { return m_layout->getDevice(); } SLANG_NO_THROW UInt SLANG_MCALL getEntryPointCount() SLANG_OVERRIDE { return 0; } @@ -1011,7 +1011,7 @@ public: protected: friend class ProgramVars; - Result init(IRenderer* renderer, GraphicsCommonShaderObjectLayout* layout) + Result init(IDevice* device, GraphicsCommonShaderObjectLayout* layout) { m_layout = layout; @@ -1075,7 +1075,7 @@ protected: { RefPtr<GraphicsCommonShaderObject> subObject; SLANG_RETURN_ON_FAIL( - GraphicsCommonShaderObject::create(renderer, subObjectLayout, subObject.writeRef())); + GraphicsCommonShaderObject::create(device, subObjectLayout, subObject.writeRef())); m_objects[bindingRangeInfo.baseIndex + i] = subObject; } } @@ -1251,11 +1251,11 @@ protected: // Once we have computed how large the buffer should be, we can allocate // it using the existing public `IRenderer` API. // - IRenderer* renderer = getRenderer(); + IDevice* device = getRenderer(); IBufferResource::Desc bufferDesc; bufferDesc.init(specializedOrdinaryDataSize); bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; - SLANG_RETURN_ON_FAIL(renderer->createBufferResource( + SLANG_RETURN_ON_FAIL(device->createBufferResource( IResource::Usage::ConstantBuffer, bufferDesc, nullptr, m_ordinaryDataBuffer.writeRef())); // Once the buffer is allocated, we can use `_writeOrdinaryData` to fill it in. @@ -1517,10 +1517,10 @@ class EntryPointVars : public GraphicsCommonShaderObject public: static Result - create(IRenderer* renderer, EntryPointLayout* layout, EntryPointVars** outShaderObject) + create(IDevice* device, EntryPointLayout* layout, EntryPointVars** outShaderObject) { RefPtr<EntryPointVars> object = new EntryPointVars(); - SLANG_RETURN_ON_FAIL(object->init(renderer, layout)); + SLANG_RETURN_ON_FAIL(object->init(device, layout)); *outShaderObject = object.detach(); return SLANG_OK; @@ -1529,9 +1529,9 @@ public: EntryPointLayout* getLayout() { return static_cast<EntryPointLayout*>(m_layout.Ptr()); } protected: - Result init(IRenderer* renderer, EntryPointLayout* layout) + Result init(IDevice* device, EntryPointLayout* layout) { - SLANG_RETURN_ON_FAIL(Super::init(renderer, layout)); + SLANG_RETURN_ON_FAIL(Super::init(device, layout)); return SLANG_OK; } }; @@ -1541,10 +1541,10 @@ class ProgramVars : public GraphicsCommonShaderObject typedef GraphicsCommonShaderObject Super; public: - static Result create(IRenderer* renderer, GraphicsCommonProgramLayout* layout, ProgramVars** outShaderObject) + static Result create(IDevice* device, GraphicsCommonProgramLayout* layout, ProgramVars** outShaderObject) { RefPtr<ProgramVars> object = new ProgramVars(); - SLANG_RETURN_ON_FAIL(object->init(renderer, layout)); + SLANG_RETURN_ON_FAIL(object->init(device, layout)); *outShaderObject = object.detach(); return SLANG_OK; @@ -1616,15 +1616,15 @@ protected: return SLANG_OK; } - Result init(IRenderer* renderer, GraphicsCommonProgramLayout* layout) + Result init(IDevice* device, GraphicsCommonProgramLayout* layout) { - SLANG_RETURN_ON_FAIL(Super::init(renderer, layout)); + SLANG_RETURN_ON_FAIL(Super::init(device, layout)); for (auto entryPointInfo : layout->getEntryPoints()) { RefPtr<EntryPointVars> entryPoint; SLANG_RETURN_ON_FAIL( - EntryPointVars::create(renderer, entryPointInfo.layout, entryPoint.writeRef())); + EntryPointVars::create(device, entryPointInfo.layout, entryPoint.writeRef())); m_entryPoints.add(entryPoint); } diff --git a/tools/gfx/render.cpp b/tools/gfx/render.cpp index 3a886aaa4..5ef2a454e 100644 --- a/tools/gfx/render.cpp +++ b/tools/gfx/render.cpp @@ -34,21 +34,9 @@ static const uint8_t s_formatSize[] = { uint8_t(sizeof(uint32_t)), // D_Unorm24_S8, }; -static const BindingStyle s_rendererTypeToBindingStyle[] = { - BindingStyle::Unknown, // Unknown, - BindingStyle::DirectX, // DirectX11, - BindingStyle::DirectX, // DirectX12, - BindingStyle::OpenGl, // OpenGl, - BindingStyle::Vulkan, // Vulkan - BindingStyle::CPU, // CPU - BindingStyle::CUDA, // CUDA -}; - static void _compileTimeAsserts() { SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(s_formatSize) == int(Format::CountOf)); - SLANG_COMPILE_TIME_ASSERT( - SLANG_COUNT_OF(s_rendererTypeToBindingStyle) == int(RendererType::CountOf)); } extern "C" @@ -58,59 +46,50 @@ extern "C" return s_formatSize[int(format)]; } - BindingStyle SLANG_MCALL gfxGetBindingStyle(RendererType type) - { - return s_rendererTypeToBindingStyle[int(type)]; - } - - const char* SLANG_MCALL gfxGetRendererName(RendererType type) + SLANG_GFX_API SlangResult SLANG_MCALL + gfxCreateDevice(const IDevice::Desc* desc, IDevice** outDevice) { - switch (type) - { - case RendererType::DirectX11: - return "DirectX11"; - case RendererType::DirectX12: - return "DirectX12"; - case RendererType::OpenGl: - return "OpenGL"; - case RendererType::Vulkan: - return "Vulkan"; - case RendererType::Unknown: - return "Unknown"; - case RendererType::CPU: - return "CPU"; - case RendererType::CUDA: - return "CUDA"; - default: - return "?!?"; - } - } - - SLANG_GFX_API SlangResult SLANG_MCALL gfxCreateRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer) - { - switch (desc->rendererType) + switch (desc->deviceType) { #if SLANG_WINDOWS_FAMILY - case RendererType::DirectX11: + case DeviceType::DirectX11: + { + return createD3D11Device(desc, outDevice); + } + case DeviceType::DirectX12: { - return createD3D11Renderer(desc, outRenderer); + return createD3D12Device(desc, outDevice); } - case RendererType::DirectX12: + case DeviceType::OpenGl: { - return createD3D12Renderer(desc, outRenderer); + return createGLDevice(desc, outDevice); } - case RendererType::OpenGl: + case DeviceType::Vulkan: { - return createGLRenderer(desc, outRenderer); + return createVKDevice(desc, outDevice); } - case RendererType::Vulkan: + case DeviceType::CUDA: { - return createVKRenderer(desc, outRenderer); + return createCUDADevice(desc, outDevice); } - case RendererType::CUDA: + case DeviceType::Default: { - return createCUDARenderer(desc, outRenderer); + IDevice::Desc newDesc = *desc; + newDesc.deviceType = DeviceType::DirectX12; + if (gfxCreateDevice(&newDesc, outDevice) == SLANG_OK) + return SLANG_OK; + newDesc.deviceType = DeviceType::Vulkan; + if (gfxCreateDevice(&newDesc, outDevice) == SLANG_OK) + return SLANG_OK; + newDesc.deviceType = DeviceType::DirectX11; + if (gfxCreateDevice(&newDesc, outDevice) == SLANG_OK) + return SLANG_OK; + newDesc.deviceType = DeviceType::OpenGl; + if (gfxCreateDevice(&newDesc, outDevice) == SLANG_OK) + return SLANG_OK; + return SLANG_FAIL; } + break; #endif default: @@ -118,29 +97,32 @@ extern "C" } } - ProjectionStyle SLANG_MCALL gfxGetProjectionStyle(RendererType type) + const char* SLANG_MCALL gfxGetDeviceTypeName(DeviceType type) { switch (type) { - case RendererType::DirectX11: - case RendererType::DirectX12: - { - return ProjectionStyle::DirectX; - } - case RendererType::OpenGl: - return ProjectionStyle::OpenGl; - case RendererType::Vulkan: - return ProjectionStyle::Vulkan; - case RendererType::Unknown: - return ProjectionStyle::Unknown; + case gfx::DeviceType::Unknown: + return "Unknown"; + case gfx::DeviceType::Default: + return "Default"; + case gfx::DeviceType::DirectX11: + return "DirectX11"; + case gfx::DeviceType::DirectX12: + return "DirectX12"; + case gfx::DeviceType::OpenGl: + return "OpenGL"; + case gfx::DeviceType::Vulkan: + return "Vulkan"; + case gfx::DeviceType::CPU: + return "CPU"; + case gfx::DeviceType::CUDA: + return "CUDA"; default: - { - assert(!"Unhandled type"); - return ProjectionStyle::Unknown; - } + return "?"; } } + void SLANG_MCALL gfxGetIdentityProjection(ProjectionStyle style, float projMatrix[16]) { switch (style) diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 1ad7e2aac..1222768db 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -113,7 +113,7 @@ gfx::StageType mapStage(SlangStage stage) } } -Result createProgramFromSlang(IRenderer* renderer, IShaderProgram::Desc const& originalDesc, IShaderProgram** outProgram) +Result createProgramFromSlang(IDevice* device, IShaderProgram::Desc const& originalDesc, IShaderProgram** outProgram) { SlangInt targetIndex = 0; auto slangProgram = originalDesc.slangProgram; @@ -153,7 +153,7 @@ Result createProgramFromSlang(IRenderer* renderer, IShaderProgram::Desc const& o programDesc.kernelCount = kernelDescs.getCount(); programDesc.kernels = kernelDescs.getBuffer(); - return renderer->createProgram(programDesc, outProgram); + return device->createProgram(programDesc, outProgram); } IShaderObject* gfx::ShaderObjectBase::getInterface(const Guid& guid) @@ -258,11 +258,11 @@ void PipelineStateBase::initializeBase(const PipelineStateDesc& inDesc) } } -IRenderer* gfx::RendererBase::getInterface(const Guid& guid) +IDevice* gfx::RendererBase::getInterface(const Guid& guid) { return (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IRenderer) - ? static_cast<IRenderer*>(this) - : nullptr; + ? static_cast<IDevice*>(this) + : nullptr; } SLANG_NO_THROW Result SLANG_MCALL RendererBase::initialize(const Desc& desc) diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index 5846aad34..9fe9768f4 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -99,7 +99,10 @@ protected: Desc m_desc; }; -Result createProgramFromSlang(IRenderer* renderer, IShaderProgram::Desc const& desc, IShaderProgram** outProgram); +Result createProgramFromSlang( + IDevice* device, + IShaderProgram::Desc const& desc, + IShaderProgram** outProgram); class RendererBase; @@ -147,7 +150,7 @@ protected: ShaderComponentID m_componentID = 0; public: - RendererBase* getRenderer() { return m_renderer; } + RendererBase* getDevice() { return m_renderer; } slang::TypeLayoutReflection* getElementTypeLayout() { @@ -191,7 +194,7 @@ public: // this function will return a specialized type using the bound sub-objects' type as specialization argument. virtual Result getSpecializedShaderObjectType(ExtendedShaderObjectType* outType); - RendererBase* getRenderer() { return m_layout->getRenderer(); } + RendererBase* getRenderer() { return m_layout->getDevice(); } SLANG_NO_THROW UInt SLANG_MCALL getEntryPointCount() SLANG_OVERRIDE { return 0; } @@ -369,7 +372,7 @@ protected: // Renderer implementation shared by all platforms. // Responsible for shader compilation, specialization and caching. -class RendererBase : public Slang::RefObject, public IRenderer +class RendererBase : public Slang::RefObject, public IDevice { friend class ShaderObjectBase; public: @@ -379,7 +382,7 @@ public: const char** outFeatures, UInt bufferSize, UInt* outFeatureCount) SLANG_OVERRIDE; virtual SLANG_NO_THROW bool SLANG_MCALL hasFeature(const char* featureName) SLANG_OVERRIDE; virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) SLANG_OVERRIDE; - IRenderer* getInterface(const Slang::Guid& guid); + IDevice* getInterface(const Slang::Guid& guid); virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(slang::TypeReflection* type, IShaderObject** outObject) SLANG_OVERRIDE; diff --git a/tools/gfx/slang-context.h b/tools/gfx/slang-context.h index 909bcaa1c..d5bf261e4 100644 --- a/tools/gfx/slang-context.h +++ b/tools/gfx/slang-context.h @@ -9,7 +9,7 @@ namespace gfx public: Slang::ComPtr<slang::IGlobalSession> globalSession; Slang::ComPtr<slang::ISession> session; - Result initialize(const gfx::IRenderer::SlangDesc& desc, SlangCompileTarget compileTarget, const char* defaultProfileName) + Result initialize(const gfx::IDevice::SlangDesc& desc, SlangCompileTarget compileTarget, const char* defaultProfileName) { if (desc.slangGlobalSession) { diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 859519c6d..c0ece3e2f 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -11,7 +11,6 @@ #include "vk-api.h" #include "vk-util.h" #include "vk-device-queue.h" -#include "vk-swap-chain.h" // Vulkan has a different coordinate system to ogl // http://anki3d.org/vulkan-coordinate-system/ @@ -34,7 +33,7 @@ namespace gfx { using namespace Slang; -class VKRenderer : public GraphicsAPIRenderer +class VKDevice : public GraphicsAPIRenderer { public: enum @@ -111,12 +110,12 @@ public: size_t size, ISlangBlob** outBlob) override; void waitForGpu(); - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const override + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { - return RendererType::Vulkan; + return m_info; } /// Dtor - ~VKRenderer(); + ~VKDevice(); class Buffer { @@ -167,7 +166,7 @@ public: public: typedef BufferResource Parent; - BufferResourceImpl(IResource::Usage initialUsage, const IBufferResource::Desc& desc, VKRenderer* renderer): + BufferResourceImpl(IResource::Usage initialUsage, const IBufferResource::Desc& desc, VKDevice* renderer): Parent(desc), m_renderer(renderer), m_initialUsage(initialUsage) @@ -176,7 +175,7 @@ public: } IResource::Usage m_initialUsage; - VKRenderer* m_renderer; + VKDevice* m_renderer; Buffer m_buffer; Buffer m_uploadBuffer; }; @@ -322,7 +321,7 @@ public: public: VkRenderPass m_renderPass; - VKRenderer* m_renderer; + VKDevice* m_renderer; Array<VkAttachmentDescription, kMaxAttachments> m_attachmentDescs; Array<VkAttachmentReference, kMaxRenderTargets> m_colorReferences; VkAttachmentReference m_depthReference; @@ -333,7 +332,7 @@ public: { m_renderer->m_api.vkDestroyRenderPass(m_renderer->m_api.m_device, m_renderPass, nullptr); } - Result init(VKRenderer* renderer, const IFramebufferLayout::Desc& desc) + Result init(VKDevice* renderer, const IFramebufferLayout::Desc& desc) { m_renderer = renderer; m_renderTargetCount = desc.renderTargetCount; @@ -435,7 +434,7 @@ public: public: VkRenderPass m_renderPass; - VKRenderer* m_renderer; + VKDevice* m_renderer; ~RenderPassLayoutImpl() { @@ -467,7 +466,7 @@ public: } } - Result init(VKRenderer* renderer, const IRenderPassLayout::Desc& desc) + Result init(VKDevice* renderer, const IRenderPassLayout::Desc& desc) { m_renderer = renderer; @@ -548,7 +547,7 @@ public: ComPtr<IResourceView> depthStencilView; uint32_t m_width; uint32_t m_height; - VKRenderer* m_renderer; + VKDevice* m_renderer; VkClearValue m_clearValues[kMaxAttachments]; RefPtr<FramebufferLayoutImpl> m_layout; public: @@ -556,7 +555,7 @@ public: { m_renderer->m_api.vkDestroyFramebuffer(m_renderer->m_api.m_device, m_handle, nullptr); } - Result init(VKRenderer* renderer, const IFramebuffer::Desc& desc) + Result init(VKDevice* renderer, const IFramebuffer::Desc& desc) { m_renderer = renderer; auto dsv = desc.depthStencilView @@ -791,7 +790,7 @@ public: return nullptr; } public: - DescriptorSetImpl(VKRenderer* renderer) + DescriptorSetImpl(VKDevice* renderer) : m_renderer(renderer) { } @@ -818,7 +817,7 @@ public: UInt size, void const* data) override; - VKRenderer* m_renderer = nullptr; ///< Weak pointer, can't be strong, because if set will become circular reference + VKDevice* m_renderer = nullptr; ///< Weak pointer, can't be strong, because if set will become circular reference RefPtr<DescriptorSetLayoutImpl> m_layout; VulkanDescriptorSet m_descriptorSet = {}; @@ -892,14 +891,14 @@ public: VkCommandBuffer m_commandBuffer; VkCommandBuffer m_preCommandBuffer = VK_NULL_HANDLE; VkCommandPool m_pool; - VKRenderer* m_renderer; + VKDevice* m_renderer; DescriptorSetAllocator* m_transientDescSetAllocator; // Command buffers are deallocated by its command pool, // so no need to free individually. ~CommandBufferImpl() = default; Result init( - VKRenderer* renderer, + VKDevice* renderer, VkCommandPool pool, DescriptorSetAllocator* transientDescSetAllocator) { @@ -1107,7 +1106,7 @@ public: m_boundPipelines[pipelineBindPointId] = pipeline->m_pipeline; } - // Next we bind all the descriptor sets that were set in the `VKRenderer`. + // Next we bind all the descriptor sets that were set in the `VKDevice`. // auto pipelineLayoutImpl = static_cast<PipelineLayoutImpl*>(pipeline->m_pipelineLayout.get()); auto vkPipelineLayout = pipelineLayoutImpl->m_pipelineLayout; @@ -1656,7 +1655,7 @@ public: public: Desc m_desc; uint32_t m_poolIndex; - RefPtr<VKRenderer> m_renderer; + RefPtr<VKDevice> m_renderer; VkQueue m_queue; uint32_t m_queueFamilyIndex; VkSemaphore m_pendingWaitSemaphore = VK_NULL_HANDLE; @@ -1682,7 +1681,7 @@ public: } } - void init(VKRenderer* renderer, VkQueue queue, uint32_t queueFamilyIndex) + void init(VKDevice* renderer, VkQueue queue, uint32_t queueFamilyIndex) { m_renderer = renderer; m_poolIndex = 0; @@ -1803,94 +1802,347 @@ public: } public: - VulkanSwapChain m_swapChain; + struct PlatformDesc + {}; + +#if SLANG_WINDOWS_FAMILY + struct WinPlatformDesc : public PlatformDesc + { + HINSTANCE m_hinstance; + HWND m_hwnd; + }; +#else + struct XPlatformDesc : public PlatformDesc + { + Display* m_display; + Window m_window; + }; +#endif + public: + VkSwapchainKHR m_swapChain; + VkSurfaceKHR m_surface; VkSemaphore m_nextImageSemaphore; // Semaphore to signal after `acquireNextImage`. ISwapchain::Desc m_desc; + VkFormat m_vkformat; RefPtr<CommandQueueImpl> m_queue; ShortList<RefPtr<TextureResourceImpl>> m_images; - RefPtr<VKRenderer> m_renderer; + RefPtr<VKDevice> m_renderer; + VulkanApi* m_api; uint32_t m_currentImageIndex = 0; + WindowHandle m_windowHandle; + void destroySwapchainAndImages() + { + m_api->vkQueueWaitIdle(m_queue->m_queue); + if (m_swapChain != VK_NULL_HANDLE) + { + m_api->vkDestroySwapchainKHR(m_api->m_device, m_swapChain, nullptr); + m_swapChain = VK_NULL_HANDLE; + } + + // Mark that it is no longer used + m_images.clear(); + } + + void getWindowSize(int* widthOut, int* heightOut) const + { +#if SLANG_WINDOWS_FAMILY + RECT rc; + ::GetClientRect((HWND)m_windowHandle.handleValues[0], &rc); + *widthOut = rc.right - rc.left; + *heightOut = rc.bottom - rc.top; +#else + auto platformDesc = _getPlatformDesc<XPlatformDesc>(); + + XWindowAttributes winAttr = {}; + XGetWindowAttributes( + (Display*)m_windowHandle.handleValues[0], + (Window)m_windowHandle.handleValues[1], + &winAttr); + + *widthOut = winAttr.width; + *heightOut = winAttr.height; +#endif + } + + Result createSwapchainAndImages() + { + int width, height; + getWindowSize(&width, &height); + + VkExtent2D imageExtent = {}; + imageExtent.width = width; + imageExtent.height = height; + + m_desc.width = width; + m_desc.height = height; + + // catch this before throwing error + if (width == 0 || height == 0) + { + return SLANG_FAIL; + } + + // It is necessary to query the caps -> otherwise the LunarG verification layer will + // issue an error + { + VkSurfaceCapabilitiesKHR surfaceCaps; + + SLANG_VK_RETURN_ON_FAIL(m_api->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + m_api->m_physicalDevice, m_surface, &surfaceCaps)); + } + + VkPresentModeKHR presentMode; + List<VkPresentModeKHR> presentModes; + uint32_t numPresentModes = 0; + m_api->vkGetPhysicalDeviceSurfacePresentModesKHR( + m_api->m_physicalDevice, m_surface, &numPresentModes, nullptr); + presentModes.setCount(numPresentModes); + m_api->vkGetPhysicalDeviceSurfacePresentModesKHR( + m_api->m_physicalDevice, m_surface, &numPresentModes, presentModes.getBuffer()); + { + int numCheckPresentOptions = 3; + VkPresentModeKHR presentOptions[] = { + VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_MAILBOX_KHR, + VK_PRESENT_MODE_FIFO_KHR}; + if (m_desc.enableVSync) + { + presentOptions[0] = VK_PRESENT_MODE_FIFO_KHR; + presentOptions[1] = VK_PRESENT_MODE_IMMEDIATE_KHR; + presentOptions[2] = VK_PRESENT_MODE_MAILBOX_KHR; + } + + presentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; // Invalid + + // Find the first option that's available on the device + for (int j = 0; j < numCheckPresentOptions; j++) + { + if (presentModes.indexOf(presentOptions[j]) != Index(-1)) + { + presentMode = presentOptions[j]; + break; + } + } + + if (presentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) + { + return SLANG_FAIL; + } + } + + VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE; + + VkSwapchainCreateInfoKHR swapchainDesc = {}; + swapchainDesc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainDesc.surface = m_surface; + swapchainDesc.minImageCount = m_desc.imageCount; + swapchainDesc.imageFormat = m_vkformat; + swapchainDesc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + swapchainDesc.imageExtent = imageExtent; + swapchainDesc.imageArrayLayers = 1; + swapchainDesc.imageUsage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + swapchainDesc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchainDesc.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + swapchainDesc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchainDesc.presentMode = presentMode; + swapchainDesc.clipped = VK_TRUE; + swapchainDesc.oldSwapchain = oldSwapchain; + + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateSwapchainKHR( + m_api->m_device, &swapchainDesc, nullptr, &m_swapChain)); + + uint32_t numSwapChainImages = 0; + m_api->vkGetSwapchainImagesKHR( + m_api->m_device, m_swapChain, &numSwapChainImages, nullptr); + List<VkImage> vkImages; + { + vkImages.setCount(numSwapChainImages); + m_api->vkGetSwapchainImagesKHR( + m_api->m_device, m_swapChain, &numSwapChainImages, vkImages.getBuffer()); + } + + for (uint32_t i = 0; i < m_desc.imageCount; i++) + { + ITextureResource::Desc imageDesc = {}; + + imageDesc.init2D( + IResource::Type::Texture2D, m_desc.format, m_desc.width, m_desc.height, 1); + RefPtr<TextureResourceImpl> image = new TextureResourceImpl( + imageDesc, gfx::IResource::Usage::RenderTarget, m_api); + image->m_image = vkImages[i]; + image->m_imageMemory = 0; + image->m_vkformat = m_vkformat; + image->m_isWeakImageReference = true; + m_images.add(image); + } + return SLANG_OK; + } public: ~SwapchainImpl() { - m_swapChain.destroy(); + destroySwapchainAndImages(); + if (m_surface) + { + m_api->vkDestroySurfaceKHR(m_api->m_instance, m_surface, nullptr); + m_surface = VK_NULL_HANDLE; + } m_renderer->m_api.vkDestroySemaphore( m_renderer->m_api.m_device, m_nextImageSemaphore, nullptr); } - Result init(VKRenderer* renderer, const ISwapchain::Desc& desc, WindowHandle window) + + static Index _indexOfFormat(List<VkSurfaceFormatKHR>& formatsIn, VkFormat format) + { + const Index numFormats = formatsIn.getCount(); + const VkSurfaceFormatKHR* formats = formatsIn.getBuffer(); + + for (Index i = 0; i < numFormats; ++i) + { + if (formats[i].format == format) + { + return i; + } + } + return -1; + } + + Result init(VKDevice* renderer, const ISwapchain::Desc& desc, WindowHandle window) { m_desc = desc; m_renderer = renderer; + m_api = &renderer->m_api; m_queue = static_cast<CommandQueueImpl*>(desc.queue); + m_windowHandle = window; VkSemaphoreCreateInfo semaphoreCreateInfo = {}; semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; SLANG_VK_RETURN_ON_FAIL(renderer->m_api.vkCreateSemaphore( renderer->m_api.m_device, &semaphoreCreateInfo, nullptr, &m_nextImageSemaphore)); - VulkanSwapChain::Desc swapchainDesc; - VulkanSwapChain::PlatformDesc* platformDesc = nullptr; - swapchainDesc.m_imageCount = desc.imageCount; - swapchainDesc.init(); - swapchainDesc.m_format = desc.format; - swapchainDesc.m_vsync = desc.enableVSync; + m_queue = static_cast<CommandQueueImpl*>(desc.queue); + + // Make sure it's not set initially + m_vkformat = VK_FORMAT_UNDEFINED; + #if SLANG_WINDOWS_FAMILY - VulkanSwapChain::WinPlatformDesc winPlatformDesc; - winPlatformDesc.m_hinstance = ::GetModuleHandle(nullptr); - winPlatformDesc.m_hwnd = (HWND)window.handleValues[0]; - platformDesc = &winPlatformDesc; + VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.hinstance = ::GetModuleHandle(nullptr); + surfaceCreateInfo.hwnd = (HWND)window.handleValues[0]; + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateWin32SurfaceKHR( + m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); +#else + VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.dpy = (Display*)window.handleValues[0]; + surfaceCreateInfo.window = (Window)window.handleValues[1]; + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateXlibSurfaceKHR( + m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); #endif - m_queue = static_cast<CommandQueueImpl*>(desc.queue); - SLANG_RETURN_ON_FAIL(m_swapChain.init( - &renderer->m_api, - m_queue->m_queue, - m_queue->m_queueFamilyIndex, - swapchainDesc, - platformDesc)); - m_desc.format = m_swapChain.getDesc().m_format; - m_desc.width = m_swapChain.getWidth(); - m_desc.height = m_swapChain.getHeight(); - m_desc.imageCount = m_swapChain.getDesc().m_imageCount; - auto& images = m_swapChain.getImages(); - for (uint32_t i = 0; i < desc.imageCount; i++) + VkBool32 supported = false; + m_api->vkGetPhysicalDeviceSurfaceSupportKHR( + m_api->m_physicalDevice, renderer->m_queueFamilyIndex, m_surface, &supported); + + uint32_t numSurfaceFormats = 0; + List<VkSurfaceFormatKHR> surfaceFormats; + m_api->vkGetPhysicalDeviceSurfaceFormatsKHR( + m_api->m_physicalDevice, m_surface, &numSurfaceFormats, nullptr); + surfaceFormats.setCount(int(numSurfaceFormats)); + m_api->vkGetPhysicalDeviceSurfaceFormatsKHR( + m_api->m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.getBuffer()); + + // Look for a suitable format + List<VkFormat> formats; + formats.add(VulkanUtil::getVkFormat(desc.format)); + // HACK! To check for a different format if couldn't be found + if (desc.format == Format::RGBA_Unorm_UInt8) { - ITextureResource::Desc imageDesc = {}; + formats.add(VK_FORMAT_B8G8R8A8_UNORM); + } - imageDesc.init2D( - IResource::Type::Texture2D, - m_swapChain.getDesc().m_format, - m_swapChain.getWidth(), - m_swapChain.getHeight(), - 1); - RefPtr<TextureResourceImpl> image = new TextureResourceImpl( - imageDesc, gfx::IResource::Usage::RenderTarget, &renderer->m_api); - image->m_image = images[i]; - image->m_imageMemory = 0; - image->m_vkformat = m_swapChain.getVkFormat(); - image->m_isWeakImageReference = true; - m_images.add(image); + for (Index i = 0; i < formats.getCount(); ++i) + { + VkFormat format = formats[i]; + if (_indexOfFormat(surfaceFormats, format) >= 0) + { + m_vkformat = format; + } + } + + if (m_vkformat == VK_FORMAT_UNDEFINED) + { + return SLANG_FAIL; } + + // Save the desc + m_desc = desc; + if (m_desc.format == Format::RGBA_Unorm_UInt8 && + m_vkformat == VK_FORMAT_B8G8R8A8_UNORM) + { + m_desc.format = Format::BGRA_Unorm_UInt8; + } + + SLANG_RETURN_ON_FAIL(createSwapchainAndImages()); return SLANG_OK; } virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() { return m_desc; } - virtual SLANG_NO_THROW Result getImage(uint32_t index, ITextureResource** outResource) + virtual SLANG_NO_THROW Result + SLANG_MCALL getImage(uint32_t index, ITextureResource** outResource) { + if (m_images.getCount() <= (Index)index) + return SLANG_FAIL; *outResource = m_images[index]; m_images[index]->addRef(); return SLANG_OK; } - virtual SLANG_NO_THROW Result present() + virtual SLANG_NO_THROW Result SLANG_MCALL resize(uint32_t width, uint32_t height) + { + SLANG_UNUSED(width); + SLANG_UNUSED(height); + destroySwapchainAndImages(); + return createSwapchainAndImages(); + } + virtual SLANG_NO_THROW Result SLANG_MCALL present() { - m_swapChain.present(m_queue->m_pendingWaitSemaphore); + uint32_t swapChainIndices[] = {uint32_t(m_currentImageIndex)}; + + VkPresentInfoKHR presentInfo = {}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &m_swapChain; + presentInfo.pImageIndices = swapChainIndices; + if (m_queue->m_pendingWaitSemaphore != VK_NULL_HANDLE) + { + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = &m_queue->m_pendingWaitSemaphore; + } + m_api->vkQueuePresentKHR(m_queue->m_queue, &presentInfo); m_queue->m_pendingWaitSemaphore = VK_NULL_HANDLE; return SLANG_OK; } - virtual SLANG_NO_THROW uint32_t acquireNextImage() + virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() { - m_currentImageIndex = (uint32_t)m_swapChain.nextFrontImageIndex(m_nextImageSemaphore); + if (!m_images.getCount()) + return -1; + + m_currentImageIndex = -1; + VkResult result = m_api->vkAcquireNextImageKHR( + m_api->m_device, + m_swapChain, + UINT64_MAX, + m_nextImageSemaphore, + VK_NULL_HANDLE, + (uint32_t*)&m_currentImageIndex); + + if (result != VK_SUCCESS) + { + m_currentImageIndex = -1; + destroySwapchainAndImages(); + return m_currentImageIndex; + } // Make the queue's next submit wait on `m_nextImageSemaphore`. m_queue->m_pendingWaitSemaphore = m_nextImageSemaphore; return m_currentImageIndex; @@ -1913,6 +2165,12 @@ public: void _transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout); +public: + // VKDevice members. + + DeviceInfo m_info; + String m_adapterName; + VkDebugReportCallbackEXT m_debugReportCallback; VkDevice m_device = VK_NULL_HANDLE; @@ -1930,9 +2188,9 @@ public: uint32_t m_queueAllocCount; }; -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VkRenderer::Buffer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VKDevice::Buffer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -Result VKRenderer::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBufferUsageFlags usage, VkMemoryPropertyFlags reqMemoryProperties) +Result VKDevice::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBufferUsageFlags usage, VkMemoryPropertyFlags reqMemoryProperties) { assert(!isInitialized()); @@ -1964,17 +2222,17 @@ Result VKRenderer::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBuffe return SLANG_OK; } -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VkRenderer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VKDevice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -Result SLANG_MCALL createVKRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer) +Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outRenderer) { - RefPtr<VKRenderer> result = new VKRenderer(); + RefPtr<VKDevice> result = new VKDevice(); SLANG_RETURN_ON_FAIL(result->initialize(*desc)); *outRenderer = result.detach(); return SLANG_OK; } -VKRenderer::~VKRenderer() +VKDevice::~VKDevice() { // Check the device queue is valid else, we can't wait on it.. if (m_deviceQueue.isValid()) @@ -1999,7 +2257,7 @@ VKRenderer::~VKRenderer() } -VkBool32 VKRenderer::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, +VkBool32 VKDevice::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg) { char const* severity = "message"; @@ -2031,13 +2289,13 @@ VkBool32 VKRenderer::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugRepo return VK_FALSE; } -/* static */VKAPI_ATTR VkBool32 VKAPI_CALL VKRenderer::debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, +/* static */VKAPI_ATTR VkBool32 VKAPI_CALL VKDevice::debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData) { - return ((VKRenderer*)pUserData)->handleDebugMessage(flags, objType, srcObject, location, msgCode, pLayerPrefix, pMsg); + return ((VKDevice*)pUserData)->handleDebugMessage(flags, objType, srcObject, location, msgCode, pLayerPrefix, pMsg); } -VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( +VkPipelineShaderStageCreateInfo VKDevice::compileEntryPoint( IShaderProgram::KernelDesc const& kernelDesc, VkShaderStageFlagBits stage, List<char>& outBuffer, @@ -2073,7 +2331,7 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!! -Result VKRenderer::initVulkanInstanceAndDevice(bool useValidationLayer) +Result VKDevice::initVulkanInstanceAndDevice(bool useValidationLayer) { m_queueAllocCount = 0; @@ -2212,6 +2470,14 @@ Result VKRenderer::initVulkanInstanceAndDevice(bool useValidationLayer) SLANG_RETURN_ON_FAIL(m_api.initPhysicalDevice(physicalDevices[selectedDeviceIndex])); + // Obtain the name of the selected adapter. + { + VkPhysicalDeviceProperties basicProps = {}; + m_api.vkGetPhysicalDeviceProperties(physicalDevices[selectedDeviceIndex], &basicProps); + m_adapterName = basicProps.deviceName; + m_info.adapterName = m_adapterName.begin(); + } + List<const char*> deviceExtensions; deviceExtensions.add(VK_KHR_SWAPCHAIN_EXTENSION_NAME); @@ -2354,8 +2620,18 @@ Result VKRenderer::initVulkanInstanceAndDevice(bool useValidationLayer) return SLANG_OK; } -SlangResult VKRenderer::initialize(const Desc& desc) +SlangResult VKDevice::initialize(const Desc& desc) { + // Initialize device info. + { + m_info.apiName = "Vulkan"; + m_info.bindingStyle = BindingStyle::Vulkan; + m_info.projectionStyle = ProjectionStyle::Vulkan; + m_info.deviceType = DeviceType::Vulkan; + static const float kIdentity[] = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + ::memcpy(m_info.identityProjectionMatrix, kIdentity, sizeof(kIdentity)); + } + m_desc = desc; SLANG_RETURN_ON_FAIL(GraphicsAPIRenderer::initialize(desc)); @@ -2374,12 +2650,12 @@ SlangResult VKRenderer::initialize(const Desc& desc) return SLANG_OK; } -void VKRenderer::waitForGpu() +void VKDevice::waitForGpu() { m_deviceQueue.flushAndWait(); } -Result VKRenderer::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) +Result VKDevice::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) { // Only support one queue for now. if (m_queueAllocCount != 0) @@ -2394,7 +2670,7 @@ Result VKRenderer::createCommandQueue(const ICommandQueue::Desc& desc, ICommandQ return SLANG_OK; } -Result VKRenderer::createSwapchain( +Result VKDevice::createSwapchain( const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) { RefPtr<SwapchainImpl> sc = new SwapchainImpl(); @@ -2403,7 +2679,7 @@ Result VKRenderer::createSwapchain( return SLANG_OK; } -Result VKRenderer::createFramebufferLayout(const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) +Result VKDevice::createFramebufferLayout(const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) { RefPtr<FramebufferLayoutImpl> layout = new FramebufferLayoutImpl(); SLANG_RETURN_ON_FAIL(layout->init(this, desc)); @@ -2411,7 +2687,7 @@ Result VKRenderer::createFramebufferLayout(const IFramebufferLayout::Desc& desc, return SLANG_OK; } -Result VKRenderer::createRenderPassLayout( +Result VKDevice::createRenderPassLayout( const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) { @@ -2421,7 +2697,7 @@ Result VKRenderer::createRenderPassLayout( return SLANG_OK; } -Result VKRenderer::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) +Result VKDevice::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) { RefPtr<FramebufferImpl> fb = new FramebufferImpl(); SLANG_RETURN_ON_FAIL(fb->init(this, desc)); @@ -2429,7 +2705,7 @@ Result VKRenderer::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffe return SLANG_OK; } -SlangResult VKRenderer::readTextureResource( +SlangResult VKDevice::readTextureResource( ITextureResource* texture, ResourceState state, ISlangBlob** outBlob, @@ -2443,7 +2719,7 @@ SlangResult VKRenderer::readTextureResource( return SLANG_FAIL; } -SlangResult VKRenderer::readBufferResource( +SlangResult VKDevice::readBufferResource( IBufferResource* inBuffer, size_t offset, size_t size, @@ -2616,7 +2892,7 @@ bool isStencilFormat(VkFormat format) return false; } -void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout) +void VKDevice::_transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout) { VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -2724,7 +3000,7 @@ size_t calcNumRows(Format format, int height) return (size_t)height; } -Result VKRenderer::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) +Result VKDevice::createTextureResource(IResource::Usage initialUsage, const ITextureResource::Desc& descIn, const ITextureResource::Data* initData, ITextureResource** outResource) { TextureResource::Desc desc(descIn); desc.setDefaults(initialUsage); @@ -2958,7 +3234,7 @@ Result VKRenderer::createTextureResource(IResource::Usage initialUsage, const IT return SLANG_OK; } -Result VKRenderer::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) +Result VKDevice::createBufferResource(IResource::Usage initialUsage, const IBufferResource::Desc& descIn, const void* initData, IBufferResource** outResource) { BufferResource::Desc desc(descIn); desc.setDefaults(initialUsage); @@ -3126,7 +3402,7 @@ static VkStencilOpState translateStencilState(DepthStencilOpDesc desc) return rs; } -Result VKRenderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) +Result VKDevice::createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) { VkSamplerCreateInfo samplerInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; @@ -3157,7 +3433,7 @@ Result VKRenderer::createSamplerState(ISamplerState::Desc const& desc, ISamplerS return SLANG_OK; } -Result VKRenderer::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) +Result VKDevice::createTextureView(ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = static_cast<TextureResourceImpl*>(texture); RefPtr<TextureResourceViewImpl> view = new TextureResourceViewImpl(&m_api); @@ -3234,7 +3510,7 @@ Result VKRenderer::createTextureView(ITextureResource* texture, IResourceView::D return SLANG_OK; } -Result VKRenderer::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) +Result VKDevice::createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) { auto resourceImpl = (BufferResourceImpl*) buffer; @@ -3308,7 +3584,7 @@ Result VKRenderer::createBufferView(IBufferResource* buffer, IResourceView::Desc } } -Result VKRenderer::createInputLayout(const InputElementDesc* elements, UInt numElements, IInputLayout** outLayout) +Result VKDevice::createInputLayout(const InputElementDesc* elements, UInt numElements, IInputLayout** outLayout) { RefPtr<InputLayoutImpl> layout(new InputLayoutImpl); @@ -3395,7 +3671,7 @@ static VkDescriptorType translateDescriptorType(DescriptorSlotType type) } } -Result VKRenderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) +Result VKDevice::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) { RefPtr<DescriptorSetLayoutImpl> descriptorSetLayoutImpl = new DescriptorSetLayoutImpl(m_api); @@ -3507,7 +3783,7 @@ Result VKRenderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc& d return SLANG_OK; } -Result VKRenderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) +Result VKDevice::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) { UInt descriptorSetCount = desc.descriptorSetCount; @@ -3569,7 +3845,7 @@ Result VKRenderer::createPipelineLayout(const IPipelineLayout::Desc& desc, IPipe return SLANG_OK; } -Result VKRenderer::createDescriptorSet( +Result VKDevice::createDescriptorSet( IDescriptorSetLayout* layout, IDescriptorSet::Flag::Enum flag, IDescriptorSet** outDescriptorSet) @@ -3588,7 +3864,7 @@ Result VKRenderer::createDescriptorSet( return SLANG_OK; } -void VKRenderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) +void VKDevice::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) { auto bufferImpl = (BufferResourceImpl*)buffer; @@ -3614,7 +3890,7 @@ void VKRenderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, IB m_boundObjects[boundObjectIndex] = dynamic_cast<RefObject*>(buffer); } -void VKRenderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) +void VKDevice::DescriptorSetImpl::setResource(UInt range, UInt index, IResourceView* view) { SLANG_ASSERT(range < UInt(m_layout->m_ranges.getCount())); auto& rangeInfo = m_layout->m_ranges[range]; @@ -3685,7 +3961,7 @@ void VKRenderer::DescriptorSetImpl::setResource(UInt range, UInt index, IResourc m_boundObjects[boundObjectIndex] = dynamic_cast<RefObject*>(view); } -void VKRenderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) +void VKDevice::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerState* sampler) { SLANG_ASSERT(range < UInt(m_layout->m_ranges.getCount())); auto& rangeInfo = m_layout->m_ranges[range]; @@ -3708,7 +3984,7 @@ void VKRenderer::DescriptorSetImpl::setSampler(UInt range, UInt index, ISamplerS m_boundObjects[boundObjectIndex] = dynamic_cast<RefObject*>(sampler); } -void VKRenderer::DescriptorSetImpl::setCombinedTextureSampler( +void VKDevice::DescriptorSetImpl::setCombinedTextureSampler( UInt range, UInt index, IResourceView* textureView, @@ -3731,7 +4007,7 @@ void VKRenderer::DescriptorSetImpl::setCombinedTextureSampler( m_boundObjects[boundObjectIndex + 1] = dynamic_cast<RefObject*>(sampler); } -void VKRenderer::DescriptorSetImpl::setRootConstants( +void VKDevice::DescriptorSetImpl::setRootConstants( UInt range, UInt offset, UInt size, @@ -3756,7 +4032,7 @@ void VKRenderer::DescriptorSetImpl::setRootConstants( memcpy(m_rootConstantData.getBuffer() + rootConstantRangeInfo.offset + offset, data, size); } -Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) +Result VKDevice::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) { @@ -3791,7 +4067,7 @@ Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgra return SLANG_OK; } -Result VKRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) +Result VKDevice::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) { GraphicsPipelineStateDesc desc = inDesc; preparePipelineDesc(desc); @@ -3965,7 +4241,7 @@ Result VKRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& return SLANG_OK; } -Result VKRenderer::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) +Result VKDevice::createComputePipelineState(const ComputePipelineStateDesc& inDesc, IPipelineState** outState) { ComputePipelineStateDesc desc = inDesc; preparePipelineDesc(desc); diff --git a/tools/gfx/vulkan/render-vk.h b/tools/gfx/vulkan/render-vk.h index b2bceb31c..b980653c7 100644 --- a/tools/gfx/vulkan/render-vk.h +++ b/tools/gfx/vulkan/render-vk.h @@ -6,6 +6,6 @@ namespace gfx { -SlangResult SLANG_MCALL createVKRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer); +SlangResult SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outDevice); } // gfx diff --git a/tools/gfx/vulkan/vk-swap-chain.cpp b/tools/gfx/vulkan/vk-swap-chain.cpp deleted file mode 100644 index 3a62ccfe2..000000000 --- a/tools/gfx/vulkan/vk-swap-chain.cpp +++ /dev/null @@ -1,283 +0,0 @@ -// vk-swap-chain.cpp -#include "vk-swap-chain.h" - -#include "vk-util.h" - -#include "core/slang-list.h" - -#include <stdlib.h> -#include <stdio.h> - -namespace gfx { -using namespace Slang; - -static Index _indexOfFormat(List<VkSurfaceFormatKHR>& formatsIn, VkFormat format) -{ - const Index numFormats = formatsIn.getCount(); - const VkSurfaceFormatKHR* formats = formatsIn.getBuffer(); - - for (Index i = 0; i < numFormats; ++i) - { - if (formats[i].format == format) - { - return i; - } - } - return -1; -} - -SlangResult VulkanSwapChain::init( - VulkanApi* vkapi, - VkQueue queue, - uint32_t queueFamilyIndex, - const Desc& descIn, - const PlatformDesc* platformDescIn) -{ - assert(platformDescIn); - - m_queue = queue; - m_api = vkapi; - - // Make sure it's not set initially - m_format = VK_FORMAT_UNDEFINED; - - Desc desc(descIn); - -#if SLANG_WINDOWS_FAMILY - const WinPlatformDesc* platformDesc = static_cast<const WinPlatformDesc*>(platformDescIn); - _setPlatformDesc(*platformDesc); - - VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = {}; - surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.hinstance = platformDesc->m_hinstance; - surfaceCreateInfo.hwnd = platformDesc->m_hwnd; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateWin32SurfaceKHR(m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); -#else - const XPlatformDesc* platformDesc = static_cast<const XPlatformDesc*>(platformDescIn); - _setPlatformDesc(*platformDesc); - - VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {}; - surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.dpy = platformDesc->m_display; - surfaceCreateInfo.window = platformDesc->m_window; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateXlibSurfaceKHR(m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); -#endif - - VkBool32 supported = false; - m_api->vkGetPhysicalDeviceSurfaceSupportKHR(m_api->m_physicalDevice, queueFamilyIndex, m_surface, &supported); - - uint32_t numSurfaceFormats = 0; - List<VkSurfaceFormatKHR> surfaceFormats; - m_api->vkGetPhysicalDeviceSurfaceFormatsKHR(m_api->m_physicalDevice, m_surface, &numSurfaceFormats, nullptr); - surfaceFormats.setCount(int(numSurfaceFormats)); - m_api->vkGetPhysicalDeviceSurfaceFormatsKHR(m_api->m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats.getBuffer()); - - // Look for a suitable format - List<VkFormat> formats; - formats.add(VulkanUtil::getVkFormat(desc.m_format)); - // HACK! To check for a different format if couldn't be found - if (descIn.m_format == Format::RGBA_Unorm_UInt8) - { - formats.add(VK_FORMAT_B8G8R8A8_UNORM); - } - - for(Index i = 0; i < formats.getCount(); ++i) - { - VkFormat format = formats[i]; - if (_indexOfFormat(surfaceFormats, format) >= 0) - { - m_format = format; - } - } - - if (m_format == VK_FORMAT_UNDEFINED) - { - return SLANG_FAIL; - } - - // Save the desc - m_desc = desc; - - if (descIn.m_format == Format::RGBA_Unorm_UInt8 && m_format == VK_FORMAT_B8G8R8A8_UNORM) - { - m_desc.m_format = Format::BGRA_Unorm_UInt8; - } - - SLANG_RETURN_ON_FAIL(_createSwapChain()); - return SLANG_OK; -} - -void VulkanSwapChain::getWindowSize(int* widthOut, int* heightOut) const -{ -#if SLANG_WINDOWS_FAMILY - auto platformDesc = _getPlatformDesc<WinPlatformDesc>(); - - RECT rc; - ::GetClientRect(platformDesc->m_hwnd, &rc); - *widthOut = rc.right - rc.left; - *heightOut = rc.bottom - rc.top; -#else - auto platformDesc = _getPlatformDesc<XPlatformDesc>(); - - XWindowAttributes winAttr = {}; - XGetWindowAttributes(platformDesc->m_display, platformDesc->m_window, &winAttr); - - *widthOut = winAttr.width; - *heightOut = winAttr.height; -#endif -} - -SlangResult VulkanSwapChain::_createSwapChain() -{ - int width, height; - getWindowSize(&width, &height); - - VkExtent2D imageExtent = {}; - imageExtent.width = width; - imageExtent.height = height; - - m_width = width; - m_height = height; - - // catch this before throwing error - if (m_width == 0 || m_height == 0) - { - return SLANG_FAIL; - } - - // It is necessary to query the caps -> otherwise the LunarG verification layer will issue an error - { - VkSurfaceCapabilitiesKHR surfaceCaps; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_api->m_physicalDevice, m_surface, &surfaceCaps)); - } - - List<VkPresentModeKHR> presentModes; - uint32_t numPresentModes = 0; - m_api->vkGetPhysicalDeviceSurfacePresentModesKHR(m_api->m_physicalDevice, m_surface, &numPresentModes, nullptr); - presentModes.setCount(numPresentModes); - m_api->vkGetPhysicalDeviceSurfacePresentModesKHR(m_api->m_physicalDevice, m_surface, &numPresentModes, presentModes.getBuffer()); - - { - int numCheckPresentOptions = 3; - VkPresentModeKHR presentOptions[] = { VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR }; - if (m_desc.m_vsync) - { - presentOptions[0] = VK_PRESENT_MODE_FIFO_KHR; - presentOptions[1] = VK_PRESENT_MODE_IMMEDIATE_KHR; - presentOptions[2] = VK_PRESENT_MODE_MAILBOX_KHR; - } - - m_presentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; // Invalid - - // Find the first option that's available on the device - for (int j = 0; j < numCheckPresentOptions; j++) - { - if (presentModes.indexOf(presentOptions[j]) != Index(-1)) - { - m_presentMode = presentOptions[j]; - break; - } - } - - if (m_presentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) - { - return SLANG_FAIL; - } - } - - VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE; - - VkSwapchainCreateInfoKHR swapchainDesc = {}; - swapchainDesc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapchainDesc.surface = m_surface; - swapchainDesc.minImageCount = m_desc.m_imageCount; - swapchainDesc.imageFormat = m_format; - swapchainDesc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; - swapchainDesc.imageExtent = imageExtent; - swapchainDesc.imageArrayLayers = 1; - swapchainDesc.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - swapchainDesc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapchainDesc.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - swapchainDesc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapchainDesc.presentMode = m_presentMode; - swapchainDesc.clipped = VK_TRUE; - swapchainDesc.oldSwapchain = oldSwapchain; - - SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateSwapchainKHR(m_api->m_device, &swapchainDesc, nullptr, &m_swapChain)); - - uint32_t numSwapChainImages = 0; - m_api->vkGetSwapchainImagesKHR(m_api->m_device, m_swapChain, &numSwapChainImages, nullptr); - m_desc.m_imageCount = numSwapChainImages; - { - m_images.setCount(numSwapChainImages); - m_api->vkGetSwapchainImagesKHR( - m_api->m_device, m_swapChain, &numSwapChainImages, m_images.getBuffer()); - } - return SLANG_OK; -} - -void VulkanSwapChain::_destroySwapChain() -{ - if (m_swapChain != VK_NULL_HANDLE) - { - m_api->vkDestroySwapchainKHR(m_api->m_device, m_swapChain, nullptr); - m_swapChain = VK_NULL_HANDLE; - } - - // Mark that it is no longer used - m_images.clear(); -} - -void VulkanSwapChain::destroy() -{ - _destroySwapChain(); - - if (m_surface) - { - m_api->vkDestroySurfaceKHR(m_api->m_instance, m_surface, nullptr); - m_surface = VK_NULL_HANDLE; - } -} - - -VulkanSwapChain::~VulkanSwapChain() -{ - destroy(); -} - -int VulkanSwapChain::nextFrontImageIndex(VkSemaphore signalSemaphore) -{ - uint32_t swapChainIndex = 0; - VkResult result = m_api->vkAcquireNextImageKHR( - m_api->m_device, m_swapChain, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &swapChainIndex); - - if (result != VK_SUCCESS) - { - _destroySwapChain(); - return -1; - } - m_currentSwapChainIndex = int(swapChainIndex); - return swapChainIndex; -} - -void VulkanSwapChain::present(VkSemaphore waitSemaphore) -{ - uint32_t swapChainIndices[] = { uint32_t(m_currentSwapChainIndex) }; - - VkPresentInfoKHR presentInfo = {}; - presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &m_swapChain; - presentInfo.pImageIndices = swapChainIndices; - if (waitSemaphore != VK_NULL_HANDLE) - { - presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &waitSemaphore; - } - m_api->vkQueuePresentKHR(m_queue, &presentInfo); -} - -} // renderer_test diff --git a/tools/gfx/vulkan/vk-swap-chain.h b/tools/gfx/vulkan/vk-swap-chain.h deleted file mode 100644 index 0ddc6f7f5..000000000 --- a/tools/gfx/vulkan/vk-swap-chain.h +++ /dev/null @@ -1,135 +0,0 @@ -// vk-swap-chain.h -#pragma once - -#include "vk-api.h" -#include "vk-device-queue.h" - -#include "slang-gfx.h" - -#include "core/slang-list.h" - -namespace gfx { - -struct VulkanSwapChain -{ - /* enum - { - kMaxImages = 8, - }; */ - - /// Base class for platform specific information - struct PlatformDesc - { - }; - -#if SLANG_WINDOWS_FAMILY - struct WinPlatformDesc: public PlatformDesc - { - HINSTANCE m_hinstance; - HWND m_hwnd; - }; -#else - struct XPlatformDesc : public PlatformDesc - { - Display* m_display; - Window m_window; - }; -#endif - - struct Desc - { - void init() - { - m_format = Format::Unknown; - m_depthFormatTypeless = Format::Unknown; - m_depthFormat = Format::Unknown; - m_textureDepthFormat = Format::Unknown; - m_imageCount = 2; - m_vsync = false; - } - - Format m_format; - Format m_depthFormatTypeless; - Format m_depthFormat; - Format m_textureDepthFormat; - uint32_t m_imageCount; - bool m_vsync; - }; - - /// Must be called before the swap chain can be used - SlangResult init( - VulkanApi* vkapi, - VkQueue queue, - uint32_t queueFamilyIndex, - const Desc& desc, - const PlatformDesc* platformDesc); - - /// Returned the desc used to construct the swap chain. - /// Is invalid if init hasn't returned with successful result. - const Desc& getDesc() const { return m_desc; } - - /// True if the swap chain is available - bool hasValidSwapChain() const { return m_images.getCount() > 0; } - - /// Present to the display - void present(VkSemaphore waitSemaphore); - - /// Get the current size of the window (in pixels written to widthOut, heightOut) - void getWindowSize(int* widthOut, int* heightOut) const; - - /// Get the VkFormat for the back buffer - VkFormat getVkFormat() const { return m_format; } - - /// Get width of the back buffers - int getWidth() const { return m_width; } - /// Get the height of the back buffer - int getHeight() const { return m_height; } - - /// Get the detail about the images - const Slang::List<VkImage>& getImages() const { return m_images; } - - /// Get the next front render image index. Returns -1, if image couldn't be found - int nextFrontImageIndex(VkSemaphore signalSemaphore); - - void destroy(); - - /// Dtor - ~VulkanSwapChain(); - - protected: - - - template <typename T> - void _setPlatformDesc(const T& desc) - { - const PlatformDesc* check = &desc; - int size = (sizeof(T) + sizeof(void*) - 1) / sizeof(void*); - m_platformDescBuffer.setCount(size); - *(T*)m_platformDescBuffer.getBuffer() = desc; - } - template <typename T> - const T* _getPlatformDesc() const { return static_cast<const T*>((const PlatformDesc*)m_platformDescBuffer.getBuffer()); } - SlangResult _createSwapChain(); - void _destroySwapChain(); - - int m_width = 0; - int m_height = 0; - - VkPresentModeKHR m_presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; - VkFormat m_format = VK_FORMAT_UNDEFINED; ///< The format used for backbuffer. Valid after successful init. - - VkSurfaceKHR m_surface = VK_NULL_HANDLE; - VkSwapchainKHR m_swapChain = VK_NULL_HANDLE; - - int m_currentSwapChainIndex = 0; - - Slang::List<VkImage> m_images; - - VkQueue m_queue; - const VulkanApi* m_api = nullptr; - - Desc m_desc; ///< The desc used to init this swap chain - Slang::List<void*> m_platformDescBuffer; ///< Buffer to hold the platform specific description parameters (as passed in platformDesc) -}; - -} // renderer_test diff --git a/tools/platform/gui.cpp b/tools/platform/gui.cpp index cf7e74acc..5c210f460 100644 --- a/tools/platform/gui.cpp +++ b/tools/platform/gui.cpp @@ -40,10 +40,10 @@ void setNativeWindowHook(Window* window, WNDPROC proc); GUI::GUI( Window* window, - IRenderer* inRenderer, + IDevice* inDevice, ICommandQueue* inQueue, IFramebufferLayout* framebufferLayout) - : renderer(inRenderer) + : device(inDevice) , queue(inQueue) { ImGui::CreateContext(); @@ -151,7 +151,7 @@ GUI::GUI( programDesc.kernels = &kernelDescs[0]; programDesc.kernelCount = 2; - auto program = renderer->createProgram(programDesc); + auto program = device->createProgram(programDesc); vertexShaderBlob->release(); fragmentShaderBlob->release(); @@ -161,7 +161,7 @@ GUI::GUI( {"U", 1, Format::RG_Float32, offsetof(ImDrawVert, uv) }, {"U", 2, Format::RGBA_Unorm_UInt8, offsetof(ImDrawVert, col) }, }; - auto inputLayout = renderer->createInputLayout( + auto inputLayout = device->createInputLayout( &inputElements[0], SLANG_COUNT_OF(inputElements)); @@ -176,7 +176,7 @@ GUI::GUI( descriptorSetLayoutDesc.slotRangeCount = descriptorSetRanges.getCount(); descriptorSetLayoutDesc.slotRanges = descriptorSetRanges.getBuffer(); - descriptorSetLayout = renderer->createDescriptorSetLayout(descriptorSetLayoutDesc); + descriptorSetLayout = device->createDescriptorSetLayout(descriptorSetLayoutDesc); Slang::List<IPipelineLayout::DescriptorSetDesc> pipelineDescriptorSets; pipelineDescriptorSets.add(IPipelineLayout::DescriptorSetDesc(descriptorSetLayout)); @@ -186,7 +186,7 @@ GUI::GUI( pipelineLayoutDesc.descriptorSets = pipelineDescriptorSets.getBuffer(); pipelineLayoutDesc.renderTargetCount = 1; - pipelineLayout = renderer->createPipelineLayout(pipelineLayoutDesc); + pipelineLayout = device->createPipelineLayout(pipelineLayoutDesc); TargetBlendDesc targetBlendDesc; targetBlendDesc.color.srcFactor = BlendFactor::SrcAlpha; @@ -208,7 +208,7 @@ GUI::GUI( // TODO: need to set up blending state... - pipelineState = renderer->createGraphicsPipelineState(pipelineDesc); + pipelineState = device->createGraphicsPipelineState(pipelineDesc); // Initialize the texture atlas unsigned char* pixels; @@ -229,19 +229,20 @@ GUI::GUI( initData.numSubResources = 1; initData.subResources = subResourceData; - auto texture = renderer->createTextureResource(IResource::Usage::PixelShaderResource, desc, &initData); + auto texture = + device->createTextureResource(IResource::Usage::PixelShaderResource, desc, &initData); gfx::IResourceView::Desc viewDesc; viewDesc.format = desc.format; viewDesc.type = IResourceView::Type::ShaderResource; - auto textureView = renderer->createTextureView(texture, viewDesc); + auto textureView = device->createTextureView(texture, viewDesc); io.Fonts->TexID = (void*) textureView.detach(); } { ISamplerState::Desc desc; - samplerState = renderer->createSamplerState(desc); + samplerState = device->createSamplerState(desc); } { @@ -255,7 +256,7 @@ GUI::GUI( colorAccess.storeOp = IRenderPassLayout::AttachmentStoreOp::Store; desc.renderTargetAccess = &colorAccess; desc.renderTargetCount = 1; - renderPass = renderer->createRenderPassLayout(desc); + renderPass = device->createRenderPassLayout(desc); } } @@ -288,15 +289,14 @@ void GUI::endFrame(IFramebuffer* framebuffer) vertexBufferDesc.init(vertexCount * sizeof(ImDrawVert)); vertexBufferDesc.setDefaults(IResource::Usage::VertexBuffer); vertexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - auto vertexBuffer = renderer->createBufferResource( - IResource::Usage::VertexBuffer, - vertexBufferDesc); + auto vertexBuffer = + device->createBufferResource(IResource::Usage::VertexBuffer, vertexBufferDesc); gfx::IBufferResource::Desc indexBufferDesc; indexBufferDesc.init(indexCount * sizeof(ImDrawIdx)); indexBufferDesc.setDefaults(IResource::Usage::IndexBuffer); indexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - auto indexBuffer = renderer->createBufferResource( + auto indexBuffer = device->createBufferResource( IResource::Usage::IndexBuffer, indexBufferDesc); auto cmdBuf = queue->createCommandBuffer(); @@ -323,9 +323,8 @@ void GUI::endFrame(IFramebuffer* framebuffer) constantBufferDesc.init(sizeof(glm::mat4x4)); constantBufferDesc.setDefaults(IResource::Usage::ConstantBuffer); constantBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - auto constantBuffer = renderer->createBufferResource( - IResource::Usage::ConstantBuffer, - constantBufferDesc); + auto constantBuffer = + device->createBufferResource(IResource::Usage::ConstantBuffer, constantBufferDesc); { float L = draw_data->DisplayPos.x; @@ -389,7 +388,7 @@ void GUI::endFrame(IFramebuffer* framebuffer) renderEncoder->setScissorRects(1, &rect); // TODO: This should be a dynamic/transient descriptor set... - auto descriptorSet = renderer->createDescriptorSet(descriptorSetLayout, gfx::IDescriptorSet::Flag::Transient); + auto descriptorSet = device->createDescriptorSet(descriptorSetLayout, gfx::IDescriptorSet::Flag::Transient); descriptorSet->setConstantBuffer(0, 0, constantBuffer); descriptorSet->setResource(1, 0, (gfx::IResourceView*) command->TextureId); diff --git a/tools/platform/gui.h b/tools/platform/gui.h index d22da3299..970f3a4e8 100644 --- a/tools/platform/gui.h +++ b/tools/platform/gui.h @@ -13,7 +13,7 @@ namespace platform { struct GUI : Slang::RefObject { GUI(Window* window, - gfx::IRenderer* renderer, + gfx::IDevice* device, gfx::ICommandQueue* queue, gfx::IFramebufferLayout* framebufferLayout); ~GUI(); @@ -22,7 +22,7 @@ struct GUI : Slang::RefObject void endFrame(gfx::IFramebuffer* framebuffer); private: - Slang::ComPtr<gfx::IRenderer> renderer; + Slang::ComPtr<gfx::IDevice> device; Slang::ComPtr<gfx::ICommandQueue> queue; Slang::ComPtr<gfx::IRenderPassLayout> renderPass; Slang::ComPtr<gfx::IPipelineState> pipelineState; diff --git a/tools/platform/model.cpp b/tools/platform/model.cpp index f28577631..287f80958 100644 --- a/tools/platform/model.cpp +++ b/tools/platform/model.cpp @@ -98,7 +98,7 @@ namespace gfx { ComPtr<ITextureResource> loadTextureImage( - IRenderer* renderer, + IDevice* device, char const* path) { int extentX = 0; @@ -187,10 +187,8 @@ ComPtr<ITextureResource> loadTextureImage( initData.subResources = &subresourceInitData[0]; initData.mipRowStrides = &mipRowStrides[0]; - auto texture = renderer->createTextureResource( - IResource::Usage::PixelShaderResource, - desc, - &initData); + auto texture = + device->createTextureResource(IResource::Usage::PixelShaderResource, desc, &initData); free(data); @@ -262,7 +260,7 @@ Result ModelLoader::load( if(objMaterial.diffuse_texname.length()) { materialData.diffuseMap = loadTextureImage( - renderer, + device, objMaterial.diffuse_texname.c_str()); } @@ -542,7 +540,7 @@ Result ModelLoader::load( vertexBufferDesc.init(modelData.vertexCount * sizeof(Vertex)); vertexBufferDesc.setDefaults(IResource::Usage::VertexBuffer); - modelData.vertexBuffer = renderer->createBufferResource( + modelData.vertexBuffer = device->createBufferResource( IResource::Usage::VertexBuffer, vertexBufferDesc, flatVertices.data()); @@ -552,7 +550,7 @@ Result ModelLoader::load( indexBufferDesc.init(modelData.indexCount * sizeof(Index)); vertexBufferDesc.setDefaults(IResource::Usage::IndexBuffer); - modelData.indexBuffer = renderer->createBufferResource( + modelData.indexBuffer = device->createBufferResource( IResource::Usage::IndexBuffer, indexBufferDesc, flatIndices.data()); diff --git a/tools/platform/model.h b/tools/platform/model.h index 412f10a1d..8cff2c67d 100644 --- a/tools/platform/model.h +++ b/tools/platform/model.h @@ -66,7 +66,7 @@ struct ModelLoader }; ICallbacks* callbacks = nullptr; - Slang::ComPtr<IRenderer> renderer; + Slang::ComPtr<IDevice> device; LoadFlags loadFlags = 0; float scale = 1.0f; diff --git a/tools/platform/window.h b/tools/platform/window.h index c776c3ffa..e4a867f0b 100644 --- a/tools/platform/window.h +++ b/tools/platform/window.h @@ -146,11 +146,17 @@ struct Rect int width, height; }; +enum class WindowStyle +{ + Default, FixedSize, +}; + struct WindowDesc { char const* title = nullptr; int width = 0; int height = 0; + WindowStyle style = WindowStyle::Default; }; class Window : public Slang::RefObject diff --git a/tools/platform/windows/win-window.cpp b/tools/platform/windows/win-window.cpp index 0362a6839..8822a6393 100644 --- a/tools/platform/windows/win-window.cpp +++ b/tools/platform/windows/win-window.cpp @@ -310,7 +310,12 @@ public: Win32PlatformWindow(const WindowDesc& desc) { DWORD windowExtendedStyle = 0; - DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; + style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; + if (desc.style == WindowStyle::Default) + { + style |= WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME; + } + HINSTANCE instance = (HINSTANCE)GetModuleHandle(0); RECT windowRect; diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp index 100c353e0..fa32bb9c0 100644 --- a/tools/render-test/options.cpp +++ b/tools/render-test/options.cpp @@ -18,29 +18,30 @@ namespace renderer_test { using namespace Slang; -static gfx::RendererType _toRenderType(Slang::RenderApiType apiType) +static gfx::DeviceType _toRenderType(Slang::RenderApiType apiType) { using namespace Slang; switch (apiType) { - case RenderApiType::D3D11: return gfx::RendererType::DirectX11; - case RenderApiType::D3D12: return gfx::RendererType::DirectX12; - case RenderApiType::OpenGl: return gfx::RendererType::OpenGl; - case RenderApiType::Vulkan: return gfx::RendererType::Vulkan; - case RenderApiType::CPU: return gfx::RendererType::CPU; - case RenderApiType::CUDA: return gfx::RendererType::CUDA; - default: return gfx::RendererType::Unknown; + case RenderApiType::D3D11: return gfx::DeviceType::DirectX11; + case RenderApiType::D3D12: return gfx::DeviceType::DirectX12; + case RenderApiType::OpenGl: return gfx::DeviceType::OpenGl; + case RenderApiType::Vulkan: return gfx::DeviceType::Vulkan; + case RenderApiType::CPU: return gfx::DeviceType::CPU; + case RenderApiType::CUDA: return gfx::DeviceType::CUDA; + default: + return gfx::DeviceType::Unknown; } } -static SlangResult _setRendererType(RendererType type, const char* arg, Slang::WriterHelper stdError, Options& ioOptions) +static SlangResult _setRendererType(DeviceType type, const char* arg, Slang::WriterHelper stdError, Options& ioOptions) { - if (ioOptions.rendererType != RendererType::Unknown) + if (ioOptions.deviceType != DeviceType::Unknown) { stdError.print("Already has renderer option set. Found '%s'\n", arg); return SLANG_FAIL; } - ioOptions.rendererType = type; + ioOptions.deviceType = type; return SLANG_OK; } @@ -262,19 +263,20 @@ static SlangResult _setRendererType(RendererType type, const char* arg, Slang::W { // Look up the rendering API if set UnownedStringSlice argName = UnownedStringSlice(argSlice.begin() + 1, argSlice.end()); - RendererType rendererType = _toRenderType(RenderApiUtil::findApiTypeByName(argName)); + DeviceType deviceType = _toRenderType(RenderApiUtil::findApiTypeByName(argName)); - if (rendererType != RendererType::Unknown) + if (deviceType != DeviceType::Unknown) { - outOptions.rendererType = rendererType; + outOptions.deviceType = deviceType; continue; } // Lookup the target language type - RendererType languageRenderType = _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName)); - if (languageRenderType != RendererType::Unknown) + DeviceType languageRenderType = + _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName)); + if (languageRenderType != DeviceType::Unknown) { - outOptions.targetLanguageRendererType = languageRenderType; + outOptions.targetLanguageDeviceType = languageRenderType; outOptions.inputLanguageID = (argName == "hlsl" || argName == "glsl" || argName == "cpp" || argName == "cxx" || argName == "c") ? InputLanguageID::Native : InputLanguageID::Slang; continue; } @@ -286,7 +288,9 @@ static SlangResult _setRendererType(RendererType type, const char* arg, Slang::W } // If a render option isn't set use defaultRenderType - outOptions.rendererType = (outOptions.rendererType == RendererType::Unknown) ? outOptions.targetLanguageRendererType : outOptions.rendererType; + outOptions.deviceType = (outOptions.deviceType == DeviceType::Unknown) + ? outOptions.targetLanguageDeviceType + : outOptions.deviceType; // first positional argument is source shader path if(positionalArgs.getCount()) diff --git a/tools/render-test/options.h b/tools/render-test/options.h index 9d39e35b3..c051a4d09 100644 --- a/tools/render-test/options.h +++ b/tools/render-test/options.h @@ -50,9 +50,9 @@ struct Options ShaderProgramType shaderType = ShaderProgramType::Graphics; /// The renderer type inferred from the target language type. Used if a rendererType is not explicitly set. - RendererType targetLanguageRendererType = RendererType::Unknown; + DeviceType targetLanguageDeviceType = DeviceType::Unknown; /// The set render type - RendererType rendererType = RendererType::Unknown; + DeviceType deviceType = DeviceType::Unknown; InputLanguageID inputLanguageID = InputLanguageID::Slang; SlangSourceLanguage sourceLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 18670537d..e13642c5c 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -96,7 +96,7 @@ public: // code, and then create the API objects we need for rendering. virtual Result initialize( SlangSession* session, - IRenderer* renderer, + IDevice* device, const Options& options, const ShaderCompilerUtil::Input& input) = 0; void runCompute(IComputeCommandEncoder* encoder); @@ -113,7 +113,7 @@ protected: /// Called in initialize Result _initializeShaders( SlangSession* session, - IRenderer* renderer, + IDevice* device, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input); void _initializeRenderPass(); @@ -124,7 +124,7 @@ protected: // variables for state to be used for rendering... uintptr_t m_constantBufferSize; - ComPtr<IRenderer> m_renderer; + ComPtr<IDevice> m_device; ComPtr<ICommandQueue> m_queue; ComPtr<IRenderPassLayout> m_renderPass; ComPtr<IInputLayout> m_inputLayout; @@ -149,7 +149,7 @@ public: virtual void setProjectionMatrix(IResourceCommandEncoder* encoder) SLANG_OVERRIDE; virtual Result initialize( SlangSession* session, - IRenderer* renderer, + IDevice* device, const Options& options, const ShaderCompilerUtil::Input& input) SLANG_OVERRIDE; @@ -172,7 +172,7 @@ public: virtual void setProjectionMatrix(IResourceCommandEncoder* encoder) SLANG_OVERRIDE; virtual Result initialize( SlangSession* session, - IRenderer* renderer, + IDevice* device, const Options& options, const ShaderCompilerUtil::Input& input) SLANG_OVERRIDE; virtual Result writeBindingOutput(BindRoot* bindRoot, const char* fileName) override; @@ -185,7 +185,7 @@ protected: }; SlangResult _assignVarsFromLayout( - IRenderer* renderer, + IDevice* device, IShaderObject* shaderObject, ShaderInputLayout const& layout, ShaderOutputPlan& ioOutputPlan, @@ -283,13 +283,13 @@ SlangResult _assignVarsFromLayout( { ComPtr<IBufferResource> bufferResource; - SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBufferResource(entry.bufferDesc, entry.isOutput, bufferSize, entry.bufferData.getBuffer(), renderer, bufferResource)); + SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBufferResource(entry.bufferDesc, entry.isOutput, bufferSize, entry.bufferData.getBuffer(), device, bufferResource)); resource = bufferResource; IResourceView::Desc viewDesc; viewDesc.type = IResourceView::Type::UnorderedAccess; viewDesc.format = srcBuffer.format; - auto bufferView = renderer->createBufferView( + auto bufferView = device->createBufferView( bufferResource, viewDesc); entryCursor.setResource(bufferView); @@ -331,14 +331,15 @@ SlangResult _assignVarsFromLayout( case ShaderInputType::CombinedTextureSampler: { ComPtr<ITextureResource> texture; - SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTextureResource(entry.textureDesc, textureBindFlags, renderer, texture)); + SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTextureResource( + entry.textureDesc, textureBindFlags, device, texture)); resource = texture; - auto sampler = _createSamplerState(renderer, entry.samplerDesc); + auto sampler = _createSamplerState(device, entry.samplerDesc); IResourceView::Desc viewDesc; viewDesc.type = IResourceView::Type::ShaderResource; - auto textureView = renderer->createTextureView( + auto textureView = device->createTextureView( texture, viewDesc); @@ -361,7 +362,8 @@ SlangResult _assignVarsFromLayout( case ShaderInputType::Texture: { ComPtr<ITextureResource> texture; - SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTextureResource(entry.textureDesc, textureBindFlags, renderer, texture)); + SLANG_RETURN_ON_FAIL(ShaderRendererUtil::generateTextureResource( + entry.textureDesc, textureBindFlags, device, texture)); resource = texture; // TODO: support UAV textures... @@ -369,7 +371,7 @@ SlangResult _assignVarsFromLayout( IResourceView::Desc viewDesc; viewDesc.type = IResourceView::Type::ShaderResource; viewDesc.format = texture->getDesc()->format; - auto textureView = renderer->createTextureView( + auto textureView = device->createTextureView( texture, viewDesc); @@ -396,7 +398,7 @@ SlangResult _assignVarsFromLayout( case ShaderInputType::Sampler: { - auto sampler = _createSamplerState(renderer, entry.samplerDesc); + auto sampler = _createSamplerState(device, entry.samplerDesc); entryCursor.setSampler(sampler); #if 0 @@ -441,8 +443,7 @@ SlangResult _assignVarsFromLayout( slangType = slangTypeLayout->getType(); } - ComPtr<IShaderObject> shaderObject = - renderer->createShaderObject(slangType); + ComPtr<IShaderObject> shaderObject = device->createShaderObject(slangType); entryCursor.setObject(shaderObject); } @@ -497,15 +498,15 @@ void ShaderObjectRenderTestApp::applyBinding(PipelineType pipelineType, ICommand SlangResult LegacyRenderTestApp::initialize( SlangSession* session, - IRenderer* renderer, + IDevice* device, const Options& options, const ShaderCompilerUtil::Input& input) { m_options = options; - m_renderer = renderer; + m_device = device; - SLANG_RETURN_ON_FAIL(_initializeShaders(session, renderer, options.shaderType, input)); + SLANG_RETURN_ON_FAIL(_initializeShaders(session, device, options.shaderType, input)); _initializeRenderPass(); @@ -519,7 +520,7 @@ SlangResult LegacyRenderTestApp::initialize( constantBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; m_constantBuffer = - renderer->createBufferResource(IResource::Usage::ConstantBuffer, constantBufferDesc); + device->createBufferResource(IResource::Usage::ConstantBuffer, constantBufferDesc); if (!m_constantBuffer) return SLANG_FAIL; @@ -542,7 +543,7 @@ SlangResult LegacyRenderTestApp::initialize( BindingStateImpl* bindingState = nullptr; SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBindingState( - m_shaderInputLayout, m_renderer, addedConstantBuffer, &bindingState)); + m_shaderInputLayout, m_device, addedConstantBuffer, &bindingState)); m_bindingState = bindingState; // Do other initialization that doesn't depend on the source language. @@ -555,14 +556,14 @@ SlangResult LegacyRenderTestApp::initialize( {"A", 2, Format::RG_Float32, offsetof(Vertex, uv)}, }; - m_inputLayout = renderer->createInputLayout(inputElements, SLANG_COUNT_OF(inputElements)); + m_inputLayout = m_device->createInputLayout(inputElements, SLANG_COUNT_OF(inputElements)); if (!m_inputLayout) return SLANG_FAIL; IBufferResource::Desc vertexBufferDesc; vertexBufferDesc.init(kVertexCount * sizeof(Vertex)); - m_vertexBuffer = renderer->createBufferResource( + m_vertexBuffer = m_device->createBufferResource( IResource::Usage::VertexBuffer, vertexBufferDesc, kVertexData); if (!m_vertexBuffer) return SLANG_FAIL; @@ -580,7 +581,7 @@ SlangResult LegacyRenderTestApp::initialize( desc.pipelineLayout = m_bindingState->pipelineLayout; desc.program = m_shaderProgram; - m_pipelineState = renderer->createComputePipelineState(desc); + m_pipelineState = m_device->createComputePipelineState(desc); } break; @@ -592,7 +593,7 @@ SlangResult LegacyRenderTestApp::initialize( desc.program = m_shaderProgram; desc.inputLayout = m_inputLayout; desc.framebufferLayout = m_framebufferLayout; - m_pipelineState = renderer->createGraphicsPipelineState(desc); + m_pipelineState = m_device->createGraphicsPipelineState(desc); } break; } @@ -603,7 +604,7 @@ SlangResult LegacyRenderTestApp::initialize( SlangResult ShaderObjectRenderTestApp::initialize( SlangSession* session, - IRenderer* renderer, + IDevice* device, const Options& options, const ShaderCompilerUtil::Input& input) { @@ -616,7 +617,8 @@ SlangResult ShaderObjectRenderTestApp::initialize( // Once the shaders have been compiled we load them via the underlying API. // - SLANG_RETURN_ON_FAIL(renderer->createProgram(m_compilationOutput.output.desc, m_shaderProgram.writeRef())); + SLANG_RETURN_ON_FAIL( + device->createProgram(m_compilationOutput.output.desc, m_shaderProgram.writeRef())); // If we are doing a non-pass-through compilation, then we will rely on // Slang's reflection API to tell us what the parameters of the program are. @@ -626,15 +628,15 @@ SlangResult ShaderObjectRenderTestApp::initialize( // Once we have determined the layout of all the parameters we need to bind, // we will create a shader object to use for storing and binding those parameters. // - m_programVars = renderer->createRootShaderObject(m_shaderProgram); + m_programVars = device->createRootShaderObject(m_shaderProgram); // Now we need to assign from the input parameter data that was parsed into // the program vars we allocated. // SLANG_RETURN_ON_FAIL(_assignVarsFromLayout( - renderer, m_programVars, m_compilationOutput.layout, m_outputPlan, slangReflection)); + device, m_programVars, m_compilationOutput.layout, m_outputPlan, slangReflection)); - m_renderer = renderer; + m_device = device; _initializeRenderPass(); @@ -650,7 +652,7 @@ SlangResult ShaderObjectRenderTestApp::initialize( ComputePipelineStateDesc desc; desc.program = m_shaderProgram; - m_pipelineState = renderer->createComputePipelineState(desc); + m_pipelineState = device->createComputePipelineState(desc); } break; @@ -673,18 +675,23 @@ SlangResult ShaderObjectRenderTestApp::initialize( }; ComPtr<IInputLayout> inputLayout; - SLANG_RETURN_ON_FAIL(renderer->createInputLayout(inputElements, SLANG_COUNT_OF(inputElements), inputLayout.writeRef())); + SLANG_RETURN_ON_FAIL(device->createInputLayout( + inputElements, SLANG_COUNT_OF(inputElements), inputLayout.writeRef())); IBufferResource::Desc vertexBufferDesc; vertexBufferDesc.init(kVertexCount * sizeof(Vertex)); - SLANG_RETURN_ON_FAIL(renderer->createBufferResource(IResource::Usage::VertexBuffer, vertexBufferDesc, kVertexData, m_vertexBuffer.writeRef())); + SLANG_RETURN_ON_FAIL(device->createBufferResource( + IResource::Usage::VertexBuffer, + vertexBufferDesc, + kVertexData, + m_vertexBuffer.writeRef())); GraphicsPipelineStateDesc desc; desc.program = m_shaderProgram; desc.inputLayout = inputLayout; desc.framebufferLayout = m_framebufferLayout; - m_pipelineState = renderer->createGraphicsPipelineState(desc); + m_pipelineState = device->createGraphicsPipelineState(desc); } break; } @@ -708,20 +715,20 @@ void ShaderObjectRenderTestApp::finalizeImpl() Result RenderTestApp::_initializeShaders( SlangSession* session, - IRenderer* renderer, + IDevice* device, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input) { SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, m_options, input, m_compilationOutput)); m_shaderInputLayout = m_compilationOutput.layout; - m_shaderProgram = renderer->createProgram(m_compilationOutput.output.desc); + m_shaderProgram = device->createProgram(m_compilationOutput.output.desc); return m_shaderProgram ? SLANG_OK : SLANG_FAIL; } void RenderTestApp::_initializeRenderPass() { ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics}; - m_queue = m_renderer->createCommandQueue(queueDesc); + m_queue = m_device->createCommandQueue(queueDesc); gfx::ITextureResource::Desc depthBufferDesc; depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); @@ -732,7 +739,7 @@ void RenderTestApp::_initializeRenderPass() gWindowHeight, 0); - ComPtr<gfx::ITextureResource> depthBufferResource = m_renderer->createTextureResource( + ComPtr<gfx::ITextureResource> depthBufferResource = m_device->createTextureResource( gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); gfx::ITextureResource::Desc colorBufferDesc; @@ -743,7 +750,7 @@ void RenderTestApp::_initializeRenderPass() gWindowWidth, gWindowHeight, 0); - m_colorBuffer = m_renderer->createTextureResource( + m_colorBuffer = m_device->createTextureResource( gfx::IResource::Usage::RenderTarget, colorBufferDesc, nullptr); gfx::IResourceView::Desc colorBufferViewDesc; @@ -752,7 +759,7 @@ void RenderTestApp::_initializeRenderPass() colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget; ComPtr<gfx::IResourceView> rtv = - m_renderer->createTextureView(m_colorBuffer.get(), colorBufferViewDesc); + m_device->createTextureView(m_colorBuffer.get(), colorBufferViewDesc); gfx::IResourceView::Desc depthBufferViewDesc; memset(&depthBufferViewDesc, 0, sizeof(depthBufferViewDesc)); @@ -760,7 +767,7 @@ void RenderTestApp::_initializeRenderPass() depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil; ComPtr<gfx::IResourceView> dsv = - m_renderer->createTextureView(depthBufferResource.get(), depthBufferViewDesc); + m_device->createTextureView(depthBufferResource.get(), depthBufferViewDesc); IFramebufferLayout::AttachmentLayout colorAttachment = {gfx::Format::RGBA_Unorm_UInt8, 1}; IFramebufferLayout::AttachmentLayout depthAttachment = {gfx::Format::D_Float32, 1}; @@ -768,14 +775,14 @@ void RenderTestApp::_initializeRenderPass() framebufferLayoutDesc.renderTargetCount = 1; framebufferLayoutDesc.renderTargets = &colorAttachment; framebufferLayoutDesc.depthStencil = &depthAttachment; - m_renderer->createFramebufferLayout(framebufferLayoutDesc, m_framebufferLayout.writeRef()); + m_device->createFramebufferLayout(framebufferLayoutDesc, m_framebufferLayout.writeRef()); gfx::IFramebuffer::Desc framebufferDesc; framebufferDesc.renderTargetCount = 1; framebufferDesc.depthStencilView = dsv.get(); framebufferDesc.renderTargetViews = rtv.readRef(); framebufferDesc.layout = m_framebufferLayout; - m_renderer->createFramebuffer(framebufferDesc, m_framebuffer.writeRef()); + m_device->createFramebuffer(framebufferDesc, m_framebuffer.writeRef()); IRenderPassLayout::Desc renderPassDesc = {}; renderPassDesc.framebufferLayout = m_framebufferLayout; @@ -792,29 +799,23 @@ void RenderTestApp::_initializeRenderPass() depthStencilAccess.finalState = ResourceState::DepthWrite; renderPassDesc.renderTargetAccess = &renderTargetAccess; renderPassDesc.depthStencilAccess = &depthStencilAccess; - m_renderer->createRenderPassLayout(renderPassDesc, m_renderPass.writeRef()); + m_device->createRenderPassLayout(renderPassDesc, m_renderPass.writeRef()); } void LegacyRenderTestApp::setProjectionMatrix(IResourceCommandEncoder* encoder) { - float matrix[16]; - const ProjectionStyle projectionStyle = gfxGetProjectionStyle(m_renderer->getRendererType()); - gfxGetIdentityProjection(projectionStyle, matrix); - encoder->uploadBufferData(m_constantBuffer, 0, sizeof(float) * 16, matrix); + auto info = m_device->getDeviceInfo(); + encoder->uploadBufferData(m_constantBuffer, 0, sizeof(float) * 16, info.identityProjectionMatrix); } void ShaderObjectRenderTestApp::setProjectionMatrix(IResourceCommandEncoder* encoder) { SLANG_UNUSED(encoder); - const ProjectionStyle projectionStyle = - gfxGetProjectionStyle(m_renderer->getRendererType()); - - float projectionMatrix[16]; - gfxGetIdentityProjection(projectionStyle, projectionMatrix); + auto info = m_device->getDeviceInfo(); ShaderCursor(m_programVars) .getField("Uniforms") .getDereferenced() - .setData(projectionMatrix, sizeof(projectionMatrix)); + .setData(info.identityProjectionMatrix, sizeof(float) * 16); } void RenderTestApp::renderFrame(IRenderCommandEncoder* encoder) @@ -855,7 +856,7 @@ void RenderTestApp::finalize() m_framebufferLayout = nullptr; m_colorBuffer = nullptr; m_queue = nullptr; - m_renderer = nullptr; + m_device = nullptr; } void RenderTestApp::finalizeImpl() @@ -886,7 +887,7 @@ Result LegacyRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const char* f IBufferResource* bufferResource = static_cast<IBufferResource*>(binding.resource.get()); const size_t bufferSize = bufferResource->getDesc()->sizeInBytes; ComPtr<ISlangBlob> blob; - m_renderer->readBufferResource(bufferResource, 0, bufferSize, blob.writeRef()); + m_device->readBufferResource(bufferResource, 0, bufferSize, blob.writeRef()); if (!blob) { return SLANG_FAIL; @@ -929,7 +930,7 @@ Result ShaderObjectRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const c const size_t bufferSize = bufferResource->getDesc()->sizeInBytes; ComPtr<ISlangBlob> blob; - m_renderer->readBufferResource(bufferResource, 0, bufferSize, blob.writeRef()); + m_device->readBufferResource(bufferResource, 0, bufferSize, blob.writeRef()); if (!blob) { return SLANG_FAIL; @@ -951,7 +952,7 @@ Result RenderTestApp::writeScreen(const char* filename) { size_t rowPitch, pixelSize; ComPtr<ISlangBlob> blob; - SLANG_RETURN_ON_FAIL(m_renderer->readTextureResource( + SLANG_RETURN_ON_FAIL(m_device->readTextureResource( m_colorBuffer, ResourceState::RenderTarget, blob.writeRef(), &rowPitch, &pixelSize)); auto bufferSize = blob->getBufferSize(); uint32_t width = static_cast<uint32_t>(rowPitch / pixelSize); @@ -1139,9 +1140,9 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN; SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE; char const* profileName = ""; - switch (options.rendererType) + switch (options.deviceType) { - case RendererType::DirectX11: + case DeviceType::DirectX11: input.target = SLANG_DXBC; input.profile = "sm_5_0"; nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; @@ -1149,7 +1150,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi break; - case RendererType::DirectX12: + case DeviceType::DirectX12: input.target = SLANG_DXBC; input.profile = "sm_5_0"; nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL; @@ -1163,26 +1164,26 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi } break; - case RendererType::OpenGl: + case DeviceType::OpenGl: input.target = SLANG_GLSL; input.profile = "glsl_430"; nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; slangPassThrough = SLANG_PASS_THROUGH_GLSLANG; break; - case RendererType::Vulkan: + case DeviceType::Vulkan: input.target = SLANG_SPIRV; input.profile = "glsl_430"; nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL; slangPassThrough = SLANG_PASS_THROUGH_GLSLANG; break; - case RendererType::CPU: + case DeviceType::CPU: input.target = SLANG_HOST_CALLABLE; input.profile = ""; nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP; slangPassThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP; break; - case RendererType::CUDA: + case DeviceType::CUDA: input.target = SLANG_PTX; input.profile = ""; nativeLanguage = SLANG_SOURCE_LANGUAGE_CUDA; @@ -1243,7 +1244,8 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi input.profile = options.profileName ? options.profileName : input.profile; StringBuilder rendererName; - rendererName << "[" << gfxGetRendererName(options.rendererType) << "] "; + auto info = + rendererName << "[" << gfxGetDeviceTypeName(options.deviceType) << "] "; if (options.adapter.getLength()) { rendererName << "'" << options.adapter << "'"; @@ -1251,9 +1253,9 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi if (options.onlyStartup) { - switch (options.rendererType) + switch (options.deviceType) { - case RendererType::CUDA: + case DeviceType::CUDA: { #if RENDER_TEST_CUDA return SLANG_SUCCEEDED(spSessionCheckPassThroughSupport(session, SLANG_PASS_THROUGH_NVRTC)) && CUDAComputeUtil::canCreateDevice() ? SLANG_OK : SLANG_FAIL; @@ -1261,7 +1263,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi return SLANG_FAIL; #endif } - case RendererType::CPU: + case DeviceType::CPU: { // As long as we have CPU, then this should work return spSessionCheckPassThroughSupport(session, SLANG_PASS_THROUGH_GENERIC_C_CPP); @@ -1292,7 +1294,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi } // If it's CPU testing we don't need a window or a renderer - if (options.rendererType == RendererType::CPU) + if (options.deviceType == DeviceType::CPU) { // Check we have all the required features for (const auto& renderFeature : options.renderFeatures) @@ -1364,7 +1366,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi return SLANG_OK; } - if (options.rendererType == RendererType::CUDA && !options.useShaderObjects) + if (options.deviceType == DeviceType::CUDA && !options.useShaderObjects) { #if RENDER_TEST_CUDA // Check we have all the required features @@ -1404,10 +1406,10 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi #endif } - Slang::ComPtr<IRenderer> renderer; + Slang::ComPtr<IDevice> device; { - IRenderer::Desc desc = {}; - desc.rendererType = options.rendererType; + IDevice::Desc desc = {}; + desc.deviceType = options.deviceType; desc.adapter = options.adapter.getBuffer(); List<const char*> requiredFeatureList; @@ -1421,7 +1423,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi desc.slang.slangGlobalSession = session; { - SlangResult res = gfxCreateRenderer(&desc, renderer.writeRef()); + SlangResult res = gfxCreateDevice(&desc, device.writeRef()); if (SLANG_FAILED(res)) { // We need to be careful here about SLANG_E_NOT_AVAILABLE. This return value means that the renderer couldn't @@ -1443,13 +1445,13 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi return res; } - SLANG_ASSERT(renderer); + SLANG_ASSERT(device); } for (const auto& feature : requiredFeatureList) { // If doesn't have required feature... we have to give up - if (!renderer->hasFeature(feature)) + if (!device->hasFeature(feature)) { return SLANG_E_NOT_AVAILABLE; } @@ -1469,7 +1471,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi else app = new LegacyRenderTestApp(); renderDocBeginFrame(); - SLANG_RETURN_ON_FAIL(app->initialize(session, renderer, options, input)); + SLANG_RETURN_ON_FAIL(app->initialize(session, device, options, input)); app->update(); renderDocEndFrame(); app->finalize(); diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp index d42c5c7ef..57187fc44 100644 --- a/tools/render-test/shader-renderer-util.cpp +++ b/tools/render-test/shader-renderer-util.cpp @@ -34,19 +34,19 @@ void BindingStateImpl::apply(ICommandEncoder* encoder, PipelineType pipelineType /* static */ Result ShaderRendererUtil::generateTextureResource( const InputTextureDesc& inputDesc, int bindFlags, - IRenderer* renderer, + IDevice* device, ComPtr<ITextureResource>& textureOut) { TextureData texData; generateTextureData(texData, inputDesc); - return createTextureResource(inputDesc, texData, bindFlags, renderer, textureOut); + return createTextureResource(inputDesc, texData, bindFlags, device, textureOut); } /* static */ Result ShaderRendererUtil::createTextureResource( const InputTextureDesc& inputDesc, const TextureData& texData, int bindFlags, - IRenderer* renderer, + IDevice* device, ComPtr<ITextureResource>& textureOut) { ITextureResource::Desc textureResourceDesc; @@ -118,7 +118,7 @@ void BindingStateImpl::apply(ICommandEncoder* encoder, PipelineType pipelineType initData.numSubResources = numSubResources; initData.subResources = subResources.getBuffer(); - textureOut = renderer->createTextureResource(IResource::Usage::GenericRead, textureResourceDesc, &initData); + textureOut = device->createTextureResource(IResource::Usage::GenericRead, textureResourceDesc, &initData); return textureOut ? SLANG_OK : SLANG_FAIL; } @@ -128,7 +128,7 @@ void BindingStateImpl::apply(ICommandEncoder* encoder, PipelineType pipelineType bool isOutput, size_t bufferSize, const void* initData, - IRenderer* renderer, + IDevice* device, Slang::ComPtr<IBufferResource>& bufferOut) { IResource::Usage initialUsage = IResource::Usage::GenericRead; @@ -158,7 +158,8 @@ void BindingStateImpl::apply(ICommandEncoder* encoder, PipelineType pipelineType srcDesc.bindFlags = bindFlags; - ComPtr<IBufferResource> bufferResource = renderer->createBufferResource(initialUsage, srcDesc, initData); + ComPtr<IBufferResource> bufferResource = + device->createBufferResource(initialUsage, srcDesc, initData); if (!bufferResource) { return SLANG_FAIL; @@ -179,15 +180,15 @@ static ISamplerState::Desc _calcSamplerDesc(const InputSamplerDesc& srcDesc) return dstDesc; } -ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, +ComPtr<ISamplerState> _createSamplerState(IDevice* device, const InputSamplerDesc& srcDesc) { - return renderer->createSamplerState(_calcSamplerDesc(srcDesc)); + return device->createSamplerState(_calcSamplerDesc(srcDesc)); } /* static */ Result ShaderRendererUtil::createBindingState( const ShaderInputLayout& layout, - IRenderer* renderer, + IDevice* device, IBufferResource* addedConstantBuffer, BindingStateImpl** outBindingState) { @@ -284,7 +285,7 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, descriptorSetLayoutDesc.slotRangeCount = slotRangeDescs.getCount(); descriptorSetLayoutDesc.slotRanges = slotRangeDescs.getBuffer(); - auto descriptorSetLayout = renderer->createDescriptorSetLayout(descriptorSetLayoutDesc); + auto descriptorSetLayout = device->createDescriptorSetLayout(descriptorSetLayoutDesc); if(!descriptorSetLayout) return SLANG_FAIL; List<IPipelineLayout::DescriptorSetDesc> pipelineDescriptorSets; @@ -295,10 +296,11 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, pipelineLayoutDesc.descriptorSetCount = pipelineDescriptorSets.getCount(); pipelineLayoutDesc.descriptorSets = pipelineDescriptorSets.getBuffer(); - auto pipelineLayout = renderer->createPipelineLayout(pipelineLayoutDesc); + auto pipelineLayout = device->createPipelineLayout(pipelineLayoutDesc); if(!pipelineLayout) return SLANG_FAIL; - auto descriptorSet = renderer->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); + auto descriptorSet = + device->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); if(!descriptorSet) return SLANG_FAIL; List<BindingStateImpl::OutputBinding> outputBindings; @@ -335,7 +337,13 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, } ComPtr<IBufferResource> bufferResource; - SLANG_RETURN_ON_FAIL(createBufferResource(srcEntry.bufferDesc, srcEntry.isOutput, bufferSize, srcEntry.bufferData.getBuffer(), renderer, bufferResource)); + SLANG_RETURN_ON_FAIL(createBufferResource( + srcEntry.bufferDesc, + srcEntry.isOutput, + bufferSize, + srcEntry.bufferData.getBuffer(), + device, + bufferResource)); switch(srcBuffer.type) { @@ -348,7 +356,7 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, IResourceView::Desc viewDesc; viewDesc.type = IResourceView::Type::UnorderedAccess; viewDesc.format = srcBuffer.format; - auto bufferView = renderer->createBufferView( + auto bufferView = device->createBufferView( bufferResource, viewDesc); descriptorSet->setResource(rangeIndex, 0, bufferView); @@ -369,13 +377,14 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, case ShaderInputType::CombinedTextureSampler: { ComPtr<ITextureResource> texture; - SLANG_RETURN_ON_FAIL(generateTextureResource(srcEntry.textureDesc, textureBindFlags, renderer, texture)); + SLANG_RETURN_ON_FAIL(generateTextureResource( + srcEntry.textureDesc, textureBindFlags, device, texture)); - auto sampler = _createSamplerState(renderer, srcEntry.samplerDesc); + auto sampler = _createSamplerState(device, srcEntry.samplerDesc); IResourceView::Desc viewDesc; viewDesc.type = IResourceView::Type::ShaderResource; - auto textureView = renderer->createTextureView( + auto textureView = device->createTextureView( texture, viewDesc); @@ -394,13 +403,14 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, case ShaderInputType::Texture: { ComPtr<ITextureResource> texture; - SLANG_RETURN_ON_FAIL(generateTextureResource(srcEntry.textureDesc, textureBindFlags, renderer, texture)); + SLANG_RETURN_ON_FAIL(generateTextureResource( + srcEntry.textureDesc, textureBindFlags, device, texture)); // TODO: support UAV textures... IResourceView::Desc viewDesc; viewDesc.type = IResourceView::Type::ShaderResource; - auto textureView = renderer->createTextureView( + auto textureView = device->createTextureView( texture, viewDesc); @@ -423,7 +433,7 @@ ComPtr<ISamplerState> _createSamplerState(IRenderer* renderer, case ShaderInputType::Sampler: { - auto sampler = _createSamplerState(renderer, srcEntry.samplerDesc); + auto sampler = _createSamplerState(device, srcEntry.samplerDesc); descriptorSet->setSampler(rangeIndex, 0, sampler); } break; diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h index b79403bb4..ecb8fc8bb 100644 --- a/tools/render-test/shader-renderer-util.h +++ b/tools/render-test/shader-renderer-util.h @@ -47,22 +47,24 @@ struct BindingStateImpl : public Slang::RefObject int m_numRenderTargets = 1; }; -ComPtr<ISamplerState> _createSamplerState( - IRenderer* renderer, - const InputSamplerDesc& srcDesc); +ComPtr<ISamplerState> _createSamplerState(IDevice* device, const InputSamplerDesc& srcDesc); /// Utility class containing functions that construct items on the renderer using the ShaderInputLayout representation struct ShaderRendererUtil { /// Generate a texture using the InputTextureDesc and construct a TextureResource using the Renderer with the contents - static Slang::Result generateTextureResource(const InputTextureDesc& inputDesc, int bindFlags, IRenderer* renderer, ComPtr<ITextureResource>& textureOut); + static Slang::Result generateTextureResource( + const InputTextureDesc& inputDesc, + int bindFlags, + IDevice* device, + ComPtr<ITextureResource>& textureOut); /// Create texture resource using inputDesc, and texData to describe format, and contents static Slang::Result createTextureResource( const InputTextureDesc& inputDesc, const TextureData& texData, int bindFlags, - IRenderer* renderer, + IDevice* device, ComPtr<ITextureResource>& textureOut); /// Create the BufferResource using the renderer from the contents of inputDesc @@ -71,13 +73,13 @@ struct ShaderRendererUtil bool isOutput, size_t bufferSize, const void* initData, - IRenderer* renderer, + IDevice* renderer, ComPtr<IBufferResource>& bufferOut); /// Create BindingState::Desc from the contents of layout static Slang::Result createBindingState( const ShaderInputLayout& layout, - IRenderer* renderer, + IDevice* renderer, IBufferResource* addedConstantBuffer, BindingStateImpl** outBindingState); }; |
