summaryrefslogtreecommitdiffstats
path: root/tools/gfx/render-d3d11.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-09-13 15:59:15 -0400
committerGitHub <noreply@github.com>2019-09-13 15:59:15 -0400
commitc2e5d2468ad6a38cdb8a067da0678302f6cc6066 (patch)
tree97c448d28e54068d84c422e9f172996b7a95f1ed /tools/gfx/render-d3d11.cpp
parent0b6321b3f08c48e37e6b8256d420f05d9727fb5a (diff)
Refactor render-test to make cross platform (#1053)
* First pass of render-test refactor. * Make window construction a function that can choose an implementation. * Remove OpenGL as currently has windows dependency. * Disable Vulkan as Renderer impl has dependency on windows. * Pass Window in as parameter of 'update'. * Add win-window.cpp as was missing. * Fix warning on windows about signs during comparison.
Diffstat (limited to 'tools/gfx/render-d3d11.cpp')
-rw-r--r--tools/gfx/render-d3d11.cpp2371
1 files changed, 0 insertions, 2371 deletions
diff --git a/tools/gfx/render-d3d11.cpp b/tools/gfx/render-d3d11.cpp
deleted file mode 100644
index 5911d6e9c..000000000
--- a/tools/gfx/render-d3d11.cpp
+++ /dev/null
@@ -1,2371 +0,0 @@
-// render-d3d11.cpp
-
-#define _CRT_SECURE_NO_WARNINGS
-
-#include "render-d3d11.h"
-
-//WORKING: #include "options.h"
-#include "render.h"
-#include "d3d-util.h"
-
-#include "surface.h"
-
-// In order to use the Slang API, we need to include its header
-
-//#include <slang.h>
-
-#include "../../slang-com-ptr.h"
-#include "flag-combiner.h"
-
-// We will be rendering with Direct3D 11, so we need to include
-// the Windows and D3D11 headers
-
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-#include <Windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#undef NOMINMAX
-
-#include <d3d11_2.h>
-#include <d3dcompiler.h>
-
-// We will use the C standard library just for printing error messages.
-#include <stdio.h>
-
-#ifdef _MSC_VER
-#include <stddef.h>
-#if (_MSC_VER < 1900)
-#define snprintf sprintf_s
-#endif
-#endif
-//
-using namespace Slang;
-
-namespace gfx {
-
-class D3D11Renderer : public Renderer
-{
-public:
- enum
- {
- kMaxUAVs = 64,
- kMaxRTVs = 8,
- };
-
- // Renderer implementation
- virtual SlangResult initialize(const Desc& desc, void* inWindowHandle) override;
- virtual const List<String>& getFeatures() override { return m_features; }
- virtual void setClearColor(const float color[4]) override;
- virtual void clearFrame() override;
- virtual void presentFrame() override;
- TextureResource::Desc getSwapChainTextureDesc() override;
-
- Result createTextureResource(Resource::Usage initialUsage, const TextureResource::Desc& desc, const TextureResource::Data* initData, TextureResource** outResource) override;
- Result createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& desc, const void* initData, BufferResource** outResource) override;
- Result createSamplerState(SamplerState::Desc const& desc, SamplerState** outSampler) override;
-
- Result createTextureView(TextureResource* texture, ResourceView::Desc const& desc, ResourceView** outView) override;
- Result createBufferView(BufferResource* buffer, ResourceView::Desc const& desc, ResourceView** outView) override;
-
- Result createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount, InputLayout** outLayout) override;
-
- Result createDescriptorSetLayout(const DescriptorSetLayout::Desc& desc, DescriptorSetLayout** outLayout) override;
- Result createPipelineLayout(const PipelineLayout::Desc& desc, PipelineLayout** outLayout) override;
- Result createDescriptorSet(DescriptorSetLayout* layout, DescriptorSet** outDescriptorSet) override;
-
- Result createProgram(const ShaderProgram::Desc& desc, ShaderProgram** outProgram) override;
- Result createGraphicsPipelineState(const GraphicsPipelineStateDesc& desc, PipelineState** outState) override;
- Result createComputePipelineState(const ComputePipelineStateDesc& desc, PipelineState** outState) override;
-
- virtual SlangResult captureScreenSurface(Surface& surfaceOut) override;
-
- virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
- virtual void unmap(BufferResource* buffer) override;
- virtual void setPrimitiveTopology(PrimitiveTopology topology) override;
-
- virtual void setDescriptorSet(PipelineType pipelineType, PipelineLayout* layout, UInt index, DescriptorSet* descriptorSet) override;
-
- virtual void setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* strides, const UInt* offsets) override;
- virtual void setIndexBuffer(BufferResource* buffer, Format indexFormat, UInt offset) override;
- virtual void setDepthStencilTarget(ResourceView* depthStencilView) override;
- void setViewports(UInt count, Viewport const* viewports) override;
- void setScissorRects(UInt count, ScissorRect const* rects) override;
- virtual void setPipelineState(PipelineType pipelineType, PipelineState* state) override;
- virtual void draw(UInt vertexCount, UInt startVertex) override;
- virtual void drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) override;
- virtual void dispatchCompute(int x, int y, int z) override;
- virtual void submitGpuWork() override {}
- virtual void waitForGpu() override {}
- virtual RendererType getRendererType() const override { return RendererType::DirectX11; }
-
- ~D3D11Renderer() {}
-
- protected:
-
-#if 0
- struct BindingDetail
- {
- ComPtr<ID3D11ShaderResourceView> m_srv;
- ComPtr<ID3D11UnorderedAccessView> m_uav;
- ComPtr<ID3D11SamplerState> m_samplerState;
- };
-
- class BindingStateImpl: public BindingState
- {
- public:
- typedef BindingState Parent;
-
- /// Ctor
- BindingStateImpl(const Desc& desc):
- Parent(desc)
- {}
-
- List<BindingDetail> m_bindingDetails;
- };
-#endif
-
- enum class D3D11DescriptorSlotType
- {
- ConstantBuffer,
- ShaderResourceView,
- UnorderedAccessView,
- Sampler,
-
- CombinedTextureSampler,
-
- CountOf,
- };
-
- class DescriptorSetLayoutImpl : public DescriptorSetLayout
- {
- public:
- struct RangeInfo
- {
- D3D11DescriptorSlotType type;
- UInt arrayIndex;
- UInt pairedSamplerArrayIndex;
- };
- List<RangeInfo> m_ranges;
-
- UInt m_counts[int(D3D11DescriptorSlotType::CountOf)];
- };
-
- class PipelineLayoutImpl : public PipelineLayout
- {
- public:
- struct DescriptorSetInfo
- {
- RefPtr<DescriptorSetLayoutImpl> layout;
- UInt baseIndices[int(D3D11DescriptorSlotType::CountOf)];
- };
-
- List<DescriptorSetInfo> m_descriptorSets;
- UINT m_uavCount;
- };
-
- class DescriptorSetImpl : public DescriptorSet
- {
- public:
- virtual void setConstantBuffer(UInt range, UInt index, BufferResource* buffer) override;
- virtual void setResource(UInt range, UInt index, ResourceView* view) override;
- virtual void setSampler(UInt range, UInt index, SamplerState* sampler) override;
- virtual void setCombinedTextureSampler(
- UInt range,
- UInt index,
- ResourceView* textureView,
- SamplerState* sampler) override;
-
- RefPtr<DescriptorSetLayoutImpl> m_layout;
-
- List<ComPtr<ID3D11Buffer>> m_cbs;
- List<ComPtr<ID3D11ShaderResourceView>> m_srvs;
- List<ComPtr<ID3D11UnorderedAccessView>> m_uavs;
- List<ComPtr<ID3D11SamplerState>> m_samplers;
- };
-
- class ShaderProgramImpl: public ShaderProgram
- {
- public:
- ComPtr<ID3D11VertexShader> m_vertexShader;
- ComPtr<ID3D11PixelShader> m_pixelShader;
- ComPtr<ID3D11ComputeShader> m_computeShader;
- };
-
- class BufferResourceImpl: public BufferResource
- {
- public:
- typedef BufferResource Parent;
-
- BufferResourceImpl(const Desc& desc, Usage initialUsage):
- Parent(desc),
- m_initialUsage(initialUsage)
- {
- }
-
- MapFlavor m_mapFlavor;
- Usage m_initialUsage;
- ComPtr<ID3D11Buffer> m_buffer;
- ComPtr<ID3D11Buffer> m_staging;
- };
- class TextureResourceImpl : public TextureResource
- {
- public:
- typedef TextureResource Parent;
-
- TextureResourceImpl(const Desc& desc, Usage initialUsage) :
- Parent(desc),
- m_initialUsage(initialUsage)
- {
- }
- Usage m_initialUsage;
- ComPtr<ID3D11Resource> m_resource;
-
- };
-
- class SamplerStateImpl : public SamplerState
- {
- public:
- ComPtr<ID3D11SamplerState> m_sampler;
- };
-
-
- class ResourceViewImpl : public ResourceView
- {
- public:
- enum class Type
- {
- SRV,
- UAV,
- DSV,
- RTV,
- };
- Type m_type;
- };
-
- class ShaderResourceViewImpl : public ResourceViewImpl
- {
- public:
- ComPtr<ID3D11ShaderResourceView> m_srv;
- };
-
- class UnorderedAccessViewImpl : public ResourceViewImpl
- {
- public:
- ComPtr<ID3D11UnorderedAccessView> m_uav;
- };
-
- class DepthStencilViewImpl : public ResourceViewImpl
- {
- public:
- ComPtr<ID3D11DepthStencilView> m_dsv;
- };
-
- class RenderTargetViewImpl : public ResourceViewImpl
- {
- public:
- ComPtr<ID3D11RenderTargetView> m_rtv;
- };
-
- class InputLayoutImpl: public InputLayout
- {
- public:
- ComPtr<ID3D11InputLayout> m_layout;
- };
-
- class PipelineStateImpl : public PipelineState
- {
- public:
- RefPtr<ShaderProgramImpl> m_program;
- RefPtr<PipelineLayoutImpl> m_pipelineLayout;
- };
-
-
- class GraphicsPipelineStateImpl : public PipelineStateImpl
- {
- public:
- UINT m_rtvCount;
-
- RefPtr<InputLayoutImpl> m_inputLayout;
- ComPtr<ID3D11DepthStencilState> m_depthStencilState;
- ComPtr<ID3D11RasterizerState> m_rasterizerState;
- ComPtr<ID3D11BlendState> m_blendState;
-
- UINT m_stencilRef;
- float m_blendColor[4];
- UINT m_sampleMask;
- };
-
- class ComputePipelineStateImpl : public PipelineStateImpl
- {
- public:
- };
-
- /// Capture a texture to a file
- static HRESULT captureTextureToSurface(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, Surface& surfaceOut);
-
- void _flushGraphicsState();
- void _flushComputeState();
-
- ComPtr<IDXGISwapChain> m_swapChain;
- ComPtr<ID3D11Device> m_device;
- ComPtr<ID3D11DeviceContext> m_immediateContext;
- ComPtr<ID3D11Texture2D> m_backBufferTexture;
-
- RefPtr<TextureResourceImpl> m_primaryRenderTargetTexture;
- RefPtr<RenderTargetViewImpl> m_primaryRenderTargetView;
-
-// List<ComPtr<ID3D11RenderTargetView> > m_renderTargetViews;
-// List<ComPtr<ID3D11Texture2D> > m_renderTargetTextures;
-
- bool m_renderTargetBindingsDirty = false;
-
- RefPtr<GraphicsPipelineStateImpl> m_currentGraphicsState;
- RefPtr<ComputePipelineStateImpl> m_currentComputeState;
-
- ComPtr<ID3D11RenderTargetView> m_rtvBindings[kMaxRTVs];
- ComPtr<ID3D11DepthStencilView> m_dsvBinding;
- ComPtr<ID3D11UnorderedAccessView> m_uavBindings[int(PipelineType::CountOf)][kMaxUAVs];
- bool m_targetBindingsDirty[int(PipelineType::CountOf)];
-
- Desc m_desc;
-
- float m_clearColor[4] = { 0, 0, 0, 0 };
-
- List<String> m_features;
-};
-
-Renderer* createD3D11Renderer()
-{
- return new D3D11Renderer();
-}
-
-/* static */HRESULT D3D11Renderer::captureTextureToSurface(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, Surface& surfaceOut)
-{
- if (!context) return E_INVALIDARG;
- if (!texture) return E_INVALIDARG;
-
- D3D11_TEXTURE2D_DESC textureDesc;
- texture->GetDesc(&textureDesc);
-
- // Don't bother supporting MSAA for right now
- if (textureDesc.SampleDesc.Count > 1)
- {
- fprintf(stderr, "ERROR: cannot capture multi-sample texture\n");
- return E_INVALIDARG;
- }
-
- HRESULT hr = S_OK;
- ComPtr<ID3D11Texture2D> stagingTexture;
-
- if (textureDesc.Usage == D3D11_USAGE_STAGING && (textureDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ))
- {
- stagingTexture = texture;
- }
- else
- {
- // Modify the descriptor to give us a staging texture
- textureDesc.BindFlags = 0;
- textureDesc.MiscFlags &= ~D3D11_RESOURCE_MISC_TEXTURECUBE;
- textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- textureDesc.Usage = D3D11_USAGE_STAGING;
-
- hr = device->CreateTexture2D(&textureDesc, 0, stagingTexture.writeRef());
- if (FAILED(hr))
- {
- fprintf(stderr, "ERROR: failed to create staging texture\n");
- return hr;
- }
-
- context->CopyResource(stagingTexture, texture);
- }
-
- // Now just read back texels from the staging textures
- {
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- SLANG_RETURN_ON_FAIL(context->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mappedResource));
-
- Result res = surfaceOut.set(textureDesc.Width, textureDesc.Height, Format::RGBA_Unorm_UInt8, mappedResource.RowPitch, mappedResource.pData, SurfaceAllocator::getMallocAllocator());
-
- // Make sure to unmap
- context->Unmap(stagingTexture, 0);
- return res;
- }
-}
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle)
-{
- auto windowHandle = (HWND)inWindowHandle;
- m_desc = desc;
-
- // Rather than statically link against D3D, we load it dynamically.
- HMODULE d3dModule = LoadLibraryA("d3d11.dll");
- if (!d3dModule)
- {
- fprintf(stderr, "error: failed load 'd3d11.dll'\n");
- return SLANG_FAIL;
- }
-
- PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN D3D11CreateDeviceAndSwapChain_ =
- (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(d3dModule, "D3D11CreateDeviceAndSwapChain");
- if (!D3D11CreateDeviceAndSwapChain_)
- {
- fprintf(stderr,
- "error: failed load symbol 'D3D11CreateDeviceAndSwapChain'\n");
- return SLANG_FAIL;
- }
-
- // Our swap chain uses RGBA8 with sRGB, with double buffering.
- DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-
- // Note(tfoley): Disabling sRGB for DX back buffer for now, so that we
- // can get consistent output with OpenGL, where setting up sRGB will
- // probably be more involved.
- // swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
- swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
-
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferCount = 2;
- swapChainDesc.OutputWindow = windowHandle;
- swapChainDesc.Windowed = TRUE;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
- swapChainDesc.Flags = 0;
-
- // We will ask for the highest feature level that can be supported.
- const D3D_FEATURE_LEVEL featureLevels[] = {
- D3D_FEATURE_LEVEL_11_1,
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1,
- };
- D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_9_1;
- const int totalNumFeatureLevels = SLANG_COUNT_OF(featureLevels);
-
- {
- // On a machine that does not have an up-to-date version of D3D installed,
- // the `D3D11CreateDeviceAndSwapChain` call will fail with `E_INVALIDARG`
- // if you ask for feature level 11_1 (DeviceCheckFlag::UseFullFeatureLevel).
- // The workaround is to call `D3D11CreateDeviceAndSwapChain` the first time
- // with 11_1 and then back off to 11_0 if that fails.
-
- FlagCombiner combiner;
- // TODO: we should probably provide a command-line option
- // to override UseDebug of default rather than leave it
- // up to each back-end to specify.
-
-#if _DEBUG
- combiner.add(DeviceCheckFlag::UseDebug, ChangeType::OnOff); ///< First try debug then non debug
-#else
- combiner.add(DeviceCheckFlag::UseDebug, ChangeType::Off); ///< Don't bother with debug
-#endif
- combiner.add(DeviceCheckFlag::UseHardwareDevice, ChangeType::OnOff); ///< First try hardware, then reference
- combiner.add(DeviceCheckFlag::UseFullFeatureLevel, ChangeType::OnOff); ///< First try fully featured, then degrade features
-
- const int numCombinations = combiner.getNumCombinations();
- Result res = SLANG_FAIL;
- for (int i = 0; i < numCombinations; ++i)
- {
- const auto deviceCheckFlags = combiner.getCombination(i);
-
- // If we have an adapter set on the desc, look it up. We only need to do so for hardware
- ComPtr<IDXGIAdapter> adapter;
- if (desc.adapter.getLength() && (deviceCheckFlags & DeviceCheckFlag::UseHardwareDevice))
- {
- List<ComPtr<IDXGIAdapter>> dxgiAdapters;
- D3DUtil::findAdapters(deviceCheckFlags, desc.adapter.getUnownedSlice(), dxgiAdapters);
- if (dxgiAdapters.getCount() == 0)
- {
- continue;
- }
- adapter = dxgiAdapters[0];
- }
-
- // The adapter can be nullptr - that just means 'default', but when so we need to select the driver type
- D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN;
- if (adapter == nullptr)
- {
- // If we don't have an adapter, select directly
- driverType = (deviceCheckFlags & DeviceCheckFlag::UseHardwareDevice) ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_REFERENCE;
- }
-
- const int startFeatureIndex = (deviceCheckFlags & DeviceCheckFlag::UseFullFeatureLevel) ? 0 : 1;
- const UINT deviceFlags = (deviceCheckFlags & DeviceCheckFlag::UseDebug) ? D3D11_CREATE_DEVICE_DEBUG : 0;
-
- res = D3D11CreateDeviceAndSwapChain_(
- adapter,
- driverType,
- nullptr, // software
- deviceFlags,
- &featureLevels[startFeatureIndex],
- totalNumFeatureLevels - startFeatureIndex,
- D3D11_SDK_VERSION,
- &swapChainDesc,
- m_swapChain.writeRef(),
- m_device.writeRef(),
- &featureLevel,
- m_immediateContext.writeRef());
-
- // Check if successfully constructed - if so we are done.
- if (SLANG_SUCCEEDED(res))
- {
- break;
- }
- }
- // If res is failure, means all styles have have failed, and so initialization fails.
- if (SLANG_FAILED(res))
- {
- return res;
- }
- // Check we have a swap chain, context and device
- SLANG_ASSERT(m_immediateContext && m_swapChain && m_device);
- }
-
- // TODO: Add support for debugging to help detect leaks:
- //
- // ComPtr<ID3D11Debug> gDebug;
- // m_device->QueryInterface(IID_PPV_ARGS(gDebug.writeRef()));
- //
-
- // After we've created the swap chain, we can request a pointer to the
- // back buffer as a D3D11 texture, and create a render-target view from it.
-
- static const IID kIID_ID3D11Texture2D = {
- 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48,
- 0x95, 0x35, 0xd3, 0x4f, 0x9c };
-
- SLANG_RETURN_ON_FAIL(m_swapChain->GetBuffer(0, kIID_ID3D11Texture2D, (void**)m_backBufferTexture.writeRef()));
-
-// for (int i = 0; i < 8; i++)
- {
- ComPtr<ID3D11Texture2D> texture;
- D3D11_TEXTURE2D_DESC textureDesc;
- m_backBufferTexture->GetDesc(&textureDesc);
- SLANG_RETURN_ON_FAIL(m_device->CreateTexture2D(&textureDesc, nullptr, texture.writeRef()));
-
- ComPtr<ID3D11RenderTargetView> rtv;
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- rtvDesc.Texture2D.MipSlice = 0;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- SLANG_RETURN_ON_FAIL(m_device->CreateRenderTargetView(texture, &rtvDesc, rtv.writeRef()));
-
- TextureResource::Desc resourceDesc;
- resourceDesc.init2D(Resource::Type::Texture2D, Format::RGBA_Unorm_UInt8, textureDesc.Width, textureDesc.Height, 1);
-
- RefPtr<TextureResource> primaryRenderTargetTexture;
- SLANG_RETURN_ON_FAIL(createTextureResource(Resource::Usage::RenderTarget, resourceDesc, nullptr, primaryRenderTargetTexture.writeRef()));
-
- ResourceView::Desc viewDesc;
- viewDesc.format = resourceDesc.format;
- viewDesc.type = ResourceView::Type::RenderTarget;
- RefPtr<ResourceView> primaryRenderTargetView;
- SLANG_RETURN_ON_FAIL(createTextureView(primaryRenderTargetTexture, viewDesc, primaryRenderTargetView.writeRef()));
-
- m_primaryRenderTargetTexture = (TextureResourceImpl*) primaryRenderTargetTexture.Ptr();
- m_primaryRenderTargetView = (RenderTargetViewImpl*) primaryRenderTargetView.Ptr();
- }
-
-// m_immediateContext->OMSetRenderTargets(1, m_primaryRenderTargetView->m_rtv.readRef(), nullptr);
- m_rtvBindings[0] = m_primaryRenderTargetView->m_rtv;
- m_targetBindingsDirty[int(PipelineType::Graphics)] = true;
-
- // Similarly, we are going to set up a viewport once, and then never
- // switch, since this is a simple test app.
- D3D11_VIEWPORT viewport;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
- viewport.Width = (float)desc.width;
- viewport.Height = (float)desc.height;
- viewport.MaxDepth = 1; // TODO(tfoley): use reversed depth
- viewport.MinDepth = 0;
- m_immediateContext->RSSetViewports(1, &viewport);
-
- return SLANG_OK;
-}
-
-void D3D11Renderer::setClearColor(const float color[4])
-{
- memcpy(m_clearColor, color, sizeof(m_clearColor));
-}
-
-void D3D11Renderer::clearFrame()
-{
- m_immediateContext->ClearRenderTargetView(m_primaryRenderTargetView->m_rtv, m_clearColor);
-
- if(m_dsvBinding)
- {
- m_immediateContext->ClearDepthStencilView(m_dsvBinding, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
- }
-}
-
-void D3D11Renderer::presentFrame()
-{
- m_immediateContext->CopyResource(m_backBufferTexture, m_primaryRenderTargetTexture->m_resource);
- m_swapChain->Present(0, 0);
-}
-
-TextureResource::Desc D3D11Renderer::getSwapChainTextureDesc()
-{
- D3D11_TEXTURE2D_DESC dxDesc;
- ((ID3D11Texture2D*)m_primaryRenderTargetTexture->m_resource.get())->GetDesc(&dxDesc);
-
- TextureResource::Desc desc;
- desc.init2D(Resource::Type::Texture2D, Format::Unknown, dxDesc.Width, dxDesc.Height, 1);
-
- return desc;
-}
-
-SlangResult D3D11Renderer::captureScreenSurface(Surface& surfaceOut)
-{
- return captureTextureToSurface(m_device, m_immediateContext, (ID3D11Texture2D*) m_primaryRenderTargetTexture->m_resource.get(), surfaceOut);
-}
-
-static D3D11_BIND_FLAG _calcResourceFlag(Resource::BindFlag::Enum bindFlag)
-{
- typedef Resource::BindFlag BindFlag;
- switch (bindFlag)
- {
- case BindFlag::VertexBuffer: return D3D11_BIND_VERTEX_BUFFER;
- case BindFlag::IndexBuffer: return D3D11_BIND_INDEX_BUFFER;
- case BindFlag::ConstantBuffer: return D3D11_BIND_CONSTANT_BUFFER;
- case BindFlag::StreamOutput: return D3D11_BIND_STREAM_OUTPUT;
- case BindFlag::RenderTarget: return D3D11_BIND_RENDER_TARGET;
- case BindFlag::DepthStencil: return D3D11_BIND_DEPTH_STENCIL;
- case BindFlag::UnorderedAccess: return D3D11_BIND_UNORDERED_ACCESS;
- case BindFlag::PixelShaderResource: return D3D11_BIND_SHADER_RESOURCE;
- case BindFlag::NonPixelShaderResource: return D3D11_BIND_SHADER_RESOURCE;
- default: return D3D11_BIND_FLAG(0);
- }
-}
-
-static int _calcResourceBindFlags(int bindFlags)
-{
- int dstFlags = 0;
- while (bindFlags)
- {
- int lsb = bindFlags & -bindFlags;
-
- dstFlags |= _calcResourceFlag(Resource::BindFlag::Enum(lsb));
- bindFlags &= ~lsb;
- }
- return dstFlags;
-}
-
-static int _calcResourceAccessFlags(int accessFlags)
-{
- switch (accessFlags)
- {
- case 0: return 0;
- case Resource::AccessFlag::Read: return D3D11_CPU_ACCESS_READ;
- case Resource::AccessFlag::Write: return D3D11_CPU_ACCESS_WRITE;
- case Resource::AccessFlag::Read |
- Resource::AccessFlag::Write: return D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- default: assert(!"Invalid flags"); return 0;
- }
-}
-
-Result D3D11Renderer::createTextureResource(Resource::Usage initialUsage, const TextureResource::Desc& descIn, const TextureResource::Data* initData, TextureResource** outResource)
-{
- TextureResource::Desc srcDesc(descIn);
- srcDesc.setDefaults(initialUsage);
-
- const int effectiveArraySize = srcDesc.calcEffectiveArraySize();
-
- if(initData)
- {
- assert(initData->numSubResources == srcDesc.numMipLevels * effectiveArraySize * srcDesc.size.depth);
- }
-
- const DXGI_FORMAT format = D3DUtil::getMapFormat(srcDesc.format);
- if (format == DXGI_FORMAT_UNKNOWN)
- {
- return SLANG_FAIL;
- }
-
- const int bindFlags = _calcResourceBindFlags(srcDesc.bindFlags);
-
- // Set up the initialize data
- List<D3D11_SUBRESOURCE_DATA> subRes;
- D3D11_SUBRESOURCE_DATA* subResourcesPtr = nullptr;
- if(initData)
- {
- subRes.setCount(srcDesc.numMipLevels * effectiveArraySize);
- {
- int subResourceIndex = 0;
- for (int i = 0; i < effectiveArraySize; i++)
- {
- for (int j = 0; j < srcDesc.numMipLevels; j++)
- {
- const int mipHeight = TextureResource::calcMipSize(srcDesc.size.height, j);
-
- D3D11_SUBRESOURCE_DATA& data = subRes[subResourceIndex];
-
- data.pSysMem = initData->subResources[subResourceIndex];
-
- data.SysMemPitch = UINT(initData->mipRowStrides[j]);
- data.SysMemSlicePitch = UINT(initData->mipRowStrides[j] * mipHeight);
-
- subResourceIndex++;
- }
- }
- }
- subResourcesPtr = subRes.getBuffer();
- }
-
- const int accessFlags = _calcResourceAccessFlags(srcDesc.cpuAccessFlags);
-
- RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(srcDesc, initialUsage));
-
- switch (srcDesc.type)
- {
- case Resource::Type::Texture1D:
- {
- D3D11_TEXTURE1D_DESC desc = { 0 };
- desc.BindFlags = bindFlags;
- desc.CPUAccessFlags = accessFlags;
- desc.Format = format;
- desc.MiscFlags = 0;
- desc.MipLevels = srcDesc.numMipLevels;
- desc.ArraySize = effectiveArraySize;
- desc.Width = srcDesc.size.width;
- desc.Usage = D3D11_USAGE_DEFAULT;
-
- ComPtr<ID3D11Texture1D> texture1D;
- SLANG_RETURN_ON_FAIL(m_device->CreateTexture1D(&desc, subResourcesPtr, texture1D.writeRef()));
-
- texture->m_resource = texture1D;
- break;
- }
- case Resource::Type::TextureCube:
- case Resource::Type::Texture2D:
- {
- D3D11_TEXTURE2D_DESC desc = { 0 };
- desc.BindFlags = bindFlags;
- desc.CPUAccessFlags = accessFlags;
- desc.Format = format;
- desc.MiscFlags = 0;
- desc.MipLevels = srcDesc.numMipLevels;
- desc.ArraySize = effectiveArraySize;
-
- desc.Width = srcDesc.size.width;
- desc.Height = srcDesc.size.height;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.SampleDesc.Count = srcDesc.sampleDesc.numSamples;
- desc.SampleDesc.Quality = srcDesc.sampleDesc.quality;
-
- if (srcDesc.type == Resource::Type::TextureCube)
- {
- desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
- }
-
- ComPtr<ID3D11Texture2D> texture2D;
- SLANG_RETURN_ON_FAIL(m_device->CreateTexture2D(&desc, subResourcesPtr, texture2D.writeRef()));
-
- texture->m_resource = texture2D;
- break;
- }
- case Resource::Type::Texture3D:
- {
- D3D11_TEXTURE3D_DESC desc = { 0 };
- desc.BindFlags = bindFlags;
- desc.CPUAccessFlags = accessFlags;
- desc.Format = format;
- desc.MiscFlags = 0;
- desc.MipLevels = srcDesc.numMipLevels;
- desc.Width = srcDesc.size.width;
- desc.Height = srcDesc.size.height;
- desc.Depth = srcDesc.size.depth;
- desc.Usage = D3D11_USAGE_DEFAULT;
-
- ComPtr<ID3D11Texture3D> texture3D;
- SLANG_RETURN_ON_FAIL(m_device->CreateTexture3D(&desc, subResourcesPtr, texture3D.writeRef()));
-
- texture->m_resource = texture3D;
- break;
- }
- default:
- return SLANG_FAIL;
- }
-
- *outResource = texture.detach();
- return SLANG_OK;
-}
-
-Result D3D11Renderer::createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& descIn, const void* initData, BufferResource** outResource)
-{
- BufferResource::Desc srcDesc(descIn);
- srcDesc.setDefaults(initialUsage);
-
- auto d3dBindFlags = _calcResourceBindFlags(srcDesc.bindFlags);
-
- size_t alignedSizeInBytes = srcDesc.sizeInBytes;
-
- if(d3dBindFlags & D3D11_BIND_CONSTANT_BUFFER)
- {
- // Make aligned to 256 bytes... not sure why, but if you remove this the tests do fail.
- alignedSizeInBytes = D3DUtil::calcAligned(alignedSizeInBytes, 256);
- }
-
- // Hack to make the initialization never read from out of bounds memory, by copying into a buffer
- List<uint8_t> initDataBuffer;
- if (initData && alignedSizeInBytes > srcDesc.sizeInBytes)
- {
- initDataBuffer.setCount(alignedSizeInBytes);
- ::memcpy(initDataBuffer.getBuffer(), initData, srcDesc.sizeInBytes);
- initData = initDataBuffer.getBuffer();
- }
-
- D3D11_BUFFER_DESC bufferDesc = { 0 };
- bufferDesc.ByteWidth = UINT(alignedSizeInBytes);
- bufferDesc.BindFlags = d3dBindFlags;
- // For read we'll need to do some staging
- bufferDesc.CPUAccessFlags = _calcResourceAccessFlags(descIn.cpuAccessFlags & Resource::AccessFlag::Write);
- bufferDesc.Usage = D3D11_USAGE_DEFAULT;
-
- // If written by CPU, make it dynamic
- if (descIn.cpuAccessFlags & Resource::AccessFlag::Write)
- {
- bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
- }
-
- switch (initialUsage)
- {
- case Resource::Usage::ConstantBuffer:
- {
- // We'll just assume ConstantBuffers are dynamic for now
- bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
- break;
- }
- default: break;
- }
-
- if (bufferDesc.BindFlags & (D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE))
- {
- //desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
- if (srcDesc.elementSize != 0)
- {
- bufferDesc.StructureByteStride = srcDesc.elementSize;
- bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
- }
- else
- {
- bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
- }
- }
-
- D3D11_SUBRESOURCE_DATA subResourceData = { 0 };
- subResourceData.pSysMem = initData;
-
- RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(srcDesc, initialUsage));
-
- SLANG_RETURN_ON_FAIL(m_device->CreateBuffer(&bufferDesc, initData ? &subResourceData : nullptr, buffer->m_buffer.writeRef()));
-
- if (srcDesc.cpuAccessFlags & Resource::AccessFlag::Read)
- {
- D3D11_BUFFER_DESC bufDesc = {};
- bufDesc.BindFlags = 0;
- bufDesc.ByteWidth = (UINT)alignedSizeInBytes;
- bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- bufDesc.Usage = D3D11_USAGE_STAGING;
-
- SLANG_RETURN_ON_FAIL(m_device->CreateBuffer(&bufDesc, nullptr, buffer->m_staging.writeRef()));
- }
-
- *outResource = buffer.detach();
- return SLANG_OK;
-}
-
-D3D11_FILTER_TYPE translateFilterMode(TextureFilteringMode mode)
-{
- switch (mode)
- {
- default:
- return D3D11_FILTER_TYPE(0);
-
-#define CASE(SRC, DST) \
- case TextureFilteringMode::SRC: return D3D11_FILTER_TYPE_##DST
-
- CASE(Point, POINT);
- CASE(Linear, LINEAR);
-
-#undef CASE
- }
-}
-
-D3D11_FILTER_REDUCTION_TYPE translateFilterReduction(TextureReductionOp op)
-{
- switch (op)
- {
- default:
- return D3D11_FILTER_REDUCTION_TYPE(0);
-
-#define CASE(SRC, DST) \
- case TextureReductionOp::SRC: return D3D11_FILTER_REDUCTION_TYPE_##DST
-
- CASE(Average, STANDARD);
- CASE(Comparison, COMPARISON);
- CASE(Minimum, MINIMUM);
- CASE(Maximum, MAXIMUM);
-
-#undef CASE
- }
-}
-
-D3D11_TEXTURE_ADDRESS_MODE translateAddressingMode(TextureAddressingMode mode)
-{
- switch (mode)
- {
- default:
- return D3D11_TEXTURE_ADDRESS_MODE(0);
-
-#define CASE(SRC, DST) \
- case TextureAddressingMode::SRC: return D3D11_TEXTURE_ADDRESS_##DST
-
- CASE(Wrap, WRAP);
- CASE(ClampToEdge, CLAMP);
- CASE(ClampToBorder, BORDER);
- CASE(MirrorRepeat, MIRROR);
- CASE(MirrorOnce, MIRROR_ONCE);
-
-#undef CASE
- }
-}
-
-static D3D11_COMPARISON_FUNC translateComparisonFunc(ComparisonFunc func)
-{
- switch (func)
- {
- default:
- // TODO: need to report failures
- return D3D11_COMPARISON_ALWAYS;
-
-#define CASE(FROM, TO) \
- case ComparisonFunc::FROM: return D3D11_COMPARISON_##TO
-
- CASE(Never, NEVER);
- CASE(Less, LESS);
- CASE(Equal, EQUAL);
- CASE(LessEqual, LESS_EQUAL);
- CASE(Greater, GREATER);
- CASE(NotEqual, NOT_EQUAL);
- CASE(GreaterEqual, GREATER_EQUAL);
- CASE(Always, ALWAYS);
-#undef CASE
- }
-}
-
-Result D3D11Renderer::createSamplerState(SamplerState::Desc const& desc, SamplerState** outSampler)
-{
- D3D11_FILTER_REDUCTION_TYPE dxReduction = translateFilterReduction(desc.reductionOp);
- D3D11_FILTER dxFilter;
- if (desc.maxAnisotropy > 1)
- {
- dxFilter = D3D11_ENCODE_ANISOTROPIC_FILTER(dxReduction);
- }
- else
- {
- D3D11_FILTER_TYPE dxMin = translateFilterMode(desc.minFilter);
- D3D11_FILTER_TYPE dxMag = translateFilterMode(desc.magFilter);
- D3D11_FILTER_TYPE dxMip = translateFilterMode(desc.mipFilter);
-
- dxFilter = D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, dxReduction);
- }
-
- D3D11_SAMPLER_DESC dxDesc = {};
- dxDesc.Filter = dxFilter;
- dxDesc.AddressU = translateAddressingMode(desc.addressU);
- dxDesc.AddressV = translateAddressingMode(desc.addressV);
- dxDesc.AddressW = translateAddressingMode(desc.addressW);
- dxDesc.MipLODBias = desc.mipLODBias;
- dxDesc.MaxAnisotropy = desc.maxAnisotropy;
- dxDesc.ComparisonFunc = translateComparisonFunc(desc.comparisonFunc);
- for (int ii = 0; ii < 4; ++ii)
- dxDesc.BorderColor[ii] = desc.borderColor[ii];
- dxDesc.MinLOD = desc.minLOD;
- dxDesc.MaxLOD = desc.maxLOD;
-
- ComPtr<ID3D11SamplerState> sampler;
- SLANG_RETURN_ON_FAIL(m_device->CreateSamplerState(
- &dxDesc,
- sampler.writeRef()));
-
- RefPtr<SamplerStateImpl> samplerImpl = new SamplerStateImpl();
- samplerImpl->m_sampler = sampler;
- *outSampler = samplerImpl.detach();
- return SLANG_OK;
-}
-
-Result D3D11Renderer::createTextureView(TextureResource* texture, ResourceView::Desc const& desc, ResourceView** outView)
-{
- auto resourceImpl = (TextureResourceImpl*) texture;
-
- switch (desc.type)
- {
- default:
- return SLANG_FAIL;
-
- case ResourceView::Type::RenderTarget:
- {
- ComPtr<ID3D11RenderTargetView> rtv;
- SLANG_RETURN_ON_FAIL(m_device->CreateRenderTargetView(resourceImpl->m_resource, nullptr, rtv.writeRef()));
-
- RefPtr<RenderTargetViewImpl> viewImpl = new RenderTargetViewImpl();
- viewImpl->m_type = ResourceViewImpl::Type::RTV;
- viewImpl->m_rtv = rtv;
- *outView = viewImpl.detach();
- return SLANG_OK;
- }
- break;
-
- case ResourceView::Type::DepthStencil:
- {
- ComPtr<ID3D11DepthStencilView> dsv;
- SLANG_RETURN_ON_FAIL(m_device->CreateDepthStencilView(resourceImpl->m_resource, nullptr, dsv.writeRef()));
-
- RefPtr<DepthStencilViewImpl> viewImpl = new DepthStencilViewImpl();
- viewImpl->m_type = ResourceViewImpl::Type::DSV;
- viewImpl->m_dsv = dsv;
- *outView = viewImpl.detach();
- return SLANG_OK;
- }
- break;
-
- case ResourceView::Type::UnorderedAccess:
- {
- ComPtr<ID3D11UnorderedAccessView> uav;
- SLANG_RETURN_ON_FAIL(m_device->CreateUnorderedAccessView(resourceImpl->m_resource, nullptr, uav.writeRef()));
-
- RefPtr<UnorderedAccessViewImpl> viewImpl = new UnorderedAccessViewImpl();
- viewImpl->m_type = ResourceViewImpl::Type::UAV;
- viewImpl->m_uav = uav;
- *outView = viewImpl.detach();
- return SLANG_OK;
- }
- break;
-
- case ResourceView::Type::ShaderResource:
- {
- ComPtr<ID3D11ShaderResourceView> srv;
- SLANG_RETURN_ON_FAIL(m_device->CreateShaderResourceView(resourceImpl->m_resource, nullptr, srv.writeRef()));
-
- RefPtr<ShaderResourceViewImpl> viewImpl = new ShaderResourceViewImpl();
- viewImpl->m_type = ResourceViewImpl::Type::SRV;
- viewImpl->m_srv = srv;
- *outView = viewImpl.detach();
- return SLANG_OK;
- }
- break;
- }
-}
-
-Result D3D11Renderer::createBufferView(BufferResource* buffer, ResourceView::Desc const& desc, ResourceView** outView)
-{
- auto resourceImpl = (BufferResourceImpl*) buffer;
- auto resourceDesc = resourceImpl->getDesc();
-
- switch (desc.type)
- {
- default:
- return SLANG_FAIL;
-
- case ResourceView::Type::UnorderedAccess:
- {
- D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
- uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
- uavDesc.Format = D3DUtil::getMapFormat(desc.format);
- uavDesc.Buffer.FirstElement = 0;
-
- if(resourceDesc.elementSize)
- {
- uavDesc.Buffer.NumElements = UINT(resourceDesc.sizeInBytes / resourceDesc.elementSize);
- }
- else if(desc.format == Format::Unknown)
- {
- uavDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW;
- uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
- uavDesc.Buffer.NumElements = UINT(resourceDesc.sizeInBytes / 4);
- }
- else
- {
- uavDesc.Buffer.NumElements = UINT(resourceDesc.sizeInBytes / RendererUtil::getFormatSize(desc.format));
- }
-
- ComPtr<ID3D11UnorderedAccessView> uav;
- SLANG_RETURN_ON_FAIL(m_device->CreateUnorderedAccessView(resourceImpl->m_buffer, &uavDesc, uav.writeRef()));
-
- RefPtr<UnorderedAccessViewImpl> viewImpl = new UnorderedAccessViewImpl();
- viewImpl->m_type = ResourceViewImpl::Type::UAV;
- viewImpl->m_uav = uav;
- *outView = viewImpl.detach();
- return SLANG_OK;
- }
- break;
-
- case ResourceView::Type::ShaderResource:
- {
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
- srvDesc.Format = D3DUtil::getMapFormat(desc.format);
- srvDesc.Buffer.FirstElement = 0;
-
- if(resourceDesc.elementSize)
- {
- srvDesc.Buffer.NumElements = UINT(resourceDesc.sizeInBytes / resourceDesc.elementSize);
- }
- else if(desc.format == Format::Unknown)
- {
- // We need to switch to a different member of the `union`,
- // so that we can set the `BufferEx.Flags` member.
- //
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
-
- // Because we've switched, we need to re-set the `FirstElement`
- // field to be valid, since we can't count on all compilers
- // to respect that `Buffer.FirstElement` and `BufferEx.FirstElement`
- // alias in memory.
- //
- srvDesc.BufferEx.FirstElement = 0;
-
- srvDesc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW;
- srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
- srvDesc.BufferEx.NumElements = UINT(resourceDesc.sizeInBytes / 4);
- }
- else
- {
- srvDesc.Buffer.NumElements = UINT(resourceDesc.sizeInBytes / RendererUtil::getFormatSize(desc.format));
- }
-
- ComPtr<ID3D11ShaderResourceView> srv;
- SLANG_RETURN_ON_FAIL(m_device->CreateShaderResourceView(resourceImpl->m_buffer, &srvDesc, srv.writeRef()));
-
- RefPtr<ShaderResourceViewImpl> viewImpl = new ShaderResourceViewImpl();
- viewImpl->m_type = ResourceViewImpl::Type::SRV;
- viewImpl->m_srv = srv;
- *outView = viewImpl.detach();
- return SLANG_OK;
- }
- break;
- }
-}
-
-Result D3D11Renderer::createInputLayout(const InputElementDesc* inputElementsIn, UInt inputElementCount, InputLayout** outLayout)
-{
- D3D11_INPUT_ELEMENT_DESC inputElements[16] = {};
-
- char hlslBuffer[1024];
- char* hlslCursor = &hlslBuffer[0];
-
- hlslCursor += sprintf(hlslCursor, "float4 main(\n");
-
- for (UInt ii = 0; ii < inputElementCount; ++ii)
- {
- inputElements[ii].SemanticName = inputElementsIn[ii].semanticName;
- inputElements[ii].SemanticIndex = (UINT)inputElementsIn[ii].semanticIndex;
- inputElements[ii].Format = D3DUtil::getMapFormat(inputElementsIn[ii].format);
- inputElements[ii].InputSlot = 0;
- inputElements[ii].AlignedByteOffset = (UINT)inputElementsIn[ii].offset;
- inputElements[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
- inputElements[ii].InstanceDataStepRate = 0;
-
- if (ii != 0)
- {
- hlslCursor += sprintf(hlslCursor, ",\n");
- }
-
- char const* typeName = "Unknown";
- switch (inputElementsIn[ii].format)
- {
- case Format::RGBA_Float32:
- case Format::RGBA_Unorm_UInt8:
- typeName = "float4";
- break;
- case Format::RGB_Float32:
- typeName = "float3";
- break;
- case Format::RG_Float32:
- typeName = "float2";
- break;
- case Format::R_Float32:
- typeName = "float";
- break;
- default:
- return SLANG_FAIL;
- }
-
- hlslCursor += sprintf(hlslCursor, "%s a%d : %s%d",
- typeName,
- (int)ii,
- inputElementsIn[ii].semanticName,
- (int)inputElementsIn[ii].semanticIndex);
- }
-
- hlslCursor += sprintf(hlslCursor, "\n) : SV_Position { return 0; }");
-
- ComPtr<ID3DBlob> vertexShaderBlob;
- SLANG_RETURN_ON_FAIL(D3DUtil::compileHLSLShader("inputLayout", hlslBuffer, "main", "vs_5_0", vertexShaderBlob));
-
- ComPtr<ID3D11InputLayout> inputLayout;
- SLANG_RETURN_ON_FAIL(m_device->CreateInputLayout(&inputElements[0], (UINT)inputElementCount, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(),
- inputLayout.writeRef()));
-
- RefPtr<InputLayoutImpl> impl = new InputLayoutImpl;
- impl->m_layout.swap(inputLayout);
-
- *outLayout = impl.detach();
- return SLANG_OK;
-}
-
-void* D3D11Renderer::map(BufferResource* bufferIn, MapFlavor flavor)
-{
- BufferResourceImpl* bufferResource = static_cast<BufferResourceImpl*>(bufferIn);
-
- D3D11_MAP mapType;
- ID3D11Buffer* buffer = bufferResource->m_buffer;
-
- switch (flavor)
- {
- case MapFlavor::WriteDiscard:
- mapType = D3D11_MAP_WRITE_DISCARD;
- break;
- case MapFlavor::HostWrite:
- mapType = D3D11_MAP_WRITE;
- break;
- case MapFlavor::HostRead:
- mapType = D3D11_MAP_READ;
-
- buffer = bufferResource->m_staging;
- if (!buffer)
- {
- return nullptr;
- }
-
- // Okay copy the data over
- m_immediateContext->CopyResource(buffer, bufferResource->m_buffer);
-
- break;
- default:
- return nullptr;
- }
-
- // We update our constant buffer per-frame, just for the purposes
- // of the example, but we don't actually load different data
- // per-frame (we always use an identity projection).
- D3D11_MAPPED_SUBRESOURCE mappedSub;
- SLANG_RETURN_NULL_ON_FAIL(m_immediateContext->Map(buffer, 0, mapType, 0, &mappedSub));
-
- bufferResource->m_mapFlavor = flavor;
-
- return mappedSub.pData;
-}
-
-void D3D11Renderer::unmap(BufferResource* bufferIn)
-{
- BufferResourceImpl* bufferResource = static_cast<BufferResourceImpl*>(bufferIn);
- ID3D11Buffer* buffer = (bufferResource->m_mapFlavor == MapFlavor::HostRead) ? bufferResource->m_staging : bufferResource->m_buffer;
- m_immediateContext->Unmap(buffer, 0);
-}
-
-#if 0
-void D3D11Renderer::setInputLayout(InputLayout* inputLayoutIn)
-{
- auto inputLayout = static_cast<InputLayoutImpl*>(inputLayoutIn);
- m_immediateContext->IASetInputLayout(inputLayout->m_layout);
-}
-#endif
-
-void D3D11Renderer::setPrimitiveTopology(PrimitiveTopology topology)
-{
- m_immediateContext->IASetPrimitiveTopology(D3DUtil::getPrimitiveTopology(topology));
-}
-
-void D3D11Renderer::setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffersIn, const UInt* stridesIn, const UInt* offsetsIn)
-{
- static const int kMaxVertexBuffers = 16;
- assert(slotCount <= kMaxVertexBuffers);
-
- UINT vertexStrides[kMaxVertexBuffers];
- UINT vertexOffsets[kMaxVertexBuffers];
- ID3D11Buffer* dxBuffers[kMaxVertexBuffers];
-
- auto buffers = (BufferResourceImpl*const*)buffersIn;
-
- for (UInt ii = 0; ii < slotCount; ++ii)
- {
- vertexStrides[ii] = (UINT)stridesIn[ii];
- vertexOffsets[ii] = (UINT)offsetsIn[ii];
- dxBuffers[ii] = buffers[ii]->m_buffer;
- }
-
- m_immediateContext->IASetVertexBuffers((UINT)startSlot, (UINT)slotCount, dxBuffers, &vertexStrides[0], &vertexOffsets[0]);
-}
-
-void D3D11Renderer::setIndexBuffer(BufferResource* buffer, Format indexFormat, UInt offset)
-{
- DXGI_FORMAT dxFormat = D3DUtil::getMapFormat(indexFormat);
- m_immediateContext->IASetIndexBuffer(((BufferResourceImpl*)buffer)->m_buffer, dxFormat, UINT(offset));
-}
-
-void D3D11Renderer::setDepthStencilTarget(ResourceView* depthStencilView)
-{
- m_dsvBinding = ((DepthStencilViewImpl*) depthStencilView)->m_dsv;
- m_targetBindingsDirty[int(PipelineType::Graphics)] = true;
-}
-
-void D3D11Renderer::setViewports(UInt count, Viewport const* viewports)
-{
- static const int kMaxViewports = D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1;
- assert(count <= kMaxViewports);
-
- D3D11_VIEWPORT dxViewports[kMaxViewports];
- for(UInt ii = 0; ii < count; ++ii)
- {
- auto& inViewport = viewports[ii];
- auto& dxViewport = dxViewports[ii];
-
- dxViewport.TopLeftX = inViewport.originX;
- dxViewport.TopLeftY = inViewport.originY;
- dxViewport.Width = inViewport.extentX;
- dxViewport.Height = inViewport.extentY;
- dxViewport.MinDepth = inViewport.minZ;
- dxViewport.MaxDepth = inViewport.maxZ;
- }
-
- m_immediateContext->RSSetViewports(UINT(count), dxViewports);
-}
-
-void D3D11Renderer::setScissorRects(UInt count, ScissorRect const* rects)
-{
- static const int kMaxScissorRects = D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1;
- assert(count <= kMaxScissorRects);
-
- D3D11_RECT dxRects[kMaxScissorRects];
- for(UInt ii = 0; ii < count; ++ii)
- {
- auto& inRect = rects[ii];
- auto& dxRect = dxRects[ii];
-
- dxRect.left = LONG(inRect.minX);
- dxRect.top = LONG(inRect.minY);
- dxRect.right = LONG(inRect.maxX);
- dxRect.bottom = LONG(inRect.maxY);
- }
-
- m_immediateContext->RSSetScissorRects(UINT(count), dxRects);
-}
-
-
-void D3D11Renderer::setPipelineState(PipelineType pipelineType, PipelineState* state)
-{
- switch(pipelineType)
- {
- default:
- break;
-
- case PipelineType::Graphics:
- {
- auto stateImpl = (GraphicsPipelineStateImpl*) state;
- auto programImpl = stateImpl->m_program;
-
- // TODO: We could conceivably do some lightweight state
- // differencing here (e.g., check if `programImpl` is the
- // same as the program that is currently bound).
- //
- // It isn't clear how much that would pay off given that
- // the D3D11 runtime seems to do its own state diffing.
-
- // IA
-
- m_immediateContext->IASetInputLayout(stateImpl->m_inputLayout->m_layout);
-
- // VS
-
- m_immediateContext->VSSetShader(programImpl->m_vertexShader, nullptr, 0);
-
- // HS
-
- // DS
-
- // GS
-
- // RS
-
- m_immediateContext->RSSetState(stateImpl->m_rasterizerState);
-
- // PS
-
- m_immediateContext->PSSetShader(programImpl->m_pixelShader, nullptr, 0);
-
- // OM
-
- m_immediateContext->OMSetBlendState(stateImpl->m_blendState, stateImpl->m_blendColor, stateImpl->m_sampleMask);
- m_immediateContext->OMSetDepthStencilState(stateImpl->m_depthStencilState, stateImpl->m_stencilRef);
-
- m_currentGraphicsState = stateImpl;
- }
- break;
-
- case PipelineType::Compute:
- {
- auto stateImpl = (ComputePipelineStateImpl*) state;
- auto programImpl = stateImpl->m_program;
-
- // CS
-
- m_immediateContext->CSSetShader(programImpl->m_computeShader, nullptr, 0);
-
- m_currentComputeState = stateImpl;
- }
- break;
- }
-
- /// ...
-}
-
-void D3D11Renderer::draw(UInt vertexCount, UInt startVertex)
-{
- _flushGraphicsState();
- m_immediateContext->Draw((UINT)vertexCount, (UINT)startVertex);
-}
-
-void D3D11Renderer::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex)
-{
- _flushGraphicsState();
- m_immediateContext->DrawIndexed((UINT)indexCount, (UINT)startIndex, (INT)baseVertex);
-}
-
-Result D3D11Renderer::createProgram(const ShaderProgram::Desc& desc, ShaderProgram** outProgram)
-{
- if (desc.pipelineType == PipelineType::Compute)
- {
- auto computeKernel = desc.findKernel(StageType::Compute);
-
- ComPtr<ID3D11ComputeShader> computeShader;
- SLANG_RETURN_ON_FAIL(m_device->CreateComputeShader(computeKernel->codeBegin, computeKernel->getCodeSize(), nullptr, computeShader.writeRef()));
-
- RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl();
- shaderProgram->m_computeShader.swap(computeShader);
-
- *outProgram = shaderProgram.detach();
- return SLANG_OK;
- }
- else
- {
- auto vertexKernel = desc.findKernel(StageType::Vertex);
- auto fragmentKernel = desc.findKernel(StageType::Fragment);
-
- ComPtr<ID3D11VertexShader> vertexShader;
- ComPtr<ID3D11PixelShader> pixelShader;
-
- SLANG_RETURN_ON_FAIL(m_device->CreateVertexShader(vertexKernel->codeBegin, vertexKernel->getCodeSize(), nullptr, vertexShader.writeRef()));
- SLANG_RETURN_ON_FAIL(m_device->CreatePixelShader(fragmentKernel->codeBegin, fragmentKernel->getCodeSize(), nullptr, pixelShader.writeRef()));
-
- RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl();
- shaderProgram->m_vertexShader.swap(vertexShader);
- shaderProgram->m_pixelShader.swap(pixelShader);
-
- *outProgram = shaderProgram.detach();
- return SLANG_OK;
- }
-}
-
-static D3D11_STENCIL_OP translateStencilOp(StencilOp op)
-{
- switch(op)
- {
- default:
- // TODO: need to report failures
- return D3D11_STENCIL_OP_KEEP;
-
-#define CASE(FROM, TO) \
- case StencilOp::FROM: return D3D11_STENCIL_OP_##TO
-
- CASE(Keep, KEEP);
- CASE(Zero, ZERO);
- CASE(Replace, REPLACE);
- CASE(IncrementSaturate, INCR_SAT);
- CASE(DecrementSaturate, DECR_SAT);
- CASE(Invert, INVERT);
- CASE(IncrementWrap, INCR);
- CASE(DecrementWrap, DECR);
-#undef CASE
-
- }
-}
-
-static D3D11_FILL_MODE translateFillMode(FillMode mode)
-{
- switch(mode)
- {
- default:
- // TODO: need to report failures
- return D3D11_FILL_SOLID;
-
- case FillMode::Solid: return D3D11_FILL_SOLID;
- case FillMode::Wireframe: return D3D11_FILL_WIREFRAME;
- }
-}
-
-static D3D11_CULL_MODE translateCullMode(CullMode mode)
-{
- switch(mode)
- {
- default:
- // TODO: need to report failures
- return D3D11_CULL_NONE;
-
- case CullMode::None: return D3D11_CULL_NONE;
- case CullMode::Back: return D3D11_CULL_BACK;
- case CullMode::Front: return D3D11_CULL_FRONT;
- }
-}
-
-bool isBlendDisabled(AspectBlendDesc const& desc)
-{
- return desc.op == BlendOp::Add
- && desc.srcFactor == BlendFactor::One
- && desc.dstFactor == BlendFactor::Zero;
-}
-
-
-bool isBlendDisabled(TargetBlendDesc const& desc)
-{
- return isBlendDisabled(desc.color)
- && isBlendDisabled(desc.alpha);
-}
-
-D3D11_BLEND_OP translateBlendOp(BlendOp op)
-{
- switch(op)
- {
- default:
- assert(!"unimplemented");
- return (D3D11_BLEND_OP) -1;
-
-#define CASE(FROM, TO) case BlendOp::FROM: return D3D11_BLEND_OP_##TO
- CASE(Add, ADD);
- CASE(Subtract, SUBTRACT);
- CASE(ReverseSubtract, REV_SUBTRACT);
- CASE(Min, MIN);
- CASE(Max, MAX);
-#undef CASE
- }
-}
-
-D3D11_BLEND translateBlendFactor(BlendFactor factor)
-{
- switch(factor)
- {
- default:
- assert(!"unimplemented");
- return (D3D11_BLEND) -1;
-
-#define CASE(FROM, TO) case BlendFactor::FROM: return D3D11_BLEND_##TO
- CASE(Zero, ZERO);
- CASE(One, ONE);
- CASE(SrcColor, SRC_COLOR);
- CASE(InvSrcColor, INV_SRC_COLOR);
- CASE(SrcAlpha, SRC_ALPHA);
- CASE(InvSrcAlpha, INV_SRC_ALPHA);
- CASE(DestAlpha, DEST_ALPHA);
- CASE(InvDestAlpha, INV_DEST_ALPHA);
- CASE(DestColor, DEST_COLOR);
- CASE(InvDestColor, INV_DEST_ALPHA);
- CASE(SrcAlphaSaturate, SRC_ALPHA_SAT);
- CASE(BlendColor, BLEND_FACTOR);
- CASE(InvBlendColor, INV_BLEND_FACTOR);
- CASE(SecondarySrcColor, SRC1_COLOR);
- CASE(InvSecondarySrcColor, INV_SRC1_COLOR);
- CASE(SecondarySrcAlpha, SRC1_ALPHA);
- CASE(InvSecondarySrcAlpha, INV_SRC1_ALPHA);
-#undef CASE
- }
-}
-
-D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask(RenderTargetWriteMaskT mask)
-{
- UINT result = 0;
-#define CASE(FROM, TO) if(mask & RenderTargetWriteMask::Enable##FROM) result |= D3D11_COLOR_WRITE_ENABLE_##TO
-
- CASE(Red, RED);
- CASE(Green, GREEN);
- CASE(Blue, BLUE);
- CASE(Alpha, ALPHA);
-
-#undef CASE
- return D3D11_COLOR_WRITE_ENABLE(result);
-}
-
-Result D3D11Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& desc, PipelineState** outState)
-{
- auto programImpl = (ShaderProgramImpl*) desc.program;
-
- ComPtr<ID3D11DepthStencilState> depthStencilState;
- {
- D3D11_DEPTH_STENCIL_DESC dsDesc;
- dsDesc.DepthEnable = desc.depthStencil.depthTestEnable;
- dsDesc.DepthWriteMask = desc.depthStencil.depthWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
- dsDesc.DepthFunc = translateComparisonFunc(desc.depthStencil.depthFunc);
- dsDesc.StencilEnable = desc.depthStencil.stencilEnable;
- dsDesc.StencilReadMask = desc.depthStencil.stencilReadMask;
- dsDesc.StencilWriteMask = desc.depthStencil.stencilWriteMask;
-
- #define FACE(DST, SRC) \
- dsDesc.DST.StencilFailOp = translateStencilOp( desc.depthStencil.SRC.stencilFailOp); \
- dsDesc.DST.StencilDepthFailOp = translateStencilOp( desc.depthStencil.SRC.stencilDepthFailOp); \
- dsDesc.DST.StencilPassOp = translateStencilOp( desc.depthStencil.SRC.stencilPassOp); \
- dsDesc.DST.StencilFunc = translateComparisonFunc(desc.depthStencil.SRC.stencilFunc); \
- /* end */
-
- FACE(FrontFace, frontFace);
- FACE(BackFace, backFace);
-
- SLANG_RETURN_ON_FAIL(m_device->CreateDepthStencilState(
- &dsDesc,
- depthStencilState.writeRef()));
- }
-
- ComPtr<ID3D11RasterizerState> rasterizerState;
- {
- D3D11_RASTERIZER_DESC rsDesc;
- rsDesc.FillMode = translateFillMode(desc.rasterizer.fillMode);
- rsDesc.CullMode = translateCullMode(desc.rasterizer.cullMode);
- rsDesc.FrontCounterClockwise = desc.rasterizer.frontFace == FrontFaceMode::Clockwise;
- rsDesc.DepthBias = desc.rasterizer.depthBias;
- rsDesc.DepthBiasClamp = desc.rasterizer.depthBiasClamp;
- rsDesc.SlopeScaledDepthBias = desc.rasterizer.slopeScaledDepthBias;
- rsDesc.DepthClipEnable = desc.rasterizer.depthClipEnable;
- rsDesc.ScissorEnable = desc.rasterizer.scissorEnable;
- rsDesc.MultisampleEnable = desc.rasterizer.multisampleEnable;
- rsDesc.AntialiasedLineEnable = desc.rasterizer.antialiasedLineEnable;
-
- SLANG_RETURN_ON_FAIL(m_device->CreateRasterizerState(
- &rsDesc,
- rasterizerState.writeRef()));
-
- }
-
- ComPtr<ID3D11BlendState> blendState;
- {
- auto& srcDesc = desc.blend;
- D3D11_BLEND_DESC dstDesc = {};
-
- TargetBlendDesc defaultTargetBlendDesc;
-
- static const UInt kMaxTargets = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
- if(srcDesc.targetCount > kMaxTargets) return SLANG_FAIL;
-
- for(UInt ii = 0; ii < kMaxTargets; ++ii)
- {
- TargetBlendDesc const* srcTargetBlendDescPtr = nullptr;
- if(ii < srcDesc.targetCount)
- {
- srcTargetBlendDescPtr = &srcDesc.targets[ii];
- }
- else if(srcDesc.targetCount == 0)
- {
- srcTargetBlendDescPtr = &defaultTargetBlendDesc;
- }
- else
- {
- srcTargetBlendDescPtr = &srcDesc.targets[srcDesc.targetCount-1];
- }
-
- auto& srcTargetBlendDesc = *srcTargetBlendDescPtr;
- auto& dstTargetBlendDesc = dstDesc.RenderTarget[ii];
-
- if(isBlendDisabled(srcTargetBlendDesc))
- {
- dstTargetBlendDesc.BlendEnable = false;
- dstTargetBlendDesc.BlendOp = D3D11_BLEND_OP_ADD;
- dstTargetBlendDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
- dstTargetBlendDesc.SrcBlend = D3D11_BLEND_ONE;
- dstTargetBlendDesc.SrcBlendAlpha = D3D11_BLEND_ONE;
- dstTargetBlendDesc.DestBlend = D3D11_BLEND_ZERO;
- dstTargetBlendDesc.DestBlendAlpha = D3D11_BLEND_ZERO;
- }
- else
- {
- dstTargetBlendDesc.BlendEnable = true;
- dstTargetBlendDesc.BlendOp = translateBlendOp(srcTargetBlendDesc.color.op);
- dstTargetBlendDesc.BlendOpAlpha = translateBlendOp(srcTargetBlendDesc.alpha.op);
- dstTargetBlendDesc.SrcBlend = translateBlendFactor(srcTargetBlendDesc.color.srcFactor);
- dstTargetBlendDesc.SrcBlendAlpha = translateBlendFactor(srcTargetBlendDesc.alpha.srcFactor);
- dstTargetBlendDesc.DestBlend = translateBlendFactor(srcTargetBlendDesc.color.dstFactor);
- dstTargetBlendDesc.DestBlendAlpha = translateBlendFactor(srcTargetBlendDesc.alpha.dstFactor);
- }
-
- dstTargetBlendDesc.RenderTargetWriteMask = translateRenderTargetWriteMask(srcTargetBlendDesc.writeMask);
- }
-
- dstDesc.IndependentBlendEnable = srcDesc.targetCount > 1;
- dstDesc.AlphaToCoverageEnable = srcDesc.alphaToCoverateEnable;
-
- SLANG_RETURN_ON_FAIL(m_device->CreateBlendState(
- &dstDesc,
- blendState.writeRef()));
- }
-
- RefPtr<GraphicsPipelineStateImpl> state = new GraphicsPipelineStateImpl();
- state->m_program = programImpl;
- state->m_stencilRef = desc.depthStencil.stencilRef;
- state->m_depthStencilState = depthStencilState;
- state->m_rasterizerState = rasterizerState;
- state->m_blendState = blendState;
- state->m_pipelineLayout = (PipelineLayoutImpl*) desc.pipelineLayout;
- state->m_inputLayout = (InputLayoutImpl*) desc.inputLayout;
- state->m_rtvCount = UINT(desc.renderTargetCount);
- state->m_blendColor[0] = 0;
- state->m_blendColor[1] = 0;
- state->m_blendColor[2] = 0;
- state->m_blendColor[3] = 0;
- state->m_sampleMask = 0xFFFFFFFF;
-
- *outState = state.detach();
- return SLANG_OK;
-}
-
-Result D3D11Renderer::createComputePipelineState(const ComputePipelineStateDesc& desc, PipelineState** outState)
-{
- auto programImpl = (ShaderProgramImpl*) desc.program;
- auto pipelineLayoutImpl = (PipelineLayoutImpl*) desc.pipelineLayout;
-
- RefPtr<ComputePipelineStateImpl> state = new ComputePipelineStateImpl();
- state->m_program = programImpl;
- state->m_pipelineLayout = pipelineLayoutImpl;
-
- *outState = state.detach();
- return SLANG_OK;
-}
-
-void D3D11Renderer::dispatchCompute(int x, int y, int z)
-{
- _flushComputeState();
- m_immediateContext->Dispatch(x, y, z);
-}
-
-Result D3D11Renderer::createDescriptorSetLayout(const DescriptorSetLayout::Desc& desc, DescriptorSetLayout** outLayout)
-{
- RefPtr<DescriptorSetLayoutImpl> descriptorSetLayoutImpl = new DescriptorSetLayoutImpl();
-
- UInt counts[int(D3D11DescriptorSlotType::CountOf)] = { 0, };
-
- UInt rangeCount = desc.slotRangeCount;
- for(UInt rr = 0; rr < rangeCount; ++rr)
- {
- auto rangeDesc = desc.slotRanges[rr];
-
- DescriptorSetLayoutImpl::RangeInfo rangeInfo;
-
- switch(rangeDesc.type)
- {
- default:
- assert(!"invalid slot type");
- return SLANG_FAIL;
-
- case DescriptorSlotType::Sampler:
- rangeInfo.type = D3D11DescriptorSlotType::Sampler;
- break;
-
- case DescriptorSlotType::CombinedImageSampler:
- rangeInfo.type = D3D11DescriptorSlotType::CombinedTextureSampler;
- break;
-
- case DescriptorSlotType::UniformBuffer:
- case DescriptorSlotType::DynamicUniformBuffer:
- rangeInfo.type = D3D11DescriptorSlotType::ConstantBuffer;
- break;
-
- case DescriptorSlotType::SampledImage:
- case DescriptorSlotType::UniformTexelBuffer:
- case DescriptorSlotType::InputAttachment:
- rangeInfo.type = D3D11DescriptorSlotType::ShaderResourceView;
- break;
-
- case DescriptorSlotType::StorageImage:
- case DescriptorSlotType::StorageTexelBuffer:
- case DescriptorSlotType::StorageBuffer:
- case DescriptorSlotType::DynamicStorageBuffer:
- rangeInfo.type = D3D11DescriptorSlotType::UnorderedAccessView;
- break;
- }
-
- if(rangeInfo.type == D3D11DescriptorSlotType::CombinedTextureSampler)
- {
- auto srvTypeIndex = int(D3D11DescriptorSlotType::ShaderResourceView);
- auto samplerTypeIndex = int(D3D11DescriptorSlotType::Sampler);
-
- rangeInfo.arrayIndex = counts[srvTypeIndex];
- rangeInfo.pairedSamplerArrayIndex = counts[samplerTypeIndex];
-
- counts[srvTypeIndex] += rangeDesc.count;
- counts[samplerTypeIndex] += rangeDesc.count;
- }
- else
- {
- auto typeIndex = int(rangeInfo.type);
-
- rangeInfo.arrayIndex = counts[typeIndex];
- counts[typeIndex] += rangeDesc.count;
- }
- descriptorSetLayoutImpl->m_ranges.add(rangeInfo);
- }
-
- for(int ii = 0; ii < int(D3D11DescriptorSlotType::CountOf); ++ii)
- {
- descriptorSetLayoutImpl->m_counts[ii] = counts[ii];
- }
-
- *outLayout = descriptorSetLayoutImpl.detach();
- return SLANG_OK;
-}
-
-Result D3D11Renderer::createPipelineLayout(const PipelineLayout::Desc& desc, PipelineLayout** outLayout)
-{
- RefPtr<PipelineLayoutImpl> pipelineLayoutImpl = new PipelineLayoutImpl();
-
- UInt counts[int(D3D11DescriptorSlotType::CountOf)] = { 0, };
-
- UInt setCount = desc.descriptorSetCount;
- for(UInt ii = 0; ii < setCount; ++ii)
- {
- auto setDesc = desc.descriptorSets[ii];
- PipelineLayoutImpl::DescriptorSetInfo setInfo;
-
- setInfo.layout = (DescriptorSetLayoutImpl*) setDesc.layout;
-
- for(int jj = 0; jj < int(D3D11DescriptorSlotType::CountOf); ++jj)
- {
- setInfo.baseIndices[jj] = counts[jj];
- counts[jj] += setInfo.layout->m_counts[jj];
- }
-
- pipelineLayoutImpl->m_descriptorSets.add(setInfo);
- }
-
- pipelineLayoutImpl->m_uavCount = UINT(counts[int(D3D11DescriptorSlotType::UnorderedAccessView)]);
-
- *outLayout = pipelineLayoutImpl.detach();
- return SLANG_OK;
-}
-
-Result D3D11Renderer::createDescriptorSet(DescriptorSetLayout* layout, DescriptorSet** outDescriptorSet)
-{
- auto layoutImpl = (DescriptorSetLayoutImpl*)layout;
-
- RefPtr<DescriptorSetImpl> descriptorSetImpl = new DescriptorSetImpl();
-
- descriptorSetImpl->m_layout = layoutImpl;
- descriptorSetImpl->m_cbs .setCount(layoutImpl->m_counts[int(D3D11DescriptorSlotType::ConstantBuffer)]);
- descriptorSetImpl->m_srvs .setCount(layoutImpl->m_counts[int(D3D11DescriptorSlotType::ShaderResourceView)]);
- descriptorSetImpl->m_uavs .setCount(layoutImpl->m_counts[int(D3D11DescriptorSlotType::UnorderedAccessView)]);
- descriptorSetImpl->m_samplers.setCount(layoutImpl->m_counts[int(D3D11DescriptorSlotType::Sampler)]);
-
- *outDescriptorSet = descriptorSetImpl.detach();
- return SLANG_OK;
-}
-
-
-#if 0
-BindingState* D3D11Renderer::createBindingState(const BindingState::Desc& bindingStateDesc)
-{
- RefPtr<BindingStateImpl> bindingState(new BindingStateImpl(bindingStateDesc));
-
- const auto& srcBindings = bindingStateDesc.m_bindings;
- const int numBindings = int(srcBindings.Count());
-
- auto& dstDetails = bindingState->m_bindingDetails;
- dstDetails.SetSize(numBindings);
-
- for (int i = 0; i < numBindings; ++i)
- {
- auto& dstDetail = dstDetails[i];
- const auto& srcBinding = srcBindings[i];
-
- assert(srcBinding.registerRange.isSingle());
-
- switch (srcBinding.bindingType)
- {
- case BindingType::Buffer:
- {
- assert(srcBinding.resource && srcBinding.resource->isBuffer());
-
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(srcBinding.resource.Ptr());
- const BufferResource::Desc& desc = buffer->getDesc();
-
- const int elemSize = bufferDesc.elementSize <= 0 ? 1 : bufferDesc.elementSize;
-
- if (bufferDesc.bindFlags & Resource::BindFlag::UnorderedAccess)
- {
- D3D11_UNORDERED_ACCESS_VIEW_DESC viewDesc;
- memset(&viewDesc, 0, sizeof(viewDesc));
- viewDesc.Buffer.FirstElement = 0;
- viewDesc.Buffer.NumElements = (UINT)(bufferDesc.sizeInBytes / elemSize);
- viewDesc.Buffer.Flags = 0;
- viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
- viewDesc.Format = D3DUtil::getMapFormat(bufferDesc.format);
-
- if (bufferDesc.elementSize == 0 && bufferDesc.format == Format::Unknown)
- {
- viewDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW;
- viewDesc.Format = DXGI_FORMAT_R32_TYPELESS;
- }
-
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateUnorderedAccessView(buffer->m_buffer, &viewDesc, dstDetail.m_uav.writeRef()));
- }
- if (bufferDesc.bindFlags & (Resource::BindFlag::NonPixelShaderResource | Resource::BindFlag::PixelShaderResource))
- {
- D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
- memset(&viewDesc, 0, sizeof(viewDesc));
- viewDesc.Buffer.FirstElement = 0;
- viewDesc.Buffer.ElementWidth = elemSize;
- viewDesc.Buffer.NumElements = (UINT)(bufferDesc.sizeInBytes / elemSize);
- viewDesc.Buffer.ElementOffset = 0;
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
- viewDesc.Format = DXGI_FORMAT_UNKNOWN;
-
- if (bufferDesc.elementSize == 0)
- {
- viewDesc.Format = DXGI_FORMAT_R32_FLOAT;
- }
-
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateShaderResourceView(buffer->m_buffer, &viewDesc, dstDetail.m_srv.writeRef()));
- }
- break;
- }
- case BindingType::Texture:
- case BindingType::CombinedTextureSampler:
- {
- assert(srcBinding.resource && srcBinding.resource->isTexture());
-
- TextureResourceImpl* texture = static_cast<TextureResourceImpl*>(srcBinding.resource.Ptr());
-
- const TextureResource::Desc& textureDesc = texture->getDesc();
-
- D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
- viewDesc.Format = D3DUtil::getMapFormat(textureDesc.format);
-
- switch (texture->getType())
- {
- case Resource::Type::Texture1D:
- {
- if (textureDesc.arraySize <= 0)
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
- viewDesc.Texture1D.MipLevels = textureDesc.numMipLevels;
- viewDesc.Texture1D.MostDetailedMip = 0;
- }
- else
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
- viewDesc.Texture1DArray.ArraySize = textureDesc.arraySize;
- viewDesc.Texture1DArray.FirstArraySlice = 0;
- viewDesc.Texture1DArray.MipLevels = textureDesc.numMipLevels;
- viewDesc.Texture1DArray.MostDetailedMip = 0;
- }
- break;
- }
- case Resource::Type::Texture2D:
- {
- if (textureDesc.arraySize <= 0)
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
- viewDesc.Texture2D.MipLevels = textureDesc.numMipLevels;
- viewDesc.Texture2D.MostDetailedMip = 0;
- }
- else
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
- viewDesc.Texture2DArray.ArraySize = textureDesc.arraySize;
- viewDesc.Texture2DArray.FirstArraySlice = 0;
- viewDesc.Texture2DArray.MipLevels = textureDesc.numMipLevels;
- viewDesc.Texture2DArray.MostDetailedMip = 0;
- }
- break;
- }
- case Resource::Type::TextureCube:
- {
- if (textureDesc.arraySize <= 0)
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
- viewDesc.TextureCube.MipLevels = textureDesc.numMipLevels;
- viewDesc.TextureCube.MostDetailedMip = 0;
- }
- else
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
- viewDesc.TextureCubeArray.MipLevels = textureDesc.numMipLevels;
- viewDesc.TextureCubeArray.MostDetailedMip = 0;
- viewDesc.TextureCubeArray.First2DArrayFace = 0;
- viewDesc.TextureCubeArray.NumCubes = textureDesc.arraySize;
- }
- break;
- }
- case Resource::Type::Texture3D:
- {
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
- viewDesc.Texture3D.MipLevels = textureDesc.numMipLevels; // Old code fixed as one
- viewDesc.Texture3D.MostDetailedMip = 0;
- break;
- }
- default:
- {
- assert(!"Unhandled type");
- return nullptr;
- }
- }
-
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateShaderResourceView(texture->m_resource, &viewDesc, dstDetail.m_srv.writeRef()));
- break;
- }
- case BindingType::Sampler:
- {
- const BindingState::SamplerDesc& samplerDesc = bindingStateDesc.m_samplerDescs[srcBinding.descIndex];
-
- D3D11_SAMPLER_DESC desc = {};
- desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
-
- if (samplerDesc.isCompareSampler)
- {
- desc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
- desc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
- desc.MinLOD = desc.MaxLOD = 0.0f;
- }
- else
- {
- desc.Filter = D3D11_FILTER_ANISOTROPIC;
- desc.MaxAnisotropy = 8;
- desc.MinLOD = 0.0f;
- desc.MaxLOD = 100.0f;
- }
- SLANG_RETURN_NULL_ON_FAIL(m_device->CreateSamplerState(&desc, dstDetail.m_samplerState.writeRef()));
- break;
- }
- default:
- {
- assert(!"Unhandled type");
- return nullptr;
- }
- }
- }
-
- // Done
- return bindingState.detach();
-}
-
-void D3D11Renderer::_applyBindingState(bool isCompute)
-{
- auto context = m_immediateContext.get();
-
- const auto& details = m_currentBindings->m_bindingDetails;
- const auto& bindings = m_currentBindings->getDesc().m_bindings;
-
- const int numBindings = int(bindings.Count());
-
- for (int i = 0; i < numBindings; ++i)
- {
- const auto& binding = bindings[i];
- const auto& detail = details[i];
-
- const int bindingIndex = binding.registerRange.getSingleIndex();
-
- switch (binding.bindingType)
- {
- case BindingType::Buffer:
- {
- assert(binding.resource && binding.resource->isBuffer());
- if (binding.resource->canBind(Resource::BindFlag::ConstantBuffer))
- {
- ID3D11Buffer* buffer = static_cast<BufferResourceImpl*>(binding.resource.Ptr())->m_buffer;
- if (isCompute)
- context->CSSetConstantBuffers(bindingIndex, 1, &buffer);
- else
- {
- context->VSSetConstantBuffers(bindingIndex, 1, &buffer);
- context->PSSetConstantBuffers(bindingIndex, 1, &buffer);
- }
- }
- else if (detail.m_uav)
- {
- if (isCompute)
- context->CSSetUnorderedAccessViews(bindingIndex, 1, detail.m_uav.readRef(), nullptr);
- else
- context->OMSetRenderTargetsAndUnorderedAccessViews(
- m_currentBindings->getDesc().m_numRenderTargets,
- m_renderTargetViews.getBuffer()->readRef(),
- m_depthStencilView,
- bindingIndex,
- 1,
- detail.m_uav.readRef(),
- nullptr);
- }
- else
- {
- if (isCompute)
- context->CSSetShaderResources(bindingIndex, 1, detail.m_srv.readRef());
- else
- {
- context->PSSetShaderResources(bindingIndex, 1, detail.m_srv.readRef());
- context->VSSetShaderResources(bindingIndex, 1, detail.m_srv.readRef());
- }
- }
- break;
- }
- case BindingType::Texture:
- {
- if (detail.m_uav)
- {
- if (isCompute)
- context->CSSetUnorderedAccessViews(bindingIndex, 1, detail.m_uav.readRef(), nullptr);
- else
- context->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL,
- nullptr, nullptr, bindingIndex, 1, detail.m_uav.readRef(), nullptr);
- }
- else
- {
- if (isCompute)
- context->CSSetShaderResources(bindingIndex, 1, detail.m_srv.readRef());
- else
- {
- context->PSSetShaderResources(bindingIndex, 1, detail.m_srv.readRef());
- context->VSSetShaderResources(bindingIndex, 1, detail.m_srv.readRef());
- }
- }
- break;
- }
- case BindingType::Sampler:
- {
- if (isCompute)
- context->CSSetSamplers(bindingIndex, 1, detail.m_samplerState.readRef());
- else
- {
- context->PSSetSamplers(bindingIndex, 1, detail.m_samplerState.readRef());
- context->VSSetSamplers(bindingIndex, 1, detail.m_samplerState.readRef());
- }
- break;
- }
- default:
- {
- assert(!"Not implemented");
- return;
- }
- }
- }
-}
-
-void D3D11Renderer::setBindingState(BindingState* state)
-{
- m_currentBindings = static_cast<BindingStateImpl*>(state);
-}
-#endif
-
-void D3D11Renderer::_flushGraphicsState()
-{
- auto pipelineType = int(PipelineType::Graphics);
- if(m_targetBindingsDirty[pipelineType])
- {
- m_targetBindingsDirty[pipelineType] = false;
-
- auto pipelineState = m_currentGraphicsState.Ptr();
-
- auto rtvCount = pipelineState->m_rtvCount;
- auto uavCount = pipelineState->m_pipelineLayout->m_uavCount;
-
- m_immediateContext->OMSetRenderTargetsAndUnorderedAccessViews(
- rtvCount,
- m_rtvBindings[0].readRef(),
- m_dsvBinding,
- rtvCount,
- uavCount,
- m_uavBindings[pipelineType][0].readRef(),
- nullptr);
- }
-}
-
-void D3D11Renderer::_flushComputeState()
-{
- auto pipelineType = int(PipelineType::Compute);
- if(m_targetBindingsDirty[pipelineType])
- {
- m_targetBindingsDirty[pipelineType] = false;
-
- auto pipelineState = m_currentComputeState.Ptr();
-
- auto uavCount = pipelineState->m_pipelineLayout->m_uavCount;
-
- m_immediateContext->CSSetUnorderedAccessViews(
- 0,
- uavCount,
- m_uavBindings[pipelineType][0].readRef(),
- nullptr);
- }
-}
-
-void D3D11Renderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, BufferResource* buffer)
-{
- auto bufferImpl = (BufferResourceImpl*) buffer;
- auto& rangeInfo = m_layout->m_ranges[range];
-
- assert(rangeInfo.type == D3D11DescriptorSlotType::ConstantBuffer);
-
- m_cbs[rangeInfo.arrayIndex + index] = bufferImpl->m_buffer;
-}
-
-void D3D11Renderer::DescriptorSetImpl::setResource(UInt range, UInt index, ResourceView* view)
-{
- auto viewImpl = (ResourceViewImpl*)view;
- auto& rangeInfo = m_layout->m_ranges[range];
-
- switch (rangeInfo.type)
- {
- case D3D11DescriptorSlotType::ShaderResourceView:
- {
- assert(viewImpl->m_type == ResourceViewImpl::Type::SRV);
- auto srvImpl = (ShaderResourceViewImpl*)viewImpl;
- m_srvs[rangeInfo.arrayIndex + index] = srvImpl->m_srv;
- }
- break;
-
- case D3D11DescriptorSlotType::UnorderedAccessView:
- {
- assert(viewImpl->m_type == ResourceViewImpl::Type::UAV);
- auto uavImpl = (UnorderedAccessViewImpl*)viewImpl;
- m_uavs[rangeInfo.arrayIndex + index] = uavImpl->m_uav;
- }
- break;
-
- default:
- assert(!"invalid to bind a resource view to this descriptor range");
- break;
- }
-}
-
-void D3D11Renderer::DescriptorSetImpl::setSampler(UInt range, UInt index, SamplerState* sampler)
-{
- auto samplerImpl = (SamplerStateImpl*) sampler;
- auto& rangeInfo = m_layout->m_ranges[range];
-
- assert(rangeInfo.type == D3D11DescriptorSlotType::Sampler);
-
- m_samplers[rangeInfo.arrayIndex + index] = samplerImpl->m_sampler;
-}
-
-void D3D11Renderer::DescriptorSetImpl::setCombinedTextureSampler(
- UInt range,
- UInt index,
- ResourceView* textureView,
- SamplerState* sampler)
-{
- auto viewImpl = (ResourceViewImpl*) textureView;
- auto samplerImpl = (SamplerStateImpl*)sampler;
-
- auto& rangeInfo = m_layout->m_ranges[range];
- assert(rangeInfo.type == D3D11DescriptorSlotType::CombinedTextureSampler);
-
- assert(viewImpl->m_type == ResourceViewImpl::Type::SRV);
- auto srvImpl = (ShaderResourceViewImpl*)viewImpl;
- m_srvs[rangeInfo.arrayIndex + index] = srvImpl->m_srv;
-
- m_samplers[rangeInfo.arrayIndex + index] = samplerImpl->m_sampler;
-
- // TODO: need a place to bind the matching sampler...
- m_srvs[rangeInfo.pairedSamplerArrayIndex + index] = srvImpl->m_srv;
-}
-
-void D3D11Renderer::setDescriptorSet(PipelineType pipelineType, PipelineLayout* layout, UInt index, DescriptorSet* descriptorSet)
-{
- auto pipelineLayoutImpl = (PipelineLayoutImpl*)layout;
- auto descriptorSetImpl = (DescriptorSetImpl*) descriptorSet;
-
- auto descriptorSetLayoutImpl = descriptorSetImpl->m_layout;
- auto& setInfo = pipelineLayoutImpl->m_descriptorSets[index];
-
- // Note: `setInfo->layout` and `descriptorSetLayoutImpl` need to be compatible
-
- // TODO: If/when we add per-stage visibility masks, it would be best to organize
- // this as a loop over stages, so that we only do the binding that is required
- // for each stage.
-
- {
- const int slotType = int(D3D11DescriptorSlotType::ConstantBuffer);
- const UINT slotCount = UINT(setInfo.layout->m_counts[slotType]);
- if(slotCount)
- {
- const UINT startSlot = UINT(setInfo.baseIndices[slotType]);
-
- auto cbs = descriptorSetImpl->m_cbs[0].readRef();
-
- m_immediateContext->VSSetConstantBuffers(startSlot, slotCount, cbs);
- // ...
- m_immediateContext->PSSetConstantBuffers(startSlot, slotCount, cbs);
-
- m_immediateContext->CSSetConstantBuffers(startSlot, slotCount, cbs);
- }
- }
-
- {
- const int slotType = int(D3D11DescriptorSlotType::ShaderResourceView);
- const UINT slotCount = UINT(setInfo.layout->m_counts[slotType]);
- if(slotCount)
- {
- const UINT startSlot = UINT(setInfo.baseIndices[slotType]);
-
- auto srvs = descriptorSetImpl->m_srvs[0].readRef();
-
- m_immediateContext->VSSetShaderResources(startSlot, slotCount, srvs);
- // ...
- m_immediateContext->PSSetShaderResources(startSlot, slotCount, srvs);
-
- m_immediateContext->CSSetShaderResources(startSlot, slotCount, srvs);
- }
- }
-
- {
- const int slotType = int(D3D11DescriptorSlotType::Sampler);
- const UINT slotCount = UINT(setInfo.layout->m_counts[slotType]);
- if(slotCount)
- {
- const UINT startSlot = UINT(setInfo.baseIndices[slotType]);
-
- auto samplers = descriptorSetImpl->m_samplers[0].readRef();
-
- m_immediateContext->VSSetSamplers(startSlot, slotCount, samplers);
- // ...
- m_immediateContext->PSSetSamplers(startSlot, slotCount, samplers);
-
- m_immediateContext->CSSetSamplers(startSlot, slotCount, samplers);
- }
- }
-
- {
- // Note: UAVs are handled differently from other bindings, because
- // D3D11 requires all UAVs to be set with a single call, rather
- // than allowing incremental updates. We will therefore shadow
- // the UAV bindings with `m_uavBindings` and then flush them
- // as needed right before a draw/dispatch.
- //
- const int slotType = int(D3D11DescriptorSlotType::UnorderedAccessView);
- const UInt slotCount = setInfo.layout->m_counts[slotType];
- if(slotCount)
- {
- UInt startSlot = setInfo.baseIndices[slotType];
-
- auto uavs = descriptorSetImpl->m_uavs[0].readRef();
-
- for(UINT ii = 0; ii < slotCount; ++ii)
- {
- m_uavBindings[int(pipelineType)][startSlot + ii] = uavs[ii];
- }
- m_targetBindingsDirty[int(pipelineType)] = true;
- }
- }
-
-
-}
-
-} // renderer_test