diff options
| -rw-r--r-- | source/core/slang-string.h | 2 | ||||
| -rw-r--r-- | tools/gfx/d3d11/render-d3d11.cpp | 144 | ||||
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 151 | ||||
| -rw-r--r-- | tools/gfx/render-graphics-common.cpp | 2 | ||||
| -rw-r--r-- | tools/gfx/render.h | 1 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 1 |
6 files changed, 175 insertions, 126 deletions
diff --git a/source/core/slang-string.h b/source/core/slang-string.h index 9f6eaafa7..cec4b0a09 100644 --- a/source/core/slang-string.h +++ b/source/core/slang-string.h @@ -72,7 +72,7 @@ namespace Slang explicit UnownedStringSlice(char const* a) : m_begin(a), - m_end(a + strlen(a)) + m_end(a ? a + strlen(a) : nullptr) {} UnownedStringSlice(char const* b, char const* e) : m_begin(b) diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index 4ac90f47f..a2cf63a8f 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -692,6 +692,15 @@ SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle) return SLANG_FAIL; } + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice_ = + (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3dModule, "D3D11CreateDevice"); + if (!D3D11CreateDevice_) + { + fprintf(stderr, + "error: failed load symbol 'D3D11CreateDevice'\n"); + return SLANG_FAIL; + } + // Our swap chain uses RGBA8 with sRGB, with double buffering. DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; @@ -773,20 +782,36 @@ SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle) const int startFeatureIndex = (deviceCheckFlags & DeviceCheckFlag::UseFullFeatureLevel) ? 0 : 1; const UINT deviceFlags = (deviceCheckFlags & DeviceCheckFlag::UseDebug) ? D3D11_CREATE_DEVICE_DEBUG : 0; - res = D3D11CreateDeviceAndSwapChain_( - adapter, - driverType, - nullptr, // software - deviceFlags, - &featureLevels[startFeatureIndex], - totalNumFeatureLevels - startFeatureIndex, - D3D11_SDK_VERSION, - &swapChainDesc, - m_swapChain.writeRef(), - m_device.writeRef(), - &featureLevel, - m_immediateContext.writeRef()); - + if (windowHandle) + { + res = D3D11CreateDeviceAndSwapChain_( + adapter, + driverType, + nullptr, // software + deviceFlags, + &featureLevels[startFeatureIndex], + totalNumFeatureLevels - startFeatureIndex, + D3D11_SDK_VERSION, + &swapChainDesc, + m_swapChain.writeRef(), + m_device.writeRef(), + &featureLevel, + m_immediateContext.writeRef()); + } + else + { + res = D3D11CreateDevice_( + adapter, + driverType, + nullptr, + deviceFlags, + &featureLevels[startFeatureIndex], + totalNumFeatureLevels - startFeatureIndex, + D3D11_SDK_VERSION, + m_device.writeRef(), + &featureLevel, + m_immediateContext.writeRef()); + } // Check if successfully constructed - if so we are done. if (SLANG_SUCCEEDED(res)) { @@ -799,7 +824,8 @@ SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle) return res; } // Check we have a swap chain, context and device - SLANG_ASSERT(m_immediateContext && m_swapChain && m_device); + SLANG_ASSERT(m_immediateContext && m_device); + SLANG_ASSERT(!windowHandle || m_swapChain); } // NVAPI @@ -841,54 +867,55 @@ SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle) static const IID kIID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c }; - - SLANG_RETURN_ON_FAIL(m_swapChain->GetBuffer(0, kIID_ID3D11Texture2D, (void**)m_backBufferTexture.writeRef())); - -// for (int i = 0; i < 8; i++) + if (m_swapChain) { - ComPtr<ID3D11Texture2D> texture; - D3D11_TEXTURE2D_DESC textureDesc; - m_backBufferTexture->GetDesc(&textureDesc); - SLANG_RETURN_ON_FAIL(m_device->CreateTexture2D(&textureDesc, nullptr, texture.writeRef())); - - ComPtr<ID3D11RenderTargetView> rtv; - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - rtvDesc.Texture2D.MipSlice = 0; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - SLANG_RETURN_ON_FAIL(m_device->CreateRenderTargetView(texture, &rtvDesc, rtv.writeRef())); + SLANG_RETURN_ON_FAIL(m_swapChain->GetBuffer(0, kIID_ID3D11Texture2D, (void**)m_backBufferTexture.writeRef())); - TextureResource::Desc resourceDesc; - resourceDesc.init2D(IResource::Type::Texture2D, Format::RGBA_Unorm_UInt8, textureDesc.Width, textureDesc.Height, 1); - - ComPtr<ITextureResource> primaryRenderTargetTexture; - SLANG_RETURN_ON_FAIL(createTextureResource(IResource::Usage::RenderTarget, resourceDesc, nullptr, primaryRenderTargetTexture.writeRef())); + // for (int i = 0; i < 8; i++) + { + ComPtr<ID3D11Texture2D> texture; + D3D11_TEXTURE2D_DESC textureDesc; + m_backBufferTexture->GetDesc(&textureDesc); + SLANG_RETURN_ON_FAIL(m_device->CreateTexture2D(&textureDesc, nullptr, texture.writeRef())); - IResourceView::Desc viewDesc; - viewDesc.format = resourceDesc.format; - viewDesc.type = IResourceView::Type::RenderTarget; - ComPtr<IResourceView> primaryRenderTargetView; - SLANG_RETURN_ON_FAIL(createTextureView(primaryRenderTargetTexture, viewDesc, primaryRenderTargetView.writeRef())); + ComPtr<ID3D11RenderTargetView> rtv; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + rtvDesc.Texture2D.MipSlice = 0; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + SLANG_RETURN_ON_FAIL(m_device->CreateRenderTargetView(texture, &rtvDesc, rtv.writeRef())); + + TextureResource::Desc resourceDesc; + resourceDesc.init2D(IResource::Type::Texture2D, Format::RGBA_Unorm_UInt8, textureDesc.Width, textureDesc.Height, 1); + + ComPtr<ITextureResource> primaryRenderTargetTexture; + SLANG_RETURN_ON_FAIL(createTextureResource(IResource::Usage::RenderTarget, resourceDesc, nullptr, primaryRenderTargetTexture.writeRef())); + + IResourceView::Desc viewDesc; + viewDesc.format = resourceDesc.format; + viewDesc.type = IResourceView::Type::RenderTarget; + ComPtr<IResourceView> primaryRenderTargetView; + SLANG_RETURN_ON_FAIL(createTextureView(primaryRenderTargetTexture, viewDesc, primaryRenderTargetView.writeRef())); + + m_primaryRenderTargetTexture = dynamic_cast<TextureResourceImpl*>(primaryRenderTargetTexture.get()); + m_primaryRenderTargetView = dynamic_cast<RenderTargetViewImpl*>(primaryRenderTargetView.get()); + } - m_primaryRenderTargetTexture = dynamic_cast<TextureResourceImpl*>(primaryRenderTargetTexture.get()); - m_primaryRenderTargetView = dynamic_cast<RenderTargetViewImpl*>(primaryRenderTargetView.get()); + // m_immediateContext->OMSetRenderTargets(1, m_primaryRenderTargetView->m_rtv.readRef(), nullptr); + m_rtvBindings[0] = m_primaryRenderTargetView->m_rtv; + m_targetBindingsDirty[int(PipelineType::Graphics)] = true; + + // Similarly, we are going to set up a viewport once, and then never + // switch, since this is a simple test app. + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = (float)desc.width; + viewport.Height = (float)desc.height; + viewport.MaxDepth = 1; // TODO(tfoley): use reversed depth + viewport.MinDepth = 0; + m_immediateContext->RSSetViewports(1, &viewport); } - -// m_immediateContext->OMSetRenderTargets(1, m_primaryRenderTargetView->m_rtv.readRef(), nullptr); - m_rtvBindings[0] = m_primaryRenderTargetView->m_rtv; - m_targetBindingsDirty[int(PipelineType::Graphics)] = true; - - // Similarly, we are going to set up a viewport once, and then never - // switch, since this is a simple test app. - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = (float)desc.width; - viewport.Height = (float)desc.height; - viewport.MaxDepth = 1; // TODO(tfoley): use reversed depth - viewport.MinDepth = 0; - m_immediateContext->RSSetViewports(1, &viewport); - return SLANG_OK; } @@ -2123,6 +2150,7 @@ Result D3D11Renderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc case DescriptorSlotType::SampledImage: case DescriptorSlotType::UniformTexelBuffer: case DescriptorSlotType::InputAttachment: + case DescriptorSlotType::ReadOnlyStorageBuffer: rangeInfo.type = D3D11DescriptorSlotType::ShaderResourceView; break; diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 3db93df50..9f208f83c 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -992,6 +992,7 @@ void D3D12Renderer::beginRender() _resetCommandList(); // Indicate that the render target needs to be writable + if (m_swapChain) { D3D12BarrierSubmitter submitter(m_commandList); m_renderTargets[m_renderTargetIndex]->transition(D3D12_RESOURCE_STATE_RENDER_TARGET, submitter); @@ -1008,30 +1009,31 @@ void D3D12Renderer::endRender() const UInt64 signalValue = m_fence.nextSignal(m_commandQueue); m_circularResourceHeap.addSync(signalValue); } - - D3D12Resource& backBuffer = *m_backBuffers[m_renderTargetIndex]; - if (m_isMultiSampled) + if (m_swapChain) { - // MSAA resolve - D3D12Resource& renderTarget = *m_renderTargets[m_renderTargetIndex]; - assert(&renderTarget != &backBuffer); - // Barriers to wait for the render target, and the backbuffer to be in correct state + D3D12Resource& backBuffer = *m_backBuffers[m_renderTargetIndex]; + if (m_isMultiSampled) { - D3D12BarrierSubmitter submitter(m_commandList); - renderTarget.transition(D3D12_RESOURCE_STATE_RESOLVE_SOURCE, submitter); - backBuffer.transition(D3D12_RESOURCE_STATE_RESOLVE_DEST, submitter); - } + // MSAA resolve + D3D12Resource& renderTarget = *m_renderTargets[m_renderTargetIndex]; + assert(&renderTarget != &backBuffer); + // Barriers to wait for the render target, and the backbuffer to be in correct state + { + D3D12BarrierSubmitter submitter(m_commandList); + renderTarget.transition(D3D12_RESOURCE_STATE_RESOLVE_SOURCE, submitter); + backBuffer.transition(D3D12_RESOURCE_STATE_RESOLVE_DEST, submitter); + } - // Do the resolve... - m_commandList->ResolveSubresource(backBuffer, 0, renderTarget, 0, m_targetFormat); - } + // Do the resolve... + m_commandList->ResolveSubresource(backBuffer, 0, renderTarget, 0, m_targetFormat); + } - // Make the back buffer presentable - { - D3D12BarrierSubmitter submitter(m_commandList); - backBuffer.transition(D3D12_RESOURCE_STATE_PRESENT, submitter); + // Make the back buffer presentable + { + D3D12BarrierSubmitter submitter(m_commandList); + backBuffer.transition(D3D12_RESOURCE_STATE_PRESENT, submitter); + } } - SLANG_ASSERT_VOID_ON_FAIL(m_commandList->Close()); { @@ -1523,51 +1525,54 @@ Result D3D12Renderer::initialize(const Desc& desc, void* inWindowHandle) SLANG_RETURN_ON_FAIL(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(m_commandQueue.writeRef()))); - // Describe the swap chain. - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferCount = m_numRenderTargets; - swapChainDesc.BufferDesc.Width = m_desc.width; - swapChainDesc.BufferDesc.Height = m_desc.height; - swapChainDesc.BufferDesc.Format = m_targetFormat; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.OutputWindow = m_hwnd; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.Windowed = TRUE; - - if (m_isFullSpeed) + if (inWindowHandle) { - m_hasVsync = false; - m_allowFullScreen = false; - } + // Describe the swap chain. + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = m_numRenderTargets; + swapChainDesc.BufferDesc.Width = m_desc.width; + swapChainDesc.BufferDesc.Height = m_desc.height; + swapChainDesc.BufferDesc.Format = m_targetFormat; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.OutputWindow = m_hwnd; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.Windowed = TRUE; - if (!m_hasVsync) - { - swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - } + if (m_isFullSpeed) + { + m_hasVsync = false; + m_allowFullScreen = false; + } - // Swap chain needs the queue so that it can force a flush on it. - ComPtr<IDXGISwapChain> swapChain; - SLANG_RETURN_ON_FAIL(m_deviceInfo.m_dxgiFactory->CreateSwapChain(m_commandQueue, &swapChainDesc, swapChain.writeRef())); - SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(m_swapChain.writeRef())); + if (!m_hasVsync) + { + swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + } - if (!m_hasVsync) - { - m_swapChainWaitableObject = m_swapChain->GetFrameLatencyWaitableObject(); + // Swap chain needs the queue so that it can force a flush on it. + ComPtr<IDXGISwapChain> swapChain; + SLANG_RETURN_ON_FAIL(m_deviceInfo.m_dxgiFactory->CreateSwapChain(m_commandQueue, &swapChainDesc, swapChain.writeRef())); + SLANG_RETURN_ON_FAIL(swapChain->QueryInterface(m_swapChain.writeRef())); - int maxLatency = m_numRenderTargets - 2; + if (!m_hasVsync) + { + m_swapChainWaitableObject = m_swapChain->GetFrameLatencyWaitableObject(); - // 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; + int maxLatency = m_numRenderTargets - 2; - m_swapChain->SetMaximumFrameLatency(maxLatency); - } + // 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_deviceInfo.m_dxgiFactory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); + // This sample does not support fullscreen transitions. + SLANG_RETURN_ON_FAIL(m_deviceInfo.m_dxgiFactory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); - m_renderTargetIndex = m_swapChain->GetCurrentBackBufferIndex(); + m_renderTargetIndex = m_swapChain->GetCurrentBackBufferIndex(); + } // Create descriptor heaps. @@ -1583,9 +1588,7 @@ Result D3D12Renderer::initialize(const Desc& desc, void* inWindowHandle) SLANG_RETURN_ON_FAIL(m_samplerAllocator.init(m_device, 16, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)); // Setup frame resources - { - SLANG_RETURN_ON_FAIL(createFrameResources()); - } + SLANG_RETURN_ON_FAIL(createFrameResources()); // Setup fence, and close the command list (as default state without begin/endRender is closed) { @@ -1614,7 +1617,15 @@ Result D3D12Renderer::initialize(const Desc& desc, void* inWindowHandle) Result D3D12Renderer::createFrameResources() { + // Set up frames + for (int i = 0; i < m_numRenderFrames; i++) + { + FrameInfo& frame = m_frameInfos[i]; + SLANG_RETURN_ON_FAIL(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(frame.m_commandAllocator.writeRef()))); + } + // Create back buffers + if (m_swapChain) { // D3D12_CPU_DESCRIPTOR_HANDLE rtvStart(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); @@ -1678,13 +1689,7 @@ Result D3D12Renderer::createFrameResources() } } - // Set up frames - for (int i = 0; i < m_numRenderFrames; i++) - { - FrameInfo& frame = m_frameInfos[i]; - SLANG_RETURN_ON_FAIL(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(frame.m_commandAllocator.writeRef()))); - } - + if (m_swapChain) { D3D12_RESOURCE_DESC desc = m_backBuffers[0]->getResource()->GetDesc(); assert(desc.Width == UINT64(m_desc.width) && desc.Height == UINT64(m_desc.height)); @@ -2367,7 +2372,7 @@ Result D3D12Renderer::createBufferView(IBufferResource* buffer, IResourceView::D srvDesc.Format = D3DUtil::getMapFormat(desc.format); srvDesc.Buffer.StructureByteStride = 0; srvDesc.Buffer.FirstElement = 0; - + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; if(resourceDesc.elementSize) { srvDesc.Buffer.StructureByteStride = resourceDesc.elementSize; @@ -3374,7 +3379,21 @@ Result D3D12Renderer::createDescriptorSetLayout(const IDescriptorSetLayout::Desc dxRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; } break; + case DescriptorSlotType::ReadOnlyStorageBuffer: + { + if (dxRegister < 0) + { + dxRegister = srvRegisterCounter; + } + srvRegisterCounter = dxRegister + bindingCount; + dxRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + dxRange.NumDescriptors = UINT(bindingCount); + dxRange.BaseShaderRegister = UINT(dxRegister); + dxRange.RegisterSpace = UINT(bindingSpace); + dxRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + } + break; case DescriptorSlotType::UniformBuffer: case DescriptorSlotType::DynamicUniformBuffer: { diff --git a/tools/gfx/render-graphics-common.cpp b/tools/gfx/render-graphics-common.cpp index 92ccc376c..747659d11 100644 --- a/tools/gfx/render-graphics-common.cpp +++ b/tools/gfx/render-graphics-common.cpp @@ -146,7 +146,7 @@ public: CASE(MutableTexture, StorageImage); CASE(TypedBuffer, UniformTexelBuffer); CASE(MutableTypedBuffer, StorageTexelBuffer); - CASE(RawBuffer, UniformBuffer); + CASE(RawBuffer, ReadOnlyStorageBuffer); CASE(MutableRawBuffer, StorageBuffer); CASE(InputRenderTarget, InputAttachment); CASE(InlineUniformData, InlineUniformBlock); diff --git a/tools/gfx/render.h b/tools/gfx/render.h index 8e1a5d665..eeef00a8f 100644 --- a/tools/gfx/render.h +++ b/tools/gfx/render.h @@ -684,6 +684,7 @@ enum class DescriptorSlotType UniformTexelBuffer, StorageTexelBuffer, UniformBuffer, + ReadOnlyStorageBuffer, StorageBuffer, DynamicUniformBuffer, DynamicStorageBuffer, diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 4e43bf249..88cd52ad7 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -2418,6 +2418,7 @@ static VkDescriptorType translateDescriptorType(DescriptorSlotType type) CASE(UniformTexelBuffer, UNIFORM_TEXEL_BUFFER); CASE(StorageTexelBuffer, STORAGE_TEXEL_BUFFER); CASE(UniformBuffer, UNIFORM_BUFFER); + CASE(ReadOnlyStorageBuffer, STORAGE_BUFFER); CASE(StorageBuffer, STORAGE_BUFFER); CASE(DynamicUniformBuffer, UNIFORM_BUFFER_DYNAMIC); CASE(DynamicStorageBuffer, STORAGE_BUFFER_DYNAMIC); |
