diff options
| -rw-r--r-- | tools/render-test/main.cpp | 58 | ||||
| -rw-r--r-- | tools/render-test/render-d3d11.cpp | 2 | ||||
| -rw-r--r-- | tools/render-test/render-d3d12.cpp | 4 | ||||
| -rw-r--r-- | tools/render-test/render-gl.cpp | 4 | ||||
| -rw-r--r-- | tools/render-test/render-test.vcxproj | 2 | ||||
| -rw-r--r-- | tools/render-test/render-test.vcxproj.filters | 6 | ||||
| -rw-r--r-- | tools/render-test/render-vk.cpp | 2 | ||||
| -rw-r--r-- | tools/render-test/render.cpp | 58 | ||||
| -rw-r--r-- | tools/render-test/render.h | 92 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.cpp | 200 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.h | 27 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 251 | ||||
| -rw-r--r-- | tools/render-test/slang-support.h | 14 |
13 files changed, 378 insertions, 342 deletions
diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index 887ba4005..5c15c8037 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -9,6 +9,8 @@ #include "slang-support.h" +#include "shader-renderer-util.h" + #include "shader-input-layout.h" #include <stdio.h> #include <stdlib.h> @@ -103,7 +105,7 @@ SlangResult RenderTestApp::initialize(Renderer* renderer, ShaderCompiler* shader { BindingState::Desc bindingStateDesc; - SLANG_RETURN_ON_FAIL(createBindingStateDesc(m_shaderInputLayout, m_renderer, bindingStateDesc)); + SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBindingStateDesc(m_shaderInputLayout, m_renderer, bindingStateDesc)); m_bindingState = m_renderer->createBindingState(bindingStateDesc); } @@ -246,9 +248,59 @@ void RenderTestApp::finalize() Result RenderTestApp::writeBindingOutput(const char* fileName) { - return serializeBindingOutput(m_shaderInputLayout, m_bindingState, m_renderer, fileName); -} + // Submit the work + m_renderer->submitGpuWork(); + // Wait until everything is complete + m_renderer->waitForGpu(); + + FILE * f = fopen(fileName, "wb"); + if (!f) + { + return SLANG_FAIL; + } + + const BindingState::Desc& bindingStateDesc = m_bindingState->getDesc(); + // Must be the same amount of entries + assert(bindingStateDesc.m_bindings.Count() == m_shaderInputLayout.entries.Count()); + const int numBindings = int(bindingStateDesc.m_bindings.Count()); + + for (int i = 0; i < numBindings; ++i) + { + const auto& layoutBinding = m_shaderInputLayout.entries[i]; + const auto& binding = bindingStateDesc.m_bindings[i]; + + if (layoutBinding.isOutput) + { + if (binding.resource && binding.resource->isBuffer()) + { + BufferResource* bufferResource = static_cast<BufferResource*>(binding.resource.Ptr()); + const size_t bufferSize = bufferResource->getDesc().sizeInBytes; + + unsigned int* ptr = (unsigned int*)m_renderer->map(bufferResource, MapFlavor::HostRead); + if (!ptr) + { + fclose(f); + return SLANG_FAIL; + } + + const int size = int(bufferSize / sizeof(unsigned int)); + for (int i = 0; i < size; ++i) + { + fprintf(f, "%X\n", ptr[i]); + } + m_renderer->unmap(bufferResource); + } + else + { + printf("invalid output type at %d.\n", i); + } + } + } + fclose(f); + + return SLANG_OK; +} // // We use a bare-minimum window procedure to get things up and running. diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index a0c4956f2..7018c223a 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -874,7 +874,7 @@ BindingState* D3D11Renderer::createBindingState(const BindingState::Desc& bindin auto& dstDetail = dstDetails[i]; const auto& srcBinding = srcBindings[i]; - dstDetail.m_binding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Hlsl, srcBinding.registerDesc); + dstDetail.m_binding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Hlsl, srcBinding.shaderBindSet); switch (srcBinding.bindingType) { diff --git a/tools/render-test/render-d3d12.cpp b/tools/render-test/render-d3d12.cpp index da2b3abd0..66f148c23 100644 --- a/tools/render-test/render-d3d12.cpp +++ b/tools/render-test/render-d3d12.cpp @@ -2370,7 +2370,7 @@ BindingState* D3D12Renderer::createBindingState(const BindingState::Desc& bindin const auto& srcEntry = srcBindings[i]; auto& dstDetail = dstDetails[i]; - dstDetail.m_binding = bindingStateDesc.getFirst(srcEntry.registerDesc.registerSets[int(BindingState::ShaderStyle::Hlsl)]); + dstDetail.m_binding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Hlsl, srcEntry.shaderBindSet); switch (srcEntry.bindingType) { @@ -2478,7 +2478,7 @@ BindingState* D3D12Renderer::createBindingState(const BindingState::Desc& bindin { const BindingState::SamplerDesc& samplerDesc = bindingStateDesc.m_samplerDescs[srcEntry.descIndex]; - const int samplerIndex = bindingStateDesc.getFirst(srcEntry.registerDesc.registerSets[int(BindingState::ShaderStyle::Hlsl)]); + const int samplerIndex = bindingStateDesc.getFirst(BindingState::ShaderStyle::Hlsl, srcEntry.shaderBindSet); dstDetail.m_samplerIndex = samplerIndex; bindingState->m_samplerHeap.placeAt(samplerIndex); diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp index 8db963014..10e25fdcd 100644 --- a/tools/render-test/render-gl.cpp +++ b/tools/render-test/render-gl.cpp @@ -928,7 +928,7 @@ BindingState* GLRenderer::createBindingState(const BindingState::Desc& bindingSt const auto& srcBinding = srcBindings[i]; // Copy over the bindings - dstDetail.m_firstBinding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Glsl, srcBinding.registerDesc); + dstDetail.m_firstBinding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Glsl, srcBinding.shaderBindSet); switch (srcBinding.bindingType) { @@ -1013,7 +1013,7 @@ void GLRenderer::setBindingState(BindingState* stateIn) } case BindingType::Sampler: { - auto bindings = bindingDesc.asRegisterList(BindingState::ShaderStyle::Glsl, binding.registerDesc); + auto bindings = bindingDesc.asSlice(BindingState::ShaderStyle::Glsl, binding.shaderBindSet); for (auto b : bindings) { glBindSampler(b, detail.m_samplerHandle); diff --git a/tools/render-test/render-test.vcxproj b/tools/render-test/render-test.vcxproj index 2106bb9c2..1d4d5ed2e 100644 --- a/tools/render-test/render-test.vcxproj +++ b/tools/render-test/render-test.vcxproj @@ -178,6 +178,7 @@ <ClCompile Include="render.cpp" /> <ClCompile Include="resource-d3d12.cpp" /> <ClCompile Include="shader-input-layout.cpp" /> + <ClCompile Include="shader-renderer-util.cpp" /> <ClCompile Include="slang-support.cpp" /> </ItemGroup> <ItemGroup> @@ -192,6 +193,7 @@ <ClInclude Include="render.h" /> <ClInclude Include="resource-d3d12.h" /> <ClInclude Include="shader-input-layout.h" /> + <ClInclude Include="shader-renderer-util.h" /> <ClInclude Include="slang-support.h" /> <ClInclude Include="window.h" /> </ItemGroup> diff --git a/tools/render-test/render-test.vcxproj.filters b/tools/render-test/render-test.vcxproj.filters index 640f132a2..82e1d990f 100644 --- a/tools/render-test/render-test.vcxproj.filters +++ b/tools/render-test/render-test.vcxproj.filters @@ -54,6 +54,9 @@ <ClCompile Include="render.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="shader-renderer-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="options.h"> @@ -95,5 +98,8 @@ <ClInclude Include="descriptor-heap-d3d12.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="shader-renderer-util.h"> + <Filter>Source Files</Filter> + </ClInclude> </ItemGroup> </Project>
\ No newline at end of file diff --git a/tools/render-test/render-vk.cpp b/tools/render-test/render-vk.cpp index 68d933d92..ef05d23b6 100644 --- a/tools/render-test/render-vk.cpp +++ b/tools/render-test/render-vk.cpp @@ -839,7 +839,7 @@ BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingSt const auto& srcBinding = srcBindings[i]; // For now use Glsl binding - dstDetail.m_binding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Glsl, srcBinding.registerDesc); + dstDetail.m_binding = bindingStateDesc.getFirst(BindingState::ShaderStyle::Glsl, srcBinding.shaderBindSet); switch (srcBinding.bindingType) { diff --git a/tools/render-test/render.cpp b/tools/render-test/render.cpp index 3346317e7..37948f88b 100644 --- a/tools/render-test/render.cpp +++ b/tools/render-test/render.cpp @@ -38,7 +38,7 @@ const Resource::DescBase& Resource::getDescBase() const /* !!!!!!!!!!!!!!!!!!!!!!!!!!! BindingState::Desc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -void BindingState::Desc::addSampler(const SamplerDesc& desc, const RegisterDesc& registerDesc) +void BindingState::Desc::addSampler(const SamplerDesc& desc, const ShaderBindSet& shaderBindSet) { int descIndex = int(m_samplerDescs.Count()); m_samplerDescs.Add(desc); @@ -46,13 +46,13 @@ void BindingState::Desc::addSampler(const SamplerDesc& desc, const RegisterDesc& Binding binding; binding.bindingType = BindingType::Sampler; binding.resource = nullptr; - binding.registerDesc = registerDesc; + binding.shaderBindSet = shaderBindSet; binding.descIndex = descIndex; m_bindings.Add(binding); } -void BindingState::Desc::addResource(BindingType bindingType, Resource* resource, const RegisterDesc& registerDesc) +void BindingState::Desc::addResource(BindingType bindingType, Resource* resource, const ShaderBindSet& shaderBindSet) { assert(resource); @@ -60,11 +60,11 @@ void BindingState::Desc::addResource(BindingType bindingType, Resource* resource binding.bindingType = bindingType; binding.resource = resource; binding.descIndex = -1; - binding.registerDesc = registerDesc; + binding.shaderBindSet = shaderBindSet; m_bindings.Add(binding); } -void BindingState::Desc::addCombinedTextureSampler(TextureResource* resource, const SamplerDesc& samplerDesc, const RegisterDesc& registerDesc) +void BindingState::Desc::addCombinedTextureSampler(TextureResource* resource, const SamplerDesc& samplerDesc, const ShaderBindSet& shaderBindSet) { assert(resource); @@ -75,77 +75,77 @@ void BindingState::Desc::addCombinedTextureSampler(TextureResource* resource, co binding.bindingType = BindingType::CombinedTextureSampler; binding.resource = resource; binding.descIndex = samplerDescIndex; - binding.registerDesc = registerDesc; + binding.shaderBindSet = shaderBindSet; m_bindings.Add(binding); } -BindingState::RegisterSet BindingState::Desc::addRegisterSet(int index) +BindingState::CompactBindIndexSlice BindingState::Desc::makeCompactSlice(int index) { if (index < 0) { - return RegisterSet(); + return CompactBindIndexSlice(); } - return RegisterSet(index, 1); + return CompactBindIndexSlice(index, 1); } -BindingState::RegisterSet BindingState::Desc::addRegisterSet(const int* srcIndices, int numIndices) +BindingState::CompactBindIndexSlice BindingState::Desc::makeCompactSlice(const int* srcIndices, int numIndices) { assert(numIndices >= 0); switch (numIndices) { - case 0: return RegisterSet(); - case 1: return RegisterSet(srcIndices[0], 1); + case 0: return CompactBindIndexSlice(); + case 1: return CompactBindIndexSlice(srcIndices[0], 1); default: { - int startIndex = int(m_indices.Count()); - m_indices.SetSize(startIndex + numIndices); - uint16_t* dstIndices = m_indices.Buffer() + startIndex; + int startIndex = int(m_sharedBindIndices.Count()); + m_sharedBindIndices.SetSize(startIndex + numIndices); + uint16_t* dstIndices = m_sharedBindIndices.Buffer() + startIndex; for (int i = 0; i < numIndices; i++) { assert(srcIndices[i] >= 0); dstIndices[i] = uint16_t(srcIndices[i]); } - return RegisterSet(startIndex, numIndices); + return CompactBindIndexSlice(startIndex, numIndices); } } } -int BindingState::Desc::getFirst(const RegisterSet& set) const +int BindingState::Desc::getFirst(const CompactBindIndexSlice& set) const { - switch (set.m_numIndices) + switch (set.m_size) { case 0: return -1; case 1: return set.m_indexOrBase; - default: return m_indices[set.m_indexOrBase]; + default: return m_sharedBindIndices[set.m_indexOrBase]; } } -int BindingState::Desc::getFirst(ShaderStyle style, const RegisterDesc& registerDesc) const +int BindingState::Desc::getFirst(ShaderStyle style, const ShaderBindSet& shaderBindSet) const { - return getFirst(registerDesc.registerSets[int(style)]); + return getFirst(shaderBindSet.shaderSlices[int(style)]); } void BindingState::Desc::clear() { m_bindings.Clear(); m_samplerDescs.Clear(); - m_indices.Clear(); + m_sharedBindIndices.Clear(); m_numRenderTargets = 1; } -BindingState::RegisterList BindingState::Desc::asRegisterList(const RegisterSet& set) const +BindingState::BindIndexSlice BindingState::Desc::asSlice(const CompactBindIndexSlice& compactSlice) const { - switch (set.m_numIndices) + switch (compactSlice.m_size) { - case 0: return RegisterList{ nullptr, 0 }; - case 1: return RegisterList{ &set.m_indexOrBase, 1 }; - default: return RegisterList{ m_indices.Buffer() + set.m_indexOrBase, set.m_numIndices }; + case 0: return BindIndexSlice{ nullptr, 0 }; + case 1: return BindIndexSlice{ &compactSlice.m_indexOrBase, 1 }; + default: return BindIndexSlice{ m_sharedBindIndices.Buffer() + compactSlice.m_indexOrBase, compactSlice.m_size }; } } -BindingState::RegisterList BindingState::Desc::asRegisterList(ShaderStyle style, const RegisterDesc& registerDesc) const +BindingState::BindIndexSlice BindingState::Desc::asSlice(ShaderStyle style, const ShaderBindSet& shaderBindSet) const { - return asRegisterList(registerDesc.registerSets[int(style)]); + return asSlice(shaderBindSet.shaderSlices[int(style)]); } diff --git a/tools/render-test/render.h b/tools/render-test/render.h index 4a25c2369..861b56b32 100644 --- a/tools/render-test/render.h +++ b/tools/render-test/render.h @@ -276,7 +276,8 @@ class TextureResource: public Resource /// and if the type is a cubemap (multiplies the amount of mip sets by 6) int calcEffectiveArraySize(Type type) const; - /// + /// Use type to fix the size values (and array size). + /// For example a 1d texture, should have height and depth set to 1. void fixSize(Type type); /// Set up default parameters based on type and usage @@ -286,13 +287,13 @@ class TextureResource: public Resource int arraySize; ///< Array size - int numMipLevels; ///< Number of mip levels - if 0 will generate all mip levels + int numMipLevels; ///< Number of mip levels - if 0 will create all mip levels Format format; ///< The resources format SampleDesc sampleDesc; ///< How the resource is sampled }; - /// The ordering of the subResources is - /// forall (cube faces (6) * arraySize / arraySize) + /// The ordering of the subResources is + /// forall (effectiveArraySize) /// forall (mip levels) /// forall (depth levels) struct Data @@ -337,6 +338,9 @@ class BindingState : public Slang::RefObject { public: + typedef uint16_t BindIndex; + + /// Shader binding style enum class ShaderStyle { Hlsl, @@ -344,38 +348,48 @@ public: CountOf, }; - struct RegisterSet + /// A 'compact' representation of a 0 or more BindIndices. + /// A Slice in this context is effectively an unowned array. + /// If only a single index is he held (which is common) it's held directly in the m_indexOrBase member, otherwise m_indexOrBase is an index into the + /// m_indices list of the Desc. Can be turned into a BindIndexSlice (which is easier to use, and iterable) using asBindIndexSlice method on Desc + struct CompactBindIndexSlice { + typedef uint16_t SizeType; /// Default Ctor makes an empty set - SLANG_FORCE_INLINE RegisterSet() : - m_numIndices(0), + SLANG_FORCE_INLINE CompactBindIndexSlice() : + m_size(0), m_indexOrBase(0) {} - /// Ctor for one or more. NOTE! Meaning if indexIn changes depending if numIndices > 1. - SLANG_FORCE_INLINE RegisterSet(int indexIn, int numIndicesIn) : - m_numIndices(uint8_t(numIndicesIn)), - m_indexOrBase(uint16_t(indexIn)) + /// Ctor for one or more. NOTE! Meaning if indexIn changes depending if numIndices > 1. + SLANG_FORCE_INLINE CompactBindIndexSlice(int indexIn, int sizeIn) : + m_size(SizeType(sizeIn)), + m_indexOrBase(BindIndex(indexIn)) { } - uint8_t m_numIndices; - uint16_t m_indexOrBase; ///< Meaning changes depending on numIndices. If 1, it is the index if larger than 1, then is an index into 'indices' + SizeType m_size; + BindIndex m_indexOrBase; ///< Meaning changes depending on numIndices. If 1, it is the index if larger than 1, then is an index into 'indices' }; - struct RegisterDesc + /// Holds the BindIndex slice associated with each ShaderStyle + struct ShaderBindSet { - RegisterSet registerSets[int(ShaderStyle::CountOf)]; + void set(ShaderStyle style, const CompactBindIndexSlice& slice) { shaderSlices[int(style)] = slice; } + + CompactBindIndexSlice shaderSlices[int(ShaderStyle::CountOf)]; }; - struct RegisterList + /// A slice (non owned array) of BindIndices + /// TODO: have a generic Slice<T> type instead of this specific type + struct BindIndexSlice { - const uint16_t* begin() const { return indices; } - const uint16_t* end() const { return indices + numIndices; } + const BindIndex* begin() const { return data; } + const BindIndex* end() const { return data + size; } - int getSize() const { return int(numIndices); } - uint16_t operator[](int i) const { assert(i >= 0 && i < numIndices); return indices[i]; } + int getSize() const { return int(size); } + BindIndex operator[](int i) const { assert(i >= 0 && i < size); return data[i]; } - const uint16_t* indices; - int numIndices; + const BindIndex* data; + int size; }; struct SamplerDesc @@ -388,44 +402,44 @@ public: BindingType bindingType; ///< Type of binding int descIndex; ///< The description index associated with type. -1 if not used. For example if bindingType is Sampler, the descIndex is into m_samplerDescs. Slang::RefPtr<Resource> resource; ///< Associated resource. nullptr if not used - RegisterDesc registerDesc; ///< Registers associated with binding + ShaderBindSet shaderBindSet; ///< Holds BindIndices associated with each ShaderStyle }; struct Desc { /// Given a RegisterSet, return as a RegisterList, that can be easily iterated over - RegisterList asRegisterList(const RegisterSet& set) const; + BindIndexSlice asSlice(const CompactBindIndexSlice& set) const; /// Given a RegisterDesc and a style returns a RegisterList, that can be easily iterated over - RegisterList asRegisterList(ShaderStyle style, const RegisterDesc& registerDesc) const; + BindIndexSlice asSlice(ShaderStyle style, const ShaderBindSet& shaderBindSet) const; /// Returns the first member of the set, or returns -1 if is empty - int getFirst(const RegisterSet& set) const; + int getFirst(const CompactBindIndexSlice& set) const; /// Returns the first member of the set, or returns -1 if is empty - int getFirst(ShaderStyle style, const RegisterDesc& registerDesc) const; + int getFirst(ShaderStyle style, const ShaderBindSet& shaderBindSet) const; /// Add a resource - assumed that the binding will match the Desc of the resource - void addResource(BindingType bindingType, Resource* resource, const RegisterDesc& registerDesc); + void addResource(BindingType bindingType, Resource* resource, const ShaderBindSet& shaderBindSet); /// Add a sampler - void addSampler(const SamplerDesc& desc, const RegisterDesc& registerDesc); + void addSampler(const SamplerDesc& desc, const ShaderBindSet& shaderBindSet); /// Add a BufferResource - void addBufferResource(BufferResource* resource, const RegisterDesc& registerDesc) { addResource(BindingType::Buffer, resource, registerDesc); } + void addBufferResource(BufferResource* resource, const ShaderBindSet& shaderBindSet) { addResource(BindingType::Buffer, resource, shaderBindSet); } /// Add a texture - void addTextureResource(TextureResource* resource, const RegisterDesc& registerDesc) { addResource(BindingType::Texture, resource, registerDesc); } + void addTextureResource(TextureResource* resource, const ShaderBindSet& shaderBindSet) { addResource(BindingType::Texture, resource, shaderBindSet); } /// Add combined texture a - void addCombinedTextureSampler(TextureResource* resource, const SamplerDesc& samplerDesc, const RegisterDesc& registerDesc); + void addCombinedTextureSampler(TextureResource* resource, const SamplerDesc& samplerDesc, const ShaderBindSet& shaderBindSet); /// Clear the contents void clear(); - /// Given an index, returns as a register set. If index is < 0, assumes means no indices, and just returns the empty set - RegisterSet addRegisterSet(int index); - /// Given a list of indices, returns the associated register set. Note does check for indices being unique. The order is maintained. + /// Given an index, makes a CompactBindIndexSlice. If index is < 0, assumes means no indices, and just returns the empty slice + CompactBindIndexSlice makeCompactSlice(int index); + /// Given a list of indices, makes a CompactBindIndexSlice. Note does check for indices being unique and the order is maintained. /// Only >= 0 indices are valid - RegisterSet addRegisterSet(const int* indices, int numIndices); + CompactBindIndexSlice makeCompactSlice(const int* indices, int numIndices); - Slang::List<Binding> m_bindings; - Slang::List<SamplerDesc> m_samplerDescs; - Slang::List<uint16_t> m_indices; ///< Used to store lists of registers + Slang::List<Binding> m_bindings; ///< All of the bindings in order + Slang::List<SamplerDesc> m_samplerDescs; ///< Holds the SamplerDesc for the binding - indexed by the descIndex member of Binding + Slang::List<BindIndex> m_sharedBindIndices; ///< Used to store BindIndex slices that don't fit into CompactBindIndexSlice int m_numRenderTargets = 1; }; diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp new file mode 100644 index 000000000..c0cf982c9 --- /dev/null +++ b/tools/render-test/shader-renderer-util.cpp @@ -0,0 +1,200 @@ +// shader-renderer-util.cpp + +#include "shader-renderer-util.h" + +namespace renderer_test { + +using namespace Slang; + +/* static */Result ShaderRendererUtil::generateTextureResource(const InputTextureDesc& inputDesc, int bindFlags, Renderer* renderer, RefPtr<TextureResource>& textureOut) +{ + TextureData texData; + generateTextureData(texData, inputDesc); + return createTextureResource(inputDesc, texData, bindFlags, renderer, textureOut); +} + +/* static */Result ShaderRendererUtil::createTextureResource(const InputTextureDesc& inputDesc, const TextureData& texData, int bindFlags, Renderer* renderer, RefPtr<TextureResource>& textureOut) +{ + TextureResource::Desc textureResourceDesc; + textureResourceDesc.init(); + + textureResourceDesc.format = Format::RGBA_Unorm_UInt8; + textureResourceDesc.numMipLevels = texData.mipLevels; + textureResourceDesc.arraySize = inputDesc.arrayLength; + textureResourceDesc.bindFlags = bindFlags; + + // It's the same size in all dimensions + Resource::Type type = Resource::Type::Unknown; + switch (inputDesc.dimension) + { + case 1: + { + type = Resource::Type::Texture1D; + textureResourceDesc.size.init(inputDesc.size); + break; + } + case 2: + { + type = inputDesc.isCube ? Resource::Type::TextureCube : Resource::Type::Texture2D; + textureResourceDesc.size.init(inputDesc.size, inputDesc.size); + break; + } + case 3: + { + type = Resource::Type::Texture3D; + textureResourceDesc.size.init(inputDesc.size, inputDesc.size, inputDesc.size); + break; + } + } + + const int effectiveArraySize = textureResourceDesc.calcEffectiveArraySize(type); + const int numSubResources = textureResourceDesc.calcNumSubResources(type); + + Resource::Usage initialUsage = Resource::Usage::GenericRead; + TextureResource::Data initData; + + List<ptrdiff_t> mipRowStrides; + mipRowStrides.SetSize(textureResourceDesc.numMipLevels); + List<const void*> subResources; + subResources.SetSize(numSubResources); + + // Set up the src row strides + for (int i = 0; i < textureResourceDesc.numMipLevels; i++) + { + const int mipWidth = TextureResource::calcMipSize(textureResourceDesc.size.width, i); + mipRowStrides[i] = mipWidth * sizeof(uint32_t); + } + + // Set up pointers the the data + { + int subResourceIndex = 0; + const int numGen = int(texData.dataBuffer.Count()); + for (int i = 0; i < numSubResources; i++) + { + subResources[i] = texData.dataBuffer[subResourceIndex].Buffer(); + // Wrap around + subResourceIndex = (subResourceIndex + 1 >= numGen) ? 0 : (subResourceIndex + 1); + } + } + + initData.mipRowStrides = mipRowStrides.Buffer(); + initData.numMips = textureResourceDesc.numMipLevels; + initData.numSubResources = numSubResources; + initData.subResources = subResources.Buffer(); + + textureOut = renderer->createTextureResource(type, Resource::Usage::GenericRead, textureResourceDesc, &initData); + + return textureOut ? SLANG_OK : SLANG_FAIL; +} + +/* static */Result ShaderRendererUtil::createBufferResource(const InputBufferDesc& inputDesc, bool isOutput, size_t bufferSize, const void* initData, Renderer* renderer, Slang::RefPtr<BufferResource>& bufferOut) +{ + Resource::Usage initialUsage = Resource::Usage::GenericRead; + + BufferResource::Desc srcDesc; + srcDesc.init(bufferSize); + + int bindFlags = 0; + if (inputDesc.type == InputBufferType::ConstantBuffer) + { + bindFlags |= Resource::BindFlag::ConstantBuffer; + srcDesc.cpuAccessFlags |= Resource::AccessFlag::Write; + initialUsage = Resource::Usage::ConstantBuffer; + } + else + { + bindFlags |= Resource::BindFlag::UnorderedAccess | Resource::BindFlag::PixelShaderResource | Resource::BindFlag::NonPixelShaderResource; + srcDesc.elementSize = inputDesc.stride; + initialUsage = Resource::Usage::UnorderedAccess; + } + + if (isOutput) + { + srcDesc.cpuAccessFlags |= Resource::AccessFlag::Read; + } + + srcDesc.bindFlags = bindFlags; + + RefPtr<BufferResource> bufferResource = renderer->createBufferResource(initialUsage, srcDesc, initData); + if (!bufferResource) + { + return SLANG_FAIL; + } + + bufferOut = bufferResource; + return SLANG_OK; +} + +static BindingState::SamplerDesc _calcSamplerDesc(const InputSamplerDesc& srcDesc) +{ + BindingState::SamplerDesc dstDesc; + dstDesc.isCompareSampler = srcDesc.isCompareSampler; + return dstDesc; +} + +/* static */Result ShaderRendererUtil::createBindingStateDesc(ShaderInputLayoutEntry* srcEntries, int numEntries, Renderer* renderer, BindingState::Desc& descOut) +{ + const int textureBindFlags = Resource::BindFlag::NonPixelShaderResource | Resource::BindFlag::PixelShaderResource; + + descOut.clear(); + for (int i = 0; i < numEntries; i++) + { + const ShaderInputLayoutEntry& srcEntry = srcEntries[i]; + + BindingState::ShaderBindSet shaderBindSet; + shaderBindSet.set(BindingState::ShaderStyle::Hlsl, descOut.makeCompactSlice(srcEntry.hlslBinding)); + shaderBindSet.set(BindingState::ShaderStyle::Glsl, descOut.makeCompactSlice(srcEntry.glslBinding.Buffer(), int(srcEntry.glslBinding.Count()))); + + switch (srcEntry.type) + { + case ShaderInputType::Buffer: + { + const InputBufferDesc& srcBuffer = srcEntry.bufferDesc; + + const size_t bufferSize = srcEntry.bufferData.Count() * sizeof(uint32_t); + + RefPtr<BufferResource> bufferResource; + SLANG_RETURN_ON_FAIL(createBufferResource(srcEntry.bufferDesc, srcEntry.isOutput, bufferSize, srcEntry.bufferData.Buffer(), renderer, bufferResource)); + + descOut.addBufferResource(bufferResource, shaderBindSet); + break; + } + case ShaderInputType::CombinedTextureSampler: + { + RefPtr<TextureResource> texture; + SLANG_RETURN_ON_FAIL(generateTextureResource(srcEntry.textureDesc, textureBindFlags, renderer, texture)); + descOut.addCombinedTextureSampler(texture, _calcSamplerDesc(srcEntry.samplerDesc), shaderBindSet); + break; + } + case ShaderInputType::Texture: + { + RefPtr<TextureResource> texture; + SLANG_RETURN_ON_FAIL(generateTextureResource(srcEntry.textureDesc, textureBindFlags, renderer, texture)); + + descOut.addTextureResource(texture, shaderBindSet); + break; + } + case ShaderInputType::Sampler: + { + descOut.addSampler(_calcSamplerDesc(srcEntry.samplerDesc), shaderBindSet); + break; + } + default: + { + assert(!"Unhandled type"); + return SLANG_FAIL; + } + } + } + + return SLANG_OK; +} + +/* static */Result ShaderRendererUtil::createBindingStateDesc(const ShaderInputLayout& layout, Renderer* renderer, BindingState::Desc& descOut) +{ + SLANG_RETURN_ON_FAIL(createBindingStateDesc(layout.entries.Buffer(), int(layout.entries.Count()), renderer, descOut)); + descOut.m_numRenderTargets = layout.numRenderTargets; + return SLANG_OK; +} + +} // renderer_test diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h new file mode 100644 index 000000000..b481d52db --- /dev/null +++ b/tools/render-test/shader-renderer-util.h @@ -0,0 +1,27 @@ +// shader-renderer-util.h +#pragma once + +#include "render.h" +#include "shader-input-layout.h" + +namespace renderer_test { + +/// 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, Renderer* renderer, Slang::RefPtr<TextureResource>& 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, Renderer* renderer, Slang::RefPtr<TextureResource>& textureOut); + + /// Create the BufferResource using the renderer from the contents of inputDesc + static Slang::Result createBufferResource(const InputBufferDesc& inputDesc, bool isOutput, size_t bufferSize, const void* initData, Renderer* renderer, Slang::RefPtr<BufferResource>& bufferOut); + + /// Create BindingState::Desc from the contents of layout + static Slang::Result createBindingStateDesc(const ShaderInputLayout& layout, Renderer* renderer, BindingState::Desc& descOut); + /// Create BindingState::Desc from a list of ShaderInputLayout entries + static Slang::Result createBindingStateDesc(ShaderInputLayoutEntry* srcEntries, int numEntries, Renderer* renderer, BindingState::Desc& descOut); +}; + +} // renderer_test diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index a9079b52c..094c306d1 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -174,255 +174,4 @@ ShaderCompiler* createSlangShaderCompiler( return result; } -SlangResult generateTextureResource(const InputTextureDesc& inputDesc, int bindFlags, Renderer* renderer, Slang::RefPtr<TextureResource>& textureOut) -{ - using namespace Slang; - - TextureData texData; - generateTextureData(texData, inputDesc); - - TextureResource::Desc textureResourceDesc; - textureResourceDesc.init(); - - textureResourceDesc.format = Format::RGBA_Unorm_UInt8; - textureResourceDesc.numMipLevels = texData.mipLevels; - textureResourceDesc.arraySize = inputDesc.arrayLength; - textureResourceDesc.bindFlags = bindFlags; - - // It's the same size in all dimensions - Resource::Type type = Resource::Type::Unknown; - switch (inputDesc.dimension) - { - case 1: - { - type = Resource::Type::Texture1D; - textureResourceDesc.size.init(inputDesc.size); - break; - } - case 2: - { - type = inputDesc.isCube ? Resource::Type::TextureCube : Resource::Type::Texture2D; - textureResourceDesc.size.init(inputDesc.size, inputDesc.size); - break; - } - case 3: - { - type = Resource::Type::Texture3D; - textureResourceDesc.size.init(inputDesc.size, inputDesc.size, inputDesc.size); - break; - } - } - - const int effectiveArraySize = textureResourceDesc.calcEffectiveArraySize(type); - const int numSubResources = textureResourceDesc.calcNumSubResources(type); - - Resource::Usage initialUsage = Resource::Usage::GenericRead; - TextureResource::Data initData; - - List<ptrdiff_t> mipRowStrides; - mipRowStrides.SetSize(textureResourceDesc.numMipLevels); - List<const void*> subResources; - subResources.SetSize(numSubResources); - - // Set up the src row strides - for (int i = 0; i < textureResourceDesc.numMipLevels; i++) - { - const int mipWidth = TextureResource::calcMipSize(textureResourceDesc.size.width, i); - mipRowStrides[i] = mipWidth * sizeof(uint32_t); - } - - // Set up pointers the the data - { - int subResourceIndex = 0; - const int numGen = int(texData.dataBuffer.Count()); - for (int i = 0; i < numSubResources; i++) - { - subResources[i] = texData.dataBuffer[subResourceIndex].Buffer(); - // Wrap around - subResourceIndex = (subResourceIndex + 1 >= numGen) ? 0 : (subResourceIndex + 1); - } - } - - initData.mipRowStrides = mipRowStrides.Buffer(); - initData.numMips = textureResourceDesc.numMipLevels; - initData.numSubResources = numSubResources; - initData.subResources = subResources.Buffer(); - - textureOut = renderer->createTextureResource(type, Resource::Usage::GenericRead, textureResourceDesc, &initData); - - return textureOut ? SLANG_OK : SLANG_FAIL; -} - -SlangResult createInputBufferResource(const InputBufferDesc& inputDesc, bool isOutput, size_t bufferSize, const void* initData, Renderer* renderer, Slang::RefPtr<BufferResource>& bufferOut) -{ - using namespace Slang; - - Resource::Usage initialUsage = Resource::Usage::GenericRead; - - BufferResource::Desc srcDesc; - srcDesc.init(bufferSize); - - int bindFlags = 0; - if (inputDesc.type == InputBufferType::ConstantBuffer) - { - bindFlags |= Resource::BindFlag::ConstantBuffer; - srcDesc.cpuAccessFlags |= Resource::AccessFlag::Write; - initialUsage = Resource::Usage::ConstantBuffer; - } - else - { - bindFlags |= Resource::BindFlag::UnorderedAccess | Resource::BindFlag::PixelShaderResource | Resource::BindFlag::NonPixelShaderResource; - srcDesc.elementSize = inputDesc.stride; - initialUsage = Resource::Usage::UnorderedAccess; - } - - if (isOutput) - { - srcDesc.cpuAccessFlags |= Resource::AccessFlag::Read; - } - - srcDesc.bindFlags = bindFlags; - - RefPtr<BufferResource> bufferResource = renderer->createBufferResource(initialUsage, srcDesc, initData); - if (!bufferResource) - { - return SLANG_FAIL; - } - - bufferOut = bufferResource; - return SLANG_OK; -} - -static BindingState::SamplerDesc _calcSamplerDesc(const InputSamplerDesc& srcDesc) -{ - BindingState::SamplerDesc dstDesc; - dstDesc.isCompareSampler = srcDesc.isCompareSampler; - return dstDesc; -} - -SlangResult createBindingStateDesc(ShaderInputLayoutEntry* srcEntries, int numEntries, Renderer* renderer, BindingState::Desc& descOut) -{ - using namespace Slang; - - const int textureBindFlags = Resource::BindFlag::NonPixelShaderResource | Resource::BindFlag::PixelShaderResource; - - descOut.clear(); - for (int i = 0; i < numEntries; i++) - { - const ShaderInputLayoutEntry& srcEntry = srcEntries[i]; - - BindingState::RegisterDesc registerDesc; - registerDesc.registerSets[int(BindingState::ShaderStyle::Hlsl)] = descOut.addRegisterSet(srcEntry.hlslBinding); - registerDesc.registerSets[int(BindingState::ShaderStyle::Glsl)] = descOut.addRegisterSet(srcEntry.glslBinding.Buffer(), int(srcEntry.glslBinding.Count())); - - switch (srcEntry.type) - { - case ShaderInputType::Buffer: - { - const InputBufferDesc& srcBuffer = srcEntry.bufferDesc; - - const size_t bufferSize = srcEntry.bufferData.Count() * sizeof(uint32_t); - - RefPtr<BufferResource> bufferResource; - SLANG_RETURN_ON_FAIL(createInputBufferResource(srcEntry.bufferDesc, srcEntry.isOutput, bufferSize, srcEntry.bufferData.Buffer(), renderer, bufferResource)); - - descOut.addBufferResource(bufferResource, registerDesc); - break; - } - case ShaderInputType::CombinedTextureSampler: - { - RefPtr<TextureResource> texture; - SLANG_RETURN_ON_FAIL(generateTextureResource(srcEntry.textureDesc, textureBindFlags, renderer, texture)); - descOut.addCombinedTextureSampler(texture, _calcSamplerDesc(srcEntry.samplerDesc), registerDesc); - break; - } - case ShaderInputType::Texture: - { - RefPtr<TextureResource> texture; - SLANG_RETURN_ON_FAIL(generateTextureResource(srcEntry.textureDesc, textureBindFlags, renderer, texture)); - - descOut.addTextureResource(texture, registerDesc); - break; - } - case ShaderInputType::Sampler: - { - descOut.addSampler(_calcSamplerDesc(srcEntry.samplerDesc), registerDesc); - break; - } - default: - { - assert(!"Unhandled type"); - return SLANG_FAIL; - } - } - } - - return SLANG_OK; -} - -SlangResult createBindingStateDesc(const ShaderInputLayout& layout, Renderer* renderer, BindingState::Desc& descOut) -{ - SLANG_RETURN_ON_FAIL(createBindingStateDesc(layout.entries.Buffer(), int(layout.entries.Count()), renderer, descOut)); - descOut.m_numRenderTargets = layout.numRenderTargets; - - return SLANG_OK; -} - -SlangResult serializeBindingOutput(const ShaderInputLayout& layout, BindingState* bindingState, Renderer* renderer, const char* fileName) -{ - // Submit the work - renderer->submitGpuWork(); - // Wait until everything is complete - renderer->waitForGpu(); - - FILE * f = fopen(fileName, "wb"); - if (!f) - { - return SLANG_FAIL; - } - - const BindingState::Desc& bindingStateDesc = bindingState->getDesc(); - // Must be the same amount of entries - assert(bindingStateDesc.m_bindings.Count() == layout.entries.Count()); - - const int numBindings = int(bindingStateDesc.m_bindings.Count()); - - for (int i = 0; i < numBindings; ++i) - { - const auto& layoutBinding = layout.entries[i]; - const auto& binding = bindingStateDesc.m_bindings[i]; - - if (layoutBinding.isOutput) - { - if (binding.resource && binding.resource->isBuffer()) - { - BufferResource* bufferResource = static_cast<BufferResource*>(binding.resource.Ptr()); - const size_t bufferSize = bufferResource->getDesc().sizeInBytes; - - unsigned int* ptr = (unsigned int*)renderer->map(bufferResource, MapFlavor::HostRead); - if (!ptr) - { - fclose(f); - return SLANG_FAIL; - } - - const int size = int(bufferSize / sizeof(unsigned int)); - for (int i = 0; i < size; ++i) - { - fprintf(f, "%X\n", ptr[i]); - } - renderer->unmap(bufferResource); - } - else - { - printf("invalid output type at %d.\n", i); - } - } - } - fclose(f); - - return SLANG_OK; -} - - } // renderer_test diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h index 67d2a2880..c24b0e2e6 100644 --- a/tools/render-test/slang-support.h +++ b/tools/render-test/slang-support.h @@ -14,18 +14,4 @@ ShaderCompiler* createSlangShaderCompiler( SlangSourceLanguage sourceLanguage, SlangCompileTarget target); - /// Create the texture resource using the renderer -SlangResult generateTextureResource(const InputTextureDesc& inputDesc, int bindFlags, Renderer* renderer, Slang::RefPtr<TextureResource>& textureOut); - - /// Create the buffer resource using the renderer -SlangResult createInputBufferResource(const InputBufferDesc& inputDesc, bool isOutput, size_t bufferSize, const void* initData, Renderer* renderer, Slang::RefPtr<BufferResource>& bufferOut); - -SlangResult createBindingStateDesc(ShaderInputLayoutEntry* srcEntries, int numEntries, Renderer* renderer, BindingState::Desc& descOut); - - /// Create binding set from the layout -SlangResult createBindingStateDesc(const ShaderInputLayout& layout, Renderer* renderer, BindingState::Desc& descOut); - - /// Write out the contents of buffers marked as output in layout to file with 'filename' -SlangResult serializeBindingOutput(const ShaderInputLayout& layout, BindingState* bindingState, Renderer* renderer, const char* fileName); - } // renderer_test |
