diff options
37 files changed, 1452 insertions, 1430 deletions
diff --git a/build/visual-studio/gfx/gfx.vcxproj b/build/visual-studio/gfx/gfx.vcxproj index 03c2bb427..5f05d7586 100644 --- a/build/visual-studio/gfx/gfx.vcxproj +++ b/build/visual-studio/gfx/gfx.vcxproj @@ -182,6 +182,7 @@ <ClInclude Include="..\..\..\slang-gfx.h" /> <ClInclude Include="..\..\..\tools\gfx\command-writer.h" /> <ClInclude Include="..\..\..\tools\gfx\cuda\render-cuda.h" /> + <ClInclude Include="..\..\..\tools\gfx\d3d\d3d-swapchain.h" /> <ClInclude Include="..\..\..\tools\gfx\d3d\d3d-util.h" /> <ClInclude Include="..\..\..\tools\gfx\d3d11\render-d3d11.h" /> <ClInclude Include="..\..\..\tools\gfx\d3d12\circular-resource-heap-d3d12.h" /> @@ -202,11 +203,11 @@ <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-descriptor-allocator.h" /> <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-device-queue.h" /> <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-module.h" /> - <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-swap-chain.h" /> <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-util.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\tools\gfx\cuda\render-cuda.cpp" /> + <ClCompile Include="..\..\..\tools\gfx\d3d\d3d-swapchain.cpp" /> <ClCompile Include="..\..\..\tools\gfx\d3d\d3d-util.cpp" /> <ClCompile Include="..\..\..\tools\gfx\d3d11\render-d3d11.cpp" /> <ClCompile Include="..\..\..\tools\gfx\d3d12\circular-resource-heap-d3d12.cpp" /> @@ -226,7 +227,6 @@ <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-descriptor-allocator.cpp" /> <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-device-queue.cpp" /> <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-module.cpp" /> - <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-swap-chain.cpp" /> <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-util.cpp" /> </ItemGroup> <ItemGroup> diff --git a/build/visual-studio/gfx/gfx.vcxproj.filters b/build/visual-studio/gfx/gfx.vcxproj.filters index 10445aaf3..c7836d62f 100644 --- a/build/visual-studio/gfx/gfx.vcxproj.filters +++ b/build/visual-studio/gfx/gfx.vcxproj.filters @@ -18,6 +18,9 @@ <ClInclude Include="..\..\..\tools\gfx\cuda\render-cuda.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\tools\gfx\d3d\d3d-swapchain.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="..\..\..\tools\gfx\d3d\d3d-util.h"> <Filter>Header Files</Filter> </ClInclude> @@ -78,9 +81,6 @@ <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-module.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-swap-chain.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\tools\gfx\vulkan\vk-util.h"> <Filter>Header Files</Filter> </ClInclude> @@ -89,6 +89,9 @@ <ClCompile Include="..\..\..\tools\gfx\cuda\render-cuda.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\tools\gfx\d3d\d3d-swapchain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\..\..\tools\gfx\d3d\d3d-util.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -146,9 +149,6 @@ <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-module.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-swap-chain.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\..\..\tools\gfx\vulkan\vk-util.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/examples/gpu-printing/main.cpp b/examples/gpu-printing/main.cpp index e95233571..3fd1e460a 100644 --- a/examples/gpu-printing/main.cpp +++ b/examples/gpu-printing/main.cpp @@ -14,22 +14,9 @@ using namespace gfx; #include "gpu-printing.h" -ComPtr<slang::ISession> createSlangSession(gfx::IRenderer* renderer) +ComPtr<slang::ISession> createSlangSession(gfx::IDevice* device) { - ComPtr<slang::IGlobalSession> slangGlobalSession; - slangGlobalSession.attach(spCreateSession(NULL)); - - slang::TargetDesc targetDesc; - targetDesc.format = SLANG_DXBC; - targetDesc.profile = spFindProfile(slangGlobalSession, "sm_5_0"); - - slang::SessionDesc sessionDesc; - sessionDesc.targetCount = 1; - sessionDesc.targets = &targetDesc; - - ComPtr<slang::ISession> slangSession; - slangGlobalSession->createSession(sessionDesc, slangSession.writeRef()); - + ComPtr<slang::ISession> slangSession = device->getSlangSession(); return slangSession; } @@ -63,7 +50,7 @@ struct ExampleProgram int gWindowWidth = 640; int gWindowHeight = 480; -ComPtr<gfx::IRenderer> gRenderer; +ComPtr<gfx::IDevice> gDevice; ComPtr<slang::ISession> gSlangSession; ComPtr<slang::IModule> gSlangModule; @@ -103,19 +90,18 @@ ComPtr<gfx::IShaderProgram> loadComputeProgram(slang::IModule* slangModule, char programDesc.kernels = &kernelDescs[0]; programDesc.kernelCount = 2; - auto shaderProgram = gRenderer->createProgram(programDesc); + auto shaderProgram = gDevice->createProgram(programDesc); return shaderProgram; } Result execute() { - IRenderer::Desc rendererDesc; - rendererDesc.rendererType = gfx::RendererType::DirectX11; - Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef()); + IDevice::Desc deviceDesc; + Result res = gfxCreateDevice(&deviceDesc, gDevice.writeRef()); if(SLANG_FAILED(res)) return res; - gSlangSession = createSlangSession(gRenderer); + gSlangSession = createSlangSession(gDevice); gSlangModule = compileShaderModuleFromFile(gSlangSession, "kernels.slang"); gProgram = loadComputeProgram(gSlangModule, "computeMain"); @@ -128,7 +114,7 @@ Result execute() IDescriptorSetLayout::Desc descriptorSetLayoutDesc; descriptorSetLayoutDesc.slotRangeCount = 1; descriptorSetLayoutDesc.slotRanges = &slotRanges[0]; - auto descriptorSetLayout = gRenderer->createDescriptorSetLayout(descriptorSetLayoutDesc); + auto descriptorSetLayout = gDevice->createDescriptorSetLayout(descriptorSetLayoutDesc); if(!descriptorSetLayout) return SLANG_FAIL; IPipelineLayout::DescriptorSetDesc descriptorSets[] = @@ -139,7 +125,7 @@ Result execute() pipelineLayoutDesc.renderTargetCount = 1; pipelineLayoutDesc.descriptorSetCount = 1; pipelineLayoutDesc.descriptorSets = &descriptorSets[0]; - auto pipelineLayout = gRenderer->createPipelineLayout(pipelineLayoutDesc); + auto pipelineLayout = gDevice->createPipelineLayout(pipelineLayoutDesc); if(!pipelineLayout) return SLANG_FAIL; gPipelineLayout = pipelineLayout; @@ -147,7 +133,8 @@ Result execute() // Once we have the descriptor set layout, we can allocate // and fill in a descriptor set to hold our parameters. // - auto descriptorSet = gRenderer->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); + auto descriptorSet = + gDevice->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); if(!descriptorSet) return SLANG_FAIL; gDescriptorSet = descriptorSet; @@ -155,7 +142,7 @@ Result execute() ComputePipelineStateDesc desc; desc.pipelineLayout = gPipelineLayout; desc.program = gProgram; - auto pipelineState = gRenderer->createComputePipelineState(desc); + auto pipelineState = gDevice->createComputePipelineState(desc); if(!pipelineState) return SLANG_FAIL; gPipelineState = pipelineState; @@ -166,14 +153,15 @@ Result execute() printBufferDesc.init(printBufferSize); printBufferDesc.elementSize = sizeof(uint32_t); printBufferDesc.cpuAccessFlags = IResource::AccessFlag::Read; // | Resource::AccessFlag::Write; - auto printBuffer = gRenderer->createBufferResource(IResource::Usage::UnorderedAccess, printBufferDesc); + auto printBuffer = + gDevice->createBufferResource(IResource::Usage::UnorderedAccess, printBufferDesc); IResourceView::Desc printBufferViewDesc; printBufferViewDesc.type = IResourceView::Type::UnorderedAccess; - auto printBufferView = gRenderer->createBufferView(printBuffer, printBufferViewDesc); + auto printBufferView = gDevice->createBufferView(printBuffer, printBufferViewDesc); ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics}; - auto queue = gRenderer->createCommandQueue(queueDesc); + auto queue = gDevice->createCommandQueue(queueDesc); auto commandBuffer = queue->createCommandBuffer(); auto encoder = commandBuffer->encodeComputeCommands(); // TODO: need to copy a zero into the start of the print buffer! @@ -189,7 +177,7 @@ Result execute() // TODO: need to copy from the print buffer to a staging buffer... ComPtr<ISlangBlob> blob; - gRenderer->readBufferResource(printBuffer, 0, printBufferSize, blob.writeRef()); + gDevice->readBufferResource(printBuffer, 0, printBufferSize, blob.writeRef()); gGPUPrinting.processGPUPrintCommands(blob->getBufferPointer(), printBufferSize); diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp index 330b52a59..7b43abcab 100644 --- a/examples/hello-world/main.cpp +++ b/examples/hello-world/main.cpp @@ -87,7 +87,7 @@ void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob) // about the program, which is what a `slang::ProgramLayout` provides. // gfx::Result loadShaderProgram( - gfx::IRenderer* renderer, + gfx::IDevice* device, gfx::IShaderProgram** outProgram) { // We need to obatin a compilation session (`slang::ISession`) that will provide @@ -96,7 +96,7 @@ gfx::Result loadShaderProgram( // Our example application uses the `gfx` graphics API abstraction layer, which already // creates a Slang compilation session for us, so we just grab and use it here. ComPtr<slang::ISession> slangSession; - slangSession = renderer->getSlangSession(); + slangSession = device->getSlangSession(); // We can now start loading code into the slang session. // @@ -182,7 +182,7 @@ gfx::Result loadShaderProgram( gfx::IShaderProgram::Desc programDesc = {}; programDesc.pipelineType = gfx::PipelineType::Graphics; programDesc.slangProgram = linkedProgram; - SLANG_RETURN_ON_FAIL(renderer->createProgram(programDesc, outProgram)); + SLANG_RETURN_ON_FAIL(device->createProgram(programDesc, outProgram)); return SLANG_OK; } @@ -211,7 +211,7 @@ const uint32_t kSwapchainImageCount = 2; // building an example program. // RefPtr<platform::Window> gWindow; -Slang::ComPtr<gfx::IRenderer> gRenderer; +Slang::ComPtr<gfx::IDevice> gDevice; ComPtr<gfx::IPipelineState> gPipelineState; ComPtr<gfx::IShaderObject> gRootObject; @@ -233,6 +233,7 @@ Slang::Result initialize() windowDesc.title = "Hello, World!"; windowDesc.width = gWindowWidth; windowDesc.height = gWindowHeight; + windowDesc.style = platform::WindowStyle::FixedSize; gWindow = platform::Application::createWindow(windowDesc); gWindow->events.mainLoop = [this]() { renderFrame(); }; // Initialize the rendering layer. @@ -242,14 +243,13 @@ Slang::Result initialize() // A future version of this example may support multiple // platforms/APIs. // - IRenderer::Desc rendererDesc = {}; - rendererDesc.rendererType = gfx::RendererType::DirectX11; - gfx::Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef()); + IDevice::Desc deviceDesc = {}; + gfx::Result res = gfxCreateDevice(&deviceDesc, gDevice.writeRef()); if(SLANG_FAILED(res)) return res; ICommandQueue::Desc queueDesc = {}; queueDesc.type = ICommandQueue::QueueType::Graphics; - gQueue = gRenderer->createCommandQueue(queueDesc); + gQueue = gDevice->createCommandQueue(queueDesc); // Now we will create objects needed to configur the "input assembler" // (IA) stage of the D3D pipeline. @@ -260,7 +260,7 @@ Slang::Result initialize() { "POSITION", 0, Format::RGB_Float32, offsetof(Vertex, position) }, { "COLOR", 0, Format::RGB_Float32, offsetof(Vertex, color) }, }; - auto inputLayout = gRenderer->createInputLayout( + auto inputLayout = gDevice->createInputLayout( &inputElements[0], 2); if(!inputLayout) return SLANG_FAIL; @@ -271,7 +271,7 @@ Slang::Result initialize() IBufferResource::Desc vertexBufferDesc; vertexBufferDesc.init(kVertexCount * sizeof(Vertex)); vertexBufferDesc.setDefaults(IResource::Usage::VertexBuffer); - gVertexBuffer = gRenderer->createBufferResource( + gVertexBuffer = gDevice->createBufferResource( IResource::Usage::VertexBuffer, vertexBufferDesc, &kVertexData[0]); @@ -281,7 +281,7 @@ Slang::Result initialize() // the code from `shaders.slang` into the graphics API. // ComPtr<IShaderProgram> shaderProgram; - SLANG_RETURN_ON_FAIL(loadShaderProgram(gRenderer, shaderProgram.writeRef())); + SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, shaderProgram.writeRef())); // In order to bind shader parameters to the pipeline, we need // to know how those parameters were assigned to locations/bindings/registers @@ -312,7 +312,7 @@ Slang::Result initialize() // layout as being similar in spirit to a "root signature" or "pipeline layout." // ComPtr<IShaderObject> rootObject; - SLANG_RETURN_ON_FAIL(gRenderer->createRootShaderObject(shaderProgram, rootObject.writeRef())); + SLANG_RETURN_ON_FAIL(gDevice->createRootShaderObject(shaderProgram, rootObject.writeRef())); gRootObject = rootObject; // Create swapchain and framebuffers. @@ -324,7 +324,7 @@ Slang::Result initialize() swapchainDesc.queue = gQueue; gfx::WindowHandle windowHandle; memcpy(&windowHandle, &gWindow->getNativeHandle(), sizeof(windowHandle)); - gSwapchain = gRenderer->createSwapchain(swapchainDesc, windowHandle); + gSwapchain = gDevice->createSwapchain(swapchainDesc, windowHandle); IFramebufferLayout::AttachmentLayout renderTargetLayout = {gSwapchain->getDesc().format, 1}; IFramebufferLayout::AttachmentLayout depthLayout = {gfx::Format::D_Float32, 1}; @@ -334,7 +334,7 @@ Slang::Result initialize() framebufferLayoutDesc.depthStencil = &depthLayout; ComPtr<IFramebufferLayout> framebufferLayout; SLANG_RETURN_ON_FAIL( - gRenderer->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef())); + gDevice->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef())); for (uint32_t i = 0; i < kSwapchainImageCount; i++) { @@ -347,7 +347,7 @@ Slang::Result initialize() gSwapchain->getDesc().height, 0); - ComPtr<gfx::ITextureResource> depthBufferResource = gRenderer->createTextureResource( + ComPtr<gfx::ITextureResource> depthBufferResource = gDevice->createTextureResource( gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); ComPtr<gfx::ITextureResource> colorBuffer; gSwapchain->getImage(i, colorBuffer.writeRef()); @@ -357,21 +357,21 @@ Slang::Result initialize() colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget; ComPtr<gfx::IResourceView> rtv = - gRenderer->createTextureView(colorBuffer.get(), colorBufferViewDesc); + gDevice->createTextureView(colorBuffer.get(), colorBufferViewDesc); gfx::IResourceView::Desc depthBufferViewDesc = {}; depthBufferViewDesc.format = gfx::Format::D_Float32; depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil; ComPtr<gfx::IResourceView> dsv = - gRenderer->createTextureView(depthBufferResource.get(), depthBufferViewDesc); + gDevice->createTextureView(depthBufferResource.get(), depthBufferViewDesc); gfx::IFramebuffer::Desc framebufferDesc = {}; framebufferDesc.renderTargetCount = 1; framebufferDesc.depthStencilView = dsv.get(); framebufferDesc.renderTargetViews = rtv.readRef(); framebufferDesc.layout = framebufferLayout; - ComPtr<gfx::IFramebuffer> frameBuffer = gRenderer->createFramebuffer(framebufferDesc); + ComPtr<gfx::IFramebuffer> frameBuffer = gDevice->createFramebuffer(framebufferDesc); gFramebuffers.add(frameBuffer); } @@ -382,7 +382,7 @@ Slang::Result initialize() desc.inputLayout = inputLayout; desc.program = shaderProgram; desc.framebufferLayout = framebufferLayout; - auto pipelineState = gRenderer->createGraphicsPipelineState(desc); + auto pipelineState = gDevice->createGraphicsPipelineState(desc); if (!pipelineState) return SLANG_FAIL; @@ -403,7 +403,7 @@ Slang::Result initialize() depthStencilAccess.finalState = ResourceState::DepthWrite; renderPassDesc.renderTargetAccess = &renderTargetAccess; renderPassDesc.depthStencilAccess = &depthStencilAccess; - gRenderPass = gRenderer->createRenderPassLayout(renderPassDesc); + gRenderPass = gDevice->createRenderPassLayout(renderPassDesc); return SLANG_OK; } @@ -431,14 +431,7 @@ void renderFrame() // basis, even though the data that is loaded does not change // per-frame (we always use an identity matrix). // - float identityMatrix[] = - { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - }; - gfxGetIdentityProjection(gfxGetProjectionStyle(gRenderer->getRendererType()), identityMatrix); + auto deviceInfo = gDevice->getDeviceInfo(); // // We know that `gRootObject` is a root shader object created @@ -474,7 +467,8 @@ void renderFrame() // Once we have formed a cursor that "points" at the // model-view projection matrix, we can set its data directly. // - rootCursor["Uniforms"]["modelViewProjection"].setData(identityMatrix, sizeof(identityMatrix)); + rootCursor["Uniforms"]["modelViewProjection"].setData( + deviceInfo.identityProjectionMatrix, sizeof(float) * 16); // // Some readers might be concerned about the performance o // the above operations because of the use of strings. For diff --git a/examples/shader-object/main.cpp b/examples/shader-object/main.cpp index d368cd9aa..aaafc010a 100644 --- a/examples/shader-object/main.cpp +++ b/examples/shader-object/main.cpp @@ -30,7 +30,7 @@ void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob) // Loads the shader code defined in `shader-object.slang` for use by the `gfx` layer. // Result loadShaderProgram( - gfx::IRenderer* renderer, + gfx::IDevice* device, ComPtr<gfx::IShaderProgram>& outShaderProgram, slang::ProgramLayout*& slangReflection) { @@ -40,7 +40,7 @@ Result loadShaderProgram( // Our example application uses the `gfx` graphics API abstraction layer, which already // creates a Slang compilation session for us, so we just grab and use it here. ComPtr<slang::ISession> slangSession; - SLANG_RETURN_ON_FAIL(renderer->getSlangSession(slangSession.writeRef())); + SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef())); // Once the session has been obtained, we can start loading code into it. // @@ -123,7 +123,7 @@ Result loadShaderProgram( programDesc.pipelineType = gfx::PipelineType::Compute; programDesc.slangProgram = composedProgram.get(); - auto shaderProgram = renderer->createProgram(programDesc); + auto shaderProgram = device->createProgram(programDesc); outShaderProgram = shaderProgram; return SLANG_OK; @@ -134,24 +134,23 @@ int main() { // Creates a `gfx` renderer, which provides the main interface for // interacting with the graphics API. - Slang::ComPtr<gfx::IRenderer> renderer; - IRenderer::Desc rendererDesc = {}; - rendererDesc.rendererType = RendererType::DirectX11; - SLANG_RETURN_ON_FAIL(gfxCreateRenderer(&rendererDesc, renderer.writeRef())); + Slang::ComPtr<gfx::IDevice> device; + IDevice::Desc deviceDesc = {}; + SLANG_RETURN_ON_FAIL(gfxCreateDevice(&deviceDesc, device.writeRef())); // Now we can load the shader code. // A `gfx::IShaderProgram` object for use in the `gfx` layer. ComPtr<gfx::IShaderProgram> shaderProgram; // A composed `IComponentType` that gives us reflection info on the shader code. slang::ProgramLayout* slangReflection; - SLANG_RETURN_ON_FAIL(loadShaderProgram(renderer, shaderProgram, slangReflection)); + SLANG_RETURN_ON_FAIL(loadShaderProgram(device, shaderProgram, slangReflection)); // Create a pipeline state with the loaded shader. gfx::ComputePipelineStateDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); ComPtr<gfx::IPipelineState> pipelineState; SLANG_RETURN_ON_FAIL( - renderer->createComputePipelineState(pipelineDesc, pipelineState.writeRef())); + device->createComputePipelineState(pipelineDesc, pipelineState.writeRef())); // Create and initiate our input/output buffer. const int numberCount = 4; @@ -165,7 +164,7 @@ int main() bufferDesc.cpuAccessFlags = IResource::AccessFlag::Write | IResource::AccessFlag::Read; ComPtr<gfx::IBufferResource> numbersBuffer; - SLANG_RETURN_ON_FAIL(renderer->createBufferResource( + SLANG_RETURN_ON_FAIL(device->createBufferResource( gfx::IResource::Usage::UnorderedAccess, bufferDesc, (void*)initialData, @@ -176,7 +175,7 @@ int main() gfx::IResourceView::Desc viewDesc = {}; viewDesc.type = gfx::IResourceView::Type::UnorderedAccess; viewDesc.format = gfx::Format::Unknown; - SLANG_RETURN_ON_FAIL(renderer->createBufferView(numbersBuffer, viewDesc, bufferView.writeRef())); + SLANG_RETURN_ON_FAIL(device->createBufferView(numbersBuffer, viewDesc, bufferView.writeRef())); // Now comes the interesting part: binding the shader parameter for the // compute kernel that we about to launch. We would like to construct @@ -185,7 +184,7 @@ int main() // To start, we create a root shader object that represents the root level // scope of the shader parameters. ComPtr<gfx::IShaderObject> rootObject; - SLANG_RETURN_ON_FAIL(renderer->createRootShaderObject(shaderProgram, rootObject.writeRef())); + SLANG_RETURN_ON_FAIL(device->createRootShaderObject(shaderProgram, rootObject.writeRef())); // We can set parameters directly with `rootObject`, but that requires us to use // the Slang reflection API to obtain the proper offsets into the root object for each parameter. // We implemented these logic in the `ShaderCursor` helper class, which simplifies the user @@ -200,8 +199,7 @@ int main() // Now we can use this type to create a shader object that can be bound to the root object. ComPtr<gfx::IShaderObject> transformer; - SLANG_RETURN_ON_FAIL( - renderer->createShaderObject(addTransformerType, transformer.writeRef())); + SLANG_RETURN_ON_FAIL(device->createShaderObject(addTransformerType, transformer.writeRef())); // Set the `c` field of the `AddTransformer`. float c = 1.0f; gfx::ShaderCursor(transformer).getPath("c").setData(&c, sizeof(float)); @@ -213,7 +211,7 @@ int main() // to bind the pipeline and root object and launch the kernel. { ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics}; - auto queue = renderer->createCommandQueue(queueDesc); + auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = queue->createCommandBuffer(); auto encoder = commandBuffer->encodeComputeCommands(); encoder->setPipelineState(pipelineState); @@ -226,7 +224,7 @@ int main() } // Read back the results. ComPtr<ISlangBlob> resultBlob; - SLANG_RETURN_ON_FAIL(renderer->readBufferResource( + SLANG_RETURN_ON_FAIL(device->readBufferResource( numbersBuffer, 0, numberCount * sizeof(float), resultBlob.writeRef())); auto result = reinterpret_cast<const float*>(resultBlob->getBufferPointer()); for (int i = 0; i < numberCount; i++) diff --git a/examples/shader-toy/main.cpp b/examples/shader-toy/main.cpp index 7c22954c0..70bff13a8 100644 --- a/examples/shader-toy/main.cpp +++ b/examples/shader-toy/main.cpp @@ -92,7 +92,7 @@ void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob) // The main interesting part of the host application code is where we // load, compile, inspect, and compose the Slang shader code. // -Result loadShaderProgram(gfx::IRenderer* renderer, ComPtr<gfx::IShaderProgram>& outShaderProgram) +Result loadShaderProgram(gfx::IDevice* device, ComPtr<gfx::IShaderProgram>& outShaderProgram) { // We need to obatin a compilation session (`slang::ISession`) that will provide // a scope to all the compilation and loading of code we do. @@ -100,7 +100,7 @@ Result loadShaderProgram(gfx::IRenderer* renderer, ComPtr<gfx::IShaderProgram>& // Our example application uses the `gfx` graphics API abstraction layer, which already // creates a Slang compilation session for us, so we just grab and use it here. ComPtr<slang::ISession> slangSession; - SLANG_RETURN_ON_FAIL(renderer->getSlangSession(slangSession.writeRef())); + SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef())); // Once the session has been obtained, we can start loading code into it. // @@ -322,7 +322,7 @@ Result loadShaderProgram(gfx::IRenderer* renderer, ComPtr<gfx::IShaderProgram>& programDesc.kernels = &kernelDescs[0]; programDesc.kernelCount = 2; - auto shaderProgram = renderer->createProgram(programDesc); + auto shaderProgram = device->createProgram(programDesc); outShaderProgram = shaderProgram; return SLANG_OK; @@ -333,9 +333,10 @@ int gWindowHeight = 768; const uint32_t kSwapchainImageCount = 2; Slang::RefPtr<platform::Window> gWindow; -Slang::ComPtr<gfx::IRenderer> gRenderer; +Slang::ComPtr<gfx::IDevice> gDevice; ComPtr<gfx::IBufferResource> gConstantBuffer; ComPtr<gfx::IPipelineLayout> gPipelineLayout; +ComPtr<gfx::IFramebufferLayout> gFramebufferLayout; ComPtr<gfx::IPipelineState> gPipelineState; ComPtr<gfx::IDescriptorSet> gDescriptorSet; ComPtr<gfx::IBufferResource> gVertexBuffer; @@ -347,7 +348,8 @@ ComPtr<gfx::ICommandQueue> gQueue; Result initialize() { platform::WindowDesc windowDesc; - windowDesc.title = "Slang Shader Toy"; + const char* title = "Slang Shader Toy"; + windowDesc.title = title; windowDesc.width = gWindowWidth; windowDesc.height = gWindowHeight; gWindow = platform::Application::createWindow(windowDesc); @@ -355,15 +357,21 @@ Result initialize() gWindow->events.mouseMove = [this](const platform::MouseEventArgs& e) { handleEvent(e); }; gWindow->events.mouseUp = [this](const platform::MouseEventArgs& e) { handleEvent(e); }; gWindow->events.mouseDown = [this](const platform::MouseEventArgs& e) { handleEvent(e); }; + gWindow->events.sizeChanged = Slang::Action<>(this, &ShaderToyApp::windowSizeChanged); - IRenderer::Desc rendererDesc; - rendererDesc.rendererType = RendererType::DirectX11; - Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef()); + IDevice::Desc deviceDesc; + deviceDesc.deviceType = DeviceType::Vulkan; + Result res = gfxCreateDevice(&deviceDesc, gDevice.writeRef()); if(SLANG_FAILED(res)) return res; + auto deviceInfo = gDevice->getDeviceInfo(); + Slang::StringBuilder titleSb; + titleSb << title << " (" << deviceInfo.apiName << ": " << deviceInfo.adapterName << ")"; + gWindow->setText(titleSb.getBuffer()); + ICommandQueue::Desc queueDesc = {}; queueDesc.type = ICommandQueue::QueueType::Graphics; - gQueue = gRenderer->createCommandQueue(queueDesc); + gQueue = gDevice->createCommandQueue(queueDesc); int constantBufferSize = sizeof(Uniforms); @@ -372,15 +380,14 @@ Result initialize() constantBufferDesc.setDefaults(IResource::Usage::ConstantBuffer); constantBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; - gConstantBuffer = gRenderer->createBufferResource( - IResource::Usage::ConstantBuffer, - constantBufferDesc); + gConstantBuffer = + gDevice->createBufferResource(IResource::Usage::ConstantBuffer, constantBufferDesc); if(!gConstantBuffer) return SLANG_FAIL; InputElementDesc inputElements[] = { { "POSITION", 0, Format::RG_Float32, offsetof(FullScreenTriangle::Vertex, position) }, }; - auto inputLayout = gRenderer->createInputLayout( + auto inputLayout = gDevice->createInputLayout( &inputElements[0], SLANG_COUNT_OF(inputElements)); if(!inputLayout) return SLANG_FAIL; @@ -388,14 +395,14 @@ Result initialize() IBufferResource::Desc vertexBufferDesc; vertexBufferDesc.init(FullScreenTriangle::kVertexCount * sizeof(FullScreenTriangle::Vertex)); vertexBufferDesc.setDefaults(IResource::Usage::VertexBuffer); - gVertexBuffer = gRenderer->createBufferResource( + gVertexBuffer = gDevice->createBufferResource( IResource::Usage::VertexBuffer, vertexBufferDesc, &FullScreenTriangle::kVertices[0]); if(!gVertexBuffer) return SLANG_FAIL; ComPtr<IShaderProgram> shaderProgram; - SLANG_RETURN_ON_FAIL(loadShaderProgram(gRenderer, shaderProgram)); + SLANG_RETURN_ON_FAIL(loadShaderProgram(gDevice, shaderProgram)); IDescriptorSetLayout::SlotRangeDesc slotRanges[] = { @@ -404,7 +411,7 @@ Result initialize() IDescriptorSetLayout::Desc descriptorSetLayoutDesc; descriptorSetLayoutDesc.slotRangeCount = 1; descriptorSetLayoutDesc.slotRanges = &slotRanges[0]; - auto descriptorSetLayout = gRenderer->createDescriptorSetLayout(descriptorSetLayoutDesc); + auto descriptorSetLayout = gDevice->createDescriptorSetLayout(descriptorSetLayoutDesc); if(!descriptorSetLayout) return SLANG_FAIL; IPipelineLayout::DescriptorSetDesc descriptorSets[] = @@ -415,12 +422,13 @@ Result initialize() pipelineLayoutDesc.renderTargetCount = 1; pipelineLayoutDesc.descriptorSetCount = 1; pipelineLayoutDesc.descriptorSets = &descriptorSets[0]; - auto pipelineLayout = gRenderer->createPipelineLayout(pipelineLayoutDesc); + auto pipelineLayout = gDevice->createPipelineLayout(pipelineLayoutDesc); if(!pipelineLayout) return SLANG_FAIL; gPipelineLayout = pipelineLayout; - auto descriptorSet = gRenderer->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); + auto descriptorSet = + gDevice->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); if(!descriptorSet) return SLANG_FAIL; descriptorSet->setConstantBuffer(0, 0, gConstantBuffer); @@ -436,7 +444,7 @@ Result initialize() swapchainDesc.queue = gQueue; gfx::WindowHandle windowHandle; memcpy(&windowHandle, &gWindow->getNativeHandle(), sizeof(windowHandle)); - gSwapchain = gRenderer->createSwapchain(swapchainDesc, windowHandle); + gSwapchain = gDevice->createSwapchain(swapchainDesc, windowHandle); IFramebufferLayout::AttachmentLayout renderTargetLayout = {gSwapchain->getDesc().format, 1}; IFramebufferLayout::AttachmentLayout depthLayout = {gfx::Format::D_Float32, 1}; @@ -444,58 +452,18 @@ Result initialize() framebufferLayoutDesc.renderTargetCount = 1; framebufferLayoutDesc.renderTargets = &renderTargetLayout; framebufferLayoutDesc.depthStencil = &depthLayout; - ComPtr<IFramebufferLayout> framebufferLayout; SLANG_RETURN_ON_FAIL( - gRenderer->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef())); - - for (uint32_t i = 0; i < kSwapchainImageCount; i++) - { - gfx::ITextureResource::Desc depthBufferDesc; - depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); - depthBufferDesc.init2D( - gfx::IResource::Type::Texture2D, - gfx::Format::D_Float32, - gSwapchain->getDesc().width, - gSwapchain->getDesc().height, - 0); - - ComPtr<gfx::ITextureResource> depthBufferResource = gRenderer->createTextureResource( - gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); - ComPtr<gfx::ITextureResource> colorBuffer; - gSwapchain->getImage(i, colorBuffer.writeRef()); + gDevice->createFramebufferLayout(framebufferLayoutDesc, gFramebufferLayout.writeRef())); - gfx::IResourceView::Desc colorBufferViewDesc; - memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); - colorBufferViewDesc.format = gSwapchain->getDesc().format; - colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; - colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget; - ComPtr<gfx::IResourceView> rtv = - gRenderer->createTextureView(colorBuffer.get(), colorBufferViewDesc); - - gfx::IResourceView::Desc depthBufferViewDesc; - memset(&depthBufferViewDesc, 0, sizeof(depthBufferViewDesc)); - depthBufferViewDesc.format = gfx::Format::D_Float32; - depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; - depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil; - ComPtr<gfx::IResourceView> dsv = - gRenderer->createTextureView(depthBufferResource.get(), depthBufferViewDesc); - - gfx::IFramebuffer::Desc framebufferDesc; - framebufferDesc.renderTargetCount = 1; - framebufferDesc.depthStencilView = dsv.get(); - framebufferDesc.renderTargetViews = rtv.readRef(); - framebufferDesc.layout = framebufferLayout; - ComPtr<gfx::IFramebuffer> frameBuffer = gRenderer->createFramebuffer(framebufferDesc); - gFramebuffers.add(frameBuffer); - } + createSwapchainFramebuffers(); // Create pipeline. GraphicsPipelineStateDesc desc; desc.inputLayout = inputLayout; desc.program = shaderProgram; - desc.framebufferLayout = framebufferLayout; + desc.framebufferLayout = gFramebufferLayout; desc.pipelineLayout = pipelineLayout; - auto pipelineState = gRenderer->createGraphicsPipelineState(desc); + auto pipelineState = gDevice->createGraphicsPipelineState(desc); if (!pipelineState) return SLANG_FAIL; @@ -503,7 +471,7 @@ Result initialize() // Create render pass. gfx::IRenderPassLayout::Desc renderPassDesc = {}; - renderPassDesc.framebufferLayout = framebufferLayout; + renderPassDesc.framebufferLayout = gFramebufferLayout; renderPassDesc.renderTargetCount = 1; IRenderPassLayout::AttachmentAccessDesc renderTargetAccess = {}; IRenderPassLayout::AttachmentAccessDesc depthStencilAccess = {}; @@ -517,7 +485,7 @@ Result initialize() depthStencilAccess.finalState = ResourceState::DepthWrite; renderPassDesc.renderTargetAccess = &renderTargetAccess; renderPassDesc.depthStencilAccess = &depthStencilAccess; - gRenderPass = gRenderer->createRenderPassLayout(renderPassDesc); + gRenderPass = gDevice->createRenderPassLayout(renderPassDesc); return SLANG_OK; } @@ -534,6 +502,9 @@ platform::TimePoint startTime; void renderFrame() { auto frameIndex = gSwapchain->acquireNextImage(); + if (frameIndex == -1) + return; + auto commandBuffer = gQueue->createCommandBuffer(); if( firstTime ) { @@ -599,6 +570,73 @@ void handleEvent(const platform::MouseEventArgs& event) lastMouseY = (float)event.y; } +void createSwapchainFramebuffers() +{ + gFramebuffers.clear(); + for (uint32_t i = 0; i < kSwapchainImageCount; i++) + { + gfx::ITextureResource::Desc depthBufferDesc; + depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); + depthBufferDesc.init2D( + gfx::IResource::Type::Texture2D, + gfx::Format::D_Float32, + gSwapchain->getDesc().width, + gSwapchain->getDesc().height, + 0); + + ComPtr<gfx::ITextureResource> depthBufferResource = gDevice->createTextureResource( + gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); + ComPtr<gfx::ITextureResource> colorBuffer; + gSwapchain->getImage(i, colorBuffer.writeRef()); + + gfx::IResourceView::Desc colorBufferViewDesc; + memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); + colorBufferViewDesc.format = gSwapchain->getDesc().format; + colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; + colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget; + ComPtr<gfx::IResourceView> rtv = + gDevice->createTextureView(colorBuffer.get(), colorBufferViewDesc); + + gfx::IResourceView::Desc depthBufferViewDesc; + memset(&depthBufferViewDesc, 0, sizeof(depthBufferViewDesc)); + depthBufferViewDesc.format = gfx::Format::D_Float32; + depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; + depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil; + ComPtr<gfx::IResourceView> dsv = + gDevice->createTextureView(depthBufferResource.get(), depthBufferViewDesc); + + gfx::IFramebuffer::Desc framebufferDesc; + framebufferDesc.renderTargetCount = 1; + framebufferDesc.depthStencilView = dsv.get(); + framebufferDesc.renderTargetViews = rtv.readRef(); + framebufferDesc.layout = gFramebufferLayout; + ComPtr<gfx::IFramebuffer> frameBuffer = gDevice->createFramebuffer(framebufferDesc); + gFramebuffers.add(frameBuffer); + } +} + +void windowSizeChanged() +{ + // Wait for the GPU to finish. + gQueue->wait(); + + auto clientRect = gWindow->getClientRect(); + if (clientRect.width > 0 && clientRect.height > 0) + { + // Free all framebuffers before resizing swapchain. + gFramebuffers = decltype(gFramebuffers)(); + + // Resize swapchain. + if (gSwapchain->resize(clientRect.width, clientRect.height) == SLANG_OK) + { + // Recreate framebuffers for each swapchain back buffer image. + createSwapchainFramebuffers(); + gWindowWidth = clientRect.width; + gWindowHeight = clientRect.height; + } + } +} + }; int innerMain() diff --git a/slang-gfx.h b/slang-gfx.h index bc89fbd5c..7e486734a 100644 --- a/slang-gfx.h +++ b/slang-gfx.h @@ -76,9 +76,10 @@ enum class StageType CountOf, }; -enum class RendererType +enum class DeviceType { Unknown, + Default, DirectX11, DirectX12, OpenGl, @@ -1427,16 +1428,47 @@ public: bool enableVSync; }; virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() = 0; - virtual SLANG_NO_THROW Result getImage(uint32_t index, ITextureResource** outResource) = 0; - virtual SLANG_NO_THROW Result present() = 0; - virtual SLANG_NO_THROW uint32_t acquireNextImage() = 0; + + /// Returns the back buffer image at `index`. + virtual SLANG_NO_THROW Result SLANG_MCALL + getImage(uint32_t index, ITextureResource** outResource) = 0; + + /// Present the next image in the swapchain. + virtual SLANG_NO_THROW Result SLANG_MCALL present() = 0; + + /// Returns the index of next back buffer image that will be presented in the next + /// `present` call. If the swapchain is invalid/out-of-date, this method returns -1. + virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() = 0; + + /// Resizes the back buffers of this swapchain. All render target views and framebuffers + /// referencing the back buffer images must be freed before calling this method. + virtual SLANG_NO_THROW Result SLANG_MCALL resize(uint32_t width, uint32_t height) = 0; }; #define SLANG_UUID_ISwapchain \ { \ 0xbe91ba6c, 0x784, 0x4308, { 0xa1, 0x0, 0x19, 0xc3, 0x66, 0x83, 0x44, 0xb2 } \ } -class IRenderer: public ISlangUnknown +struct DeviceInfo +{ + DeviceType deviceType; + + BindingStyle bindingStyle; + + ProjectionStyle projectionStyle; + + /// An projection matrix that ensures x, y mapping to pixels + /// is the same on all targets + float identityProjectionMatrix[16]; + + /// The name of the graphics API being used by this device. + const char* apiName = nullptr; + + /// The name of the graphics adapter. + const char* adapterName = nullptr; +}; + +class IDevice: public ISlangUnknown { public: struct SlangDesc @@ -1458,7 +1490,7 @@ public: struct Desc { - RendererType rendererType; // The underlying API/Platform of the renderer. + DeviceType deviceType = DeviceType::Default; // The underlying API/Platform of the device. const char* adapter = nullptr; // Name to identify the adapter to use int requiredFeatureCount = 0; // Number of required features. const char** requiredFeatures = nullptr; // Array of required feature names, whose size is `requiredFeatureCount`. @@ -1695,7 +1727,7 @@ public: ISlangBlob** outBlob) = 0; /// Get the type of this renderer - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const = 0; + virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const = 0; }; #define SLANG_UUID_IRenderer \ @@ -1710,22 +1742,11 @@ extern "C" /// Gets the size in bytes of a Format type. Returns 0 if a size is not defined/invalid SLANG_GFX_API size_t SLANG_MCALL gfxGetFormatSize(Format format); - /// Gets the binding style from the type - SLANG_GFX_API BindingStyle SLANG_MCALL gfxGetBindingStyle(RendererType type); - - /// Given a renderer type, gets a projection style - SLANG_GFX_API ProjectionStyle SLANG_MCALL gfxGetProjectionStyle(RendererType type); - - /// Given the projection style returns an 'identity' matrix, which ensures x,y mapping to pixels - /// is the same on all targets - SLANG_GFX_API void SLANG_MCALL - gfxGetIdentityProjection(ProjectionStyle style, float projMatrix[16]); - - /// Get the name of the renderer - SLANG_GFX_API const char* SLANG_MCALL gfxGetRendererName(RendererType type); - /// Given a type returns a function that can construct it, or nullptr if there isn't one - SLANG_GFX_API SlangResult SLANG_MCALL gfxCreateRenderer(const IRenderer::Desc* desc, IRenderer** outRenderer); + SLANG_GFX_API SlangResult SLANG_MCALL + gfxCreateDevice(const IDevice::Desc* desc, IDevice** outDevice); + + SLANG_GFX_API const char* SLANG_MCALL gfxGetDeviceTypeName(DeviceType type); } }// renderer_test 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); }; |
