diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cb677245..b5b00179a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +v3.0.4 +------ +- Updated Slang to 0.10.24 +- Added an option to create a `Program` from a string +- Added `CopyContext::updateSubresourceData()` which allows updating a region of a subresource +- Added `Program::Desc` has a new function - `setShaderModel()`. It allows the user to request shader-model 6.x, which will use dxcompiler instead of FXC +- Added support for double-quotes when parsing command line arguments. Text surrounded by double-quotes will be considered a single argument. + v3.0.3 ------ - Added FXAA as an effect diff --git a/Framework/BuildScripts/movedata.bat b/Framework/BuildScripts/movedata.bat index 338e9cace..3cd77b5eb 100644 --- a/Framework/BuildScripts/movedata.bat +++ b/Framework/BuildScripts/movedata.bat @@ -34,11 +34,12 @@ call %1\BuildScripts\moveprojectdata.bat %3 %DestinationDirectory% /r:0 >nul rem copy or clear the DXR DLLs if "%8%"=="FALCOR_DXR" ( robocopy %ExternalsSourceDirectory%\DXR\bin\x64 %DestinationDirectory% *.dll /r:0 >nul + del %DestinationDirectory%\dxil.dll >nul ) ELSE ( del %DestinationDirectory%\d3d12.dll >nul del %DestinationDirectory%\d3d12SDKLayers.dll >nul - del %DestinationDirectory%\dxcompiler.dll >nul del %DestinationDirectory%\dxgidebug.dll >nul + robocopy %ExternalsSourceDirectory%\dxcompiler\x64\ %DestinationDirectory% *.dll /r:0 >nul ) rem robocopy sets the error level to something that is not zero even if the copy operation was successful. Set the error level to zero diff --git a/Framework/Source/API/CopyContext.cpp b/Framework/Source/API/CopyContext.cpp index ef8203fbc..ffb3e92e6 100644 --- a/Framework/Source/API/CopyContext.cpp +++ b/Framework/Source/API/CopyContext.cpp @@ -57,17 +57,6 @@ namespace Falcor mpLowLevelData->getFence()->syncCpu(); } } - - void CopyContext::updateTexture(const Texture* pTexture, const void* pData) - { - mCommandsPending = true; - uint32_t subresourceCount = pTexture->getArraySize() * pTexture->getMipCount(); - if (pTexture->getType() == Texture::Type::TextureCube) - { - subresourceCount *= 6; - } - updateTextureSubresources(pTexture, 0, subresourceCount, pData); - } CopyContext::ReadTextureTask::SharedPtr CopyContext::asyncReadTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex) { @@ -80,8 +69,6 @@ namespace Falcor return pTask->getData(); } - - void CopyContext::resourceBarrier(const Resource* pResource, Resource::State newState, const ResourceViewInfo* pViewInfo) { const Texture* pTexture = dynamic_cast(pResource); @@ -141,4 +128,21 @@ namespace Falcor } if (setGlobal) pTexture->setGlobalState(newState); } + + void CopyContext::updateTextureData(const Texture* pTexture, const void* pData) + { + mCommandsPending = true; + uint32_t subresourceCount = pTexture->getArraySize() * pTexture->getMipCount(); + if (pTexture->getType() == Texture::Type::TextureCube) + { + subresourceCount *= 6; + } + updateTextureSubresources(pTexture, 0, subresourceCount, pData); + } + + void CopyContext::updateSubresourceData(const Texture* pDst, uint32_t subresource, const void* pData, const uvec3& offset, const uvec3& size) + { + mCommandsPending = true; + updateTextureSubresources(pDst, subresource, 1, pData, offset, size); + } } \ No newline at end of file diff --git a/Framework/Source/API/CopyContext.h b/Framework/Source/API/CopyContext.h index 77bac86ab..d6e5b1dd7 100644 --- a/Framework/Source/API/CopyContext.h +++ b/Framework/Source/API/CopyContext.h @@ -62,12 +62,6 @@ namespace Falcor }; static SharedPtr create(CommandQueueHandle queue); - void updateBuffer(const Buffer* pBuffer, const void* pData, size_t offset = 0, size_t numBytes = 0); - void updateTexture(const Texture* pTexture, const void* pData); - void updateTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex, const void* pData); - void updateTextureSubresources(const Texture* pTexture, uint32_t firstSubresource, uint32_t subresourceCount, const void* pData); - ReadTextureTask::SharedPtr asyncReadTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex); - std::vector readTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex); /** Flush the command list. This doesn't reset the command allocator, just submits the commands \param[in] wait If true, will block execution until the GPU finished processing the commands @@ -103,6 +97,33 @@ namespace Falcor */ void copyBufferRegion(const Buffer* pDst, uint64_t dstOffset, const Buffer* pSrc, uint64_t srcOffset, uint64_t numBytes); + /** Copy a region of a subresource from one texture to another + `srcOffset`, `dstOffset` and `size` describe the source and destination regions. For any channel of `extent` that is -1, the source texture dimension will be used + */ + void copySubresourceRegion(const Texture* pDst, uint32_t dstSubresource, const Texture* pSrc, uint32_t srcSubresource, const uvec3& dstOffset = uvec3(0), const uvec3& srcOffset = uvec3(0), const uvec3& size = uvec3(-1)); + + /** Update a texture's subresource data + `offset` and `size` describe a region to update. For any channel of `extent` that is -1, the texture dimension will be used. + pData can't be null. The size of the pointed buffer must be equal to a single texel size times the size of the region we are updating + */ + void updateSubresourceData(const Texture* pDst, uint32_t subresource, const void* pData, const uvec3& offset = uvec3(0), const uvec3& size = uvec3(-1)); + + /** Update an entire texture + */ + void updateTextureData(const Texture* pTexture, const void* pData); + + /** Update a buffer + */ + void updateBuffer(const Buffer* pBuffer, const void* pData, size_t offset = 0, size_t numBytes = 0); + + /** Read texture data synchronously. Calling this command will flush the pipeline and wait for the GPU to finish execution + */ + std::vector readTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex); + + /** Read texture data Asynchronously + */ + ReadTextureTask::SharedPtr asyncReadTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex); + /** Get the low-level context data */ virtual const LowLevelContextData::SharedPtr& getLowLevelData() const { return mpLowLevelData; } @@ -120,6 +141,8 @@ namespace Falcor void bufferBarrier(const Buffer* pBuffer, Resource::State newState); void subresourceBarriers(const Texture* pTexture, Resource::State newState, const ResourceViewInfo* pViewInfo); void apiSubresourceBarrier(const Texture* pTexture, Resource::State newState, Resource::State oldState, uint32_t arraySlice, uint32_t mipLevel); + void updateTextureSubresources(const Texture* pTexture, uint32_t firstSubresource, uint32_t subresourceCount, const void* pData, const uvec3& offset = uvec3(0), const uvec3& size = uvec3(-1)); + CopyContext() = default; bool mCommandsPending = false; LowLevelContextData::SharedPtr mpLowLevelData; diff --git a/Framework/Source/API/D3D12/D3D12CopyContext.cpp b/Framework/Source/API/D3D12/D3D12CopyContext.cpp index 516a1d3a5..7cf35d251 100644 --- a/Framework/Source/API/D3D12/D3D12CopyContext.cpp +++ b/Framework/Source/API/D3D12/D3D12CopyContext.cpp @@ -72,31 +72,50 @@ namespace Falcor } } - void CopyContext::updateTextureSubresources(const Texture* pTexture, uint32_t firstSubresource, uint32_t subresourceCount, const void* pData) + void CopyContext::updateTextureSubresources(const Texture* pTexture, uint32_t firstSubresource, uint32_t subresourceCount, const void* pData, const uvec3& offset, const uvec3& size) { + bool copyRegion = (offset != uvec3(0)) || (size != uvec3(-1)); + assert(subresourceCount == 1 || (copyRegion == false)); + mCommandsPending = true; uint32_t arraySize = (pTexture->getType() == Texture::Type::TextureCube) ? pTexture->getArraySize() * 6 : pTexture->getArraySize(); assert(firstSubresource + subresourceCount <= arraySize * pTexture->getMipCount()); - ID3D12Device* pDevice = gpDevice->getApiHandle(); - // Get the footprint D3D12_RESOURCE_DESC texDesc = pTexture->getApiHandle()->GetDesc(); std::vector footprint(subresourceCount); std::vector rowCount(subresourceCount); std::vector rowSize(subresourceCount); - uint64_t size; - pDevice->GetCopyableFootprints(&texDesc, firstSubresource, subresourceCount, 0, footprint.data(), rowCount.data(), rowSize.data(), &size); + uint64_t bufferSize; + + if (copyRegion) + { + footprint[0].Offset = 0; + footprint[0].Footprint.Format = getDxgiFormat(pTexture->getFormat()); + uint32_t mipLevel = pTexture->getSubresourceMipLevel(firstSubresource); + footprint[0].Footprint.Width = (size.x == -1) ? pTexture->getWidth(mipLevel) - offset.x : size.x; + footprint[0].Footprint.Height = (size.y == -1) ? pTexture->getHeight(mipLevel) - offset.y : size.y; + footprint[0].Footprint.Depth = (size.z == -1) ? pTexture->getDepth(mipLevel) - offset.z : size.z; + footprint[0].Footprint.RowPitch = footprint[0].Footprint.Width * getFormatBytesPerBlock(pTexture->getFormat()); + rowCount[0] = footprint[0].Footprint.Height; + rowSize[0] = footprint[0].Footprint.RowPitch; + bufferSize = rowSize[0] * rowCount[0] * footprint[0].Footprint.Depth; + } + else + { + ID3D12Device* pDevice = gpDevice->getApiHandle(); + pDevice->GetCopyableFootprints(&texDesc, firstSubresource, subresourceCount, 0, footprint.data(), rowCount.data(), rowSize.data(), &bufferSize); + } // Allocate a buffer on the upload heap - Buffer::SharedPtr pBuffer = Buffer::create(size, Buffer::BindFlags::None, Buffer::CpuAccess::Write, nullptr); + Buffer::SharedPtr pBuffer = Buffer::create(bufferSize, Buffer::BindFlags::None, Buffer::CpuAccess::Write, nullptr); // Map the buffer uint8_t* pDst = (uint8_t*)pBuffer->map(Buffer::MapType::WriteDiscard); ID3D12ResourcePtr pResource = pBuffer->getApiHandle(); // Get the offset from the beginning of the resource - uint64_t offset = pBuffer->getGpuAddressOffset(); + uint64_t vaOffset = pBuffer->getGpuAddressOffset(); resourceBarrier(pTexture, Resource::State::CopyDest); const uint8_t* pSrc = (uint8_t*)pData; @@ -113,22 +132,17 @@ namespace Falcor pSrc = (uint8_t*)pSrc + footprint[s].Footprint.Depth * src.SlicePitch; // Dispatch a command - footprint[s].Offset += offset; + footprint[s].Offset += vaOffset; uint32_t subresource = s + firstSubresource; D3D12_TEXTURE_COPY_LOCATION dstLoc = { pTexture->getApiHandle(), D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, subresource }; D3D12_TEXTURE_COPY_LOCATION srcLoc = { pResource, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, footprint[s] }; - mpLowLevelData->getCommandList()->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); + + mpLowLevelData->getCommandList()->CopyTextureRegion(&dstLoc, offset.x, offset.y, offset.z, &srcLoc, nullptr); } pBuffer->unmap(); } - void CopyContext::updateTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex, const void* pData) - { - mCommandsPending = true; - updateTextureSubresources(pTexture, subresourceIndex, 1, pData); - } - CopyContext::ReadTextureTask::SharedPtr CopyContext::ReadTextureTask::create(CopyContext::SharedPtr pCtx, const Texture* pTexture, uint32_t subresourceIndex) { SharedPtr pThis = SharedPtr(new ReadTextureTask); @@ -278,4 +292,33 @@ namespace Falcor mpLowLevelData->getCommandList()->CopyBufferRegion(pDst->getApiHandle(), dstOffset, pSrc->getApiHandle(), pSrc->getGpuAddressOffset() + srcOffset, numBytes); mCommandsPending = true; } + + void CopyContext::copySubresourceRegion(const Texture* pDst, uint32_t dstSubresource, const Texture* pSrc, uint32_t srcSubresource, const uvec3& dstOffset, const uvec3& srcOffset, const uvec3& size) + { + resourceBarrier(pDst, Resource::State::CopyDest); + resourceBarrier(pSrc, Resource::State::CopySource); + + D3D12_TEXTURE_COPY_LOCATION dstLoc = {}; + dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLoc.SubresourceIndex = dstSubresource; + dstLoc.pResource = pDst->getApiHandle(); + + D3D12_TEXTURE_COPY_LOCATION srcLoc = {}; + srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcLoc.SubresourceIndex = srcSubresource; + srcLoc.pResource = pSrc->getApiHandle(); + + D3D12_BOX box; + box.left = srcOffset.x; + box.top = srcOffset.y; + box.front = srcOffset.z; + uint32_t mipLevel = pSrc->getSubresourceMipLevel(dstSubresource); + box.right = (size.x == -1) ? pSrc->getWidth(mipLevel) - box.left : size.x; + box.bottom = (size.y == -1) ? pSrc->getHeight(mipLevel) - box.top : size.y; + box.back = (size.z == -1) ? pSrc->getDepth(mipLevel) - box.front : size.z; + + mpLowLevelData->getCommandList()->CopyTextureRegion(&dstLoc, dstOffset.x, dstOffset.y, dstOffset.z, &srcLoc, &box); + + mCommandsPending = true; + } } \ No newline at end of file diff --git a/Framework/Source/API/D3D12/D3DShader.cpp b/Framework/Source/API/D3D12/D3DShader.cpp index 00db935ce..c263fc847 100644 --- a/Framework/Source/API/D3D12/D3DShader.cpp +++ b/Framework/Source/API/D3D12/D3DShader.cpp @@ -36,22 +36,22 @@ namespace Falcor ID3DBlobPtr pBlob; }; - const char* getTargetString(ShaderType type) + std::string getTargetString(ShaderType type, const std::string& shaderModel) { switch (type) { case ShaderType::Vertex: - return "vs_5_1"; + return "vs_" + shaderModel; case ShaderType::Pixel: - return "ps_5_1"; + return "ps_" + shaderModel; case ShaderType::Hull: - return "hs_5_1"; + return "hs_" + shaderModel; case ShaderType::Domain: - return "ds_5_1"; + return "ds_" + shaderModel; case ShaderType::Geometry: - return "gs_5_1"; + return "gs_" + shaderModel; case ShaderType::Compute: - return "cs_5_1"; + return "cs_" + shaderModel; default: should_not_get_here(); return ""; @@ -60,13 +60,11 @@ namespace Falcor struct SlangBlob : ID3DBlob { - void* buffer; - size_t bufferSize; + std::vector data; size_t refCount; - SlangBlob(void* buffer, size_t bufferSize) - : buffer(buffer) - , bufferSize(bufferSize) + SlangBlob(const void* buffer, size_t bufferSize) + : data((uint8_t*)buffer, ((uint8_t*)buffer) + bufferSize) , refCount(1) {} @@ -100,12 +98,12 @@ namespace Falcor virtual LPVOID STDMETHODCALLTYPE GetBufferPointer() override { - return buffer; + return data.data(); } virtual SIZE_T STDMETHODCALLTYPE GetBufferSize() override { - return bufferSize; + return data.size(); } }; @@ -122,29 +120,36 @@ namespace Falcor ID3DBlobPtr Shader::compile(const Blob& blob, const std::string& entryPointName, CompilerFlags flags, std::string& errorLog) { - ID3DBlob* pCode; - ID3DBlobPtr pErrors; - - UINT d3dFlags = getD3dCompilerFlags(flags); - - HRESULT hr = D3DCompile( - blob.data.data(), - blob.data.size(), - nullptr, - nullptr, - nullptr, - entryPointName.c_str(), - getTargetString(mType), - d3dFlags, - 0, - &pCode, - &pErrors); - if(FAILED(hr)) + ID3DBlob* pCode = nullptr; + + if (blob.type == Blob::Type::String) { - errorLog = convertBlobToString(pErrors.GetInterfacePtr()); - return nullptr; + ID3DBlobPtr pErrors; + UINT d3dFlags = getD3dCompilerFlags(flags); + + HRESULT hr = D3DCompile( + blob.data.data(), + blob.data.size(), + nullptr, + nullptr, + nullptr, + entryPointName.c_str(), + getTargetString(mType, blob.shaderModel).c_str(), + d3dFlags, + 0, + &pCode, + &pErrors); + if (FAILED(hr)) + { + errorLog = convertBlobToString(pErrors.GetInterfacePtr()); + return nullptr; + } + } + else + { + assert(blob.type == Blob::Type::Bytecode); + pCode = new SlangBlob(blob.data.data(), blob.data.size()); } - return pCode; } @@ -161,11 +166,6 @@ namespace Falcor bool Shader::init(const Blob& shaderBlob, const std::string& entryPointName, CompilerFlags flags, std::string& log) { - if (shaderBlob.type != Blob::Type::String) - { - logError("D3D shader compilation only supports string inputs"); - return false; - } // Compile the shader ShaderData* pData = (ShaderData*)mpPrivateData; pData->pBlob = compile(shaderBlob, entryPointName, flags, log); diff --git a/Framework/Source/API/Shader.h b/Framework/Source/API/Shader.h index 80111a128..b674e2327 100644 --- a/Framework/Source/API/Shader.h +++ b/Framework/Source/API/Shader.h @@ -52,6 +52,7 @@ namespace Falcor }; std::vector data; Type type = Type::Undefined; + std::string shaderModel; }; enum class CompilerFlags diff --git a/Framework/Source/API/Texture.cpp b/Framework/Source/API/Texture.cpp index 96549d248..059c74a17 100644 --- a/Framework/Source/API/Texture.cpp +++ b/Framework/Source/API/Texture.cpp @@ -150,13 +150,13 @@ namespace Falcor for (uint32_t i = 0; i < mArraySize * numFaces; i++) { uint32_t subresource = getSubresourceIndex(i, 0); - pRenderContext->updateTextureSubresource(this, subresource, pSrc); + pRenderContext->updateSubresourceData(this, subresource, pSrc); pSrc += arraySliceSize; } } else { - pRenderContext->updateTexture(this, pData); + pRenderContext->updateTextureData(this, pData); } if (autoGenMips) diff --git a/Framework/Source/API/Texture.h b/Framework/Source/API/Texture.h index 5e7f54067..bfc007cd5 100644 --- a/Framework/Source/API/Texture.h +++ b/Framework/Source/API/Texture.h @@ -175,21 +175,9 @@ namespace Falcor */ const std::string& getSourceFilename() const { return mSourceFilename; } - void copySubresource(const Texture* pDst, uint32_t srcMipLevel, uint32_t srcArraySlice, uint32_t dstMipLevel, uint32_t dstArraySlice) const; - - /** If the texture has been created as using sparse storage, makes individual physically pages resident and non-resident. - * Use page index. - */ - void setSparseResidencyPageIndex(bool isResident, uint32_t mipLevel, uint32_t pageX, uint32_t pageY, uint32_t pageZ, uint32_t width = 1, uint32_t height = 1, uint32_t depth = 1); - - /** If the texture has been created as using sparse storage, makes individual physically pages resident and non-resident. - */ - glm::i32vec3 getSparseResidencyPageSize(); - protected: friend class Device; void apinit(const void* pData, bool autoGenMips); - void apiSetName(); void uploadInitData(const void* pData, bool autoGenMips); bool mReleaseRtvsAfterGenMips = true; static RtvHandle spNullRTV; diff --git a/Framework/Source/API/Vulkan/VKCopyContext.cpp b/Framework/Source/API/Vulkan/VKCopyContext.cpp index 7690cf09b..784673f3d 100644 --- a/Framework/Source/API/Vulkan/VKCopyContext.cpp +++ b/Framework/Source/API/Vulkan/VKCopyContext.cpp @@ -45,21 +45,14 @@ namespace Falcor return flags; } - static uint32_t getMipLevelPackedDataSize(const Texture* pTexture, uint32_t mipLevel) + static uint32_t getMipLevelPackedDataSize(const Texture* pTexture, uint32_t w, uint32_t h, uint32_t d, ResourceFormat format) { - assert(mipLevel < pTexture->getMipCount()); - ResourceFormat format = pTexture->getFormat(); - - uint32_t w = pTexture->getWidth(mipLevel); uint32_t perW = getFormatWidthCompressionRatio(format); uint32_t bw = align_to(perW, w) / perW; - uint32_t h = pTexture->getHeight(mipLevel); uint32_t perH = getFormatHeightCompressionRatio(format); uint32_t bh = align_to(perH, h) / perH; - uint32_t d = pTexture->getDepth(mipLevel); - uint32_t size = bh * bw * d * getFormatBytesPerBlock(format); return size; } @@ -172,54 +165,58 @@ namespace Falcor { } - void CopyContext::updateTextureSubresources(const Texture* pTexture, uint32_t firstSubresource, uint32_t subresourceCount, const void* pData) - { - mCommandsPending = true; - const uint8_t* pSubResData = (uint8_t*)pData; - for (uint32_t i = 0; i < subresourceCount; i++) - { - uint32_t subresource = i + firstSubresource; - updateTextureSubresource(pTexture, subresource, pSubResData); - uint32_t mipLevel = pTexture->getSubresourceMipLevel(subresource); - uint32_t offset = getMipLevelPackedDataSize(pTexture, mipLevel); - pSubResData += offset; - } - } - - void initTexAccessParams(const Texture* pTexture, uint32_t subresourceIndex, VkBufferImageCopy& vkCopy, Buffer::SharedPtr& pStaging, const void* pSrcData, size_t& dataSize) + static void initTexAccessParams(const Texture* pTexture, uint32_t subresourceIndex, VkBufferImageCopy& vkCopy, Buffer::SharedPtr& pStaging, const void* pSrcData, const uvec3& offset, const uvec3& size, size_t& dataSize) { assert(isDepthStencilFormat(pTexture->getFormat()) == false); // #VKTODO Nothing complicated here, just that Vulkan doesn't support writing to both depth and stencil, which may be confusing to the user uint32_t mipLevel = pTexture->getSubresourceMipLevel(subresourceIndex); - dataSize = getMipLevelPackedDataSize(pTexture, mipLevel); - - // Upload the data to a staging buffer - pStaging = Buffer::create(dataSize, Buffer::BindFlags::None, pSrcData ? Buffer::CpuAccess::Write : Buffer::CpuAccess::Read, pSrcData); vkCopy = {}; - vkCopy.bufferOffset = pStaging->getGpuAddressOffset(); vkCopy.bufferRowLength = 0; vkCopy.bufferImageHeight = 0; vkCopy.imageSubresource.aspectMask = getAspectFlagsFromFormat(pTexture->getFormat()); vkCopy.imageSubresource.baseArrayLayer = pTexture->getSubresourceArraySlice(subresourceIndex); vkCopy.imageSubresource.layerCount = 1; vkCopy.imageSubresource.mipLevel = mipLevel; - vkCopy.imageExtent.width = pTexture->getWidth(mipLevel); - vkCopy.imageExtent.height = pTexture->getHeight(mipLevel); - vkCopy.imageExtent.depth = pTexture->getDepth(mipLevel); + vkCopy.imageOffset = { (int32_t)offset.x, (int32_t)offset.y, (int32_t)offset.z }; + vkCopy.imageExtent.width = (size.x == -1) ? pTexture->getWidth(mipLevel) - offset.x : size.x; + vkCopy.imageExtent.height = (size.y == -1) ? pTexture->getHeight(mipLevel) - offset.y : size.y; + vkCopy.imageExtent.depth = (size.z == -1) ? pTexture->getDepth(mipLevel) - offset.z : size.z; + + dataSize = getMipLevelPackedDataSize(pTexture, vkCopy.imageExtent.width, vkCopy.imageExtent.height, vkCopy.imageExtent.depth, pTexture->getFormat()); + + // Upload the data to a staging buffer + pStaging = Buffer::create(dataSize, Buffer::BindFlags::None, pSrcData ? Buffer::CpuAccess::Write : Buffer::CpuAccess::Read, pSrcData); + vkCopy.bufferOffset = pStaging->getGpuAddressOffset(); } - - void CopyContext::updateTextureSubresource(const Texture* pTexture, uint32_t subresourceIndex, const void* pData) + + static void updateTextureSubresource(CopyContext* pCtx, const Texture* pTexture, uint32_t subresourceIndex, const void* pData, const uvec3& offset, const uvec3& size) { - mCommandsPending = true; VkBufferImageCopy vkCopy; Buffer::SharedPtr pStaging; size_t dataSize; - initTexAccessParams(pTexture, subresourceIndex, vkCopy, pStaging, pData, dataSize); + initTexAccessParams(pTexture, subresourceIndex, vkCopy, pStaging, pData, offset, size, dataSize); // Execute the copy - resourceBarrier(pTexture, Resource::State::CopyDest); - resourceBarrier(pStaging.get(), Resource::State::CopySource); - vkCmdCopyBufferToImage(mpLowLevelData->getCommandList(), pStaging->getApiHandle(), pTexture->getApiHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkCopy); + pCtx->resourceBarrier(pTexture, Resource::State::CopyDest); + pCtx->resourceBarrier(pStaging.get(), Resource::State::CopySource); + vkCmdCopyBufferToImage(pCtx->getLowLevelData()->getCommandList(), pStaging->getApiHandle(), pTexture->getApiHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkCopy); + } + + void CopyContext::updateTextureSubresources(const Texture* pTexture, uint32_t firstSubresource, uint32_t subresourceCount, const void* pData, const uvec3& offset, const uvec3& size) + { + bool copyRegion = (offset != uvec3(0)) || (size != uvec3(-1)); + assert(subresourceCount == 1 || (copyRegion == false)); + + mCommandsPending = true; + const uint8_t* pSubResData = (uint8_t*)pData; + for (uint32_t i = 0; i < subresourceCount; i++) + { + uint32_t subresource = i + firstSubresource; + updateTextureSubresource(this, pTexture, subresource, pSubResData, offset, size); + uint32_t mipLevel = pTexture->getSubresourceMipLevel(subresource); + uint32_t offset = getMipLevelPackedDataSize(pTexture, pTexture->getWidth(mipLevel), pTexture->getHeight(mipLevel), pTexture->getDepth(mipLevel), pTexture->getFormat()); + pSubResData += offset; + } } CopyContext::ReadTextureTask::SharedPtr CopyContext::ReadTextureTask::create(CopyContext::SharedPtr pCtx, const Texture* pTexture, uint32_t subresourceIndex) @@ -228,7 +225,7 @@ namespace Falcor pThis->mpContext = pCtx; VkBufferImageCopy vkCopy; - initTexAccessParams(pTexture, subresourceIndex, vkCopy, pThis->mpBuffer, nullptr, pThis->mDataSize); + initTexAccessParams(pTexture, subresourceIndex, vkCopy, pThis->mpBuffer, nullptr, {}, uvec3(-1, -1, -1), pThis->mDataSize); // Execute the copy pCtx->resourceBarrier(pTexture, Resource::State::CopySource); @@ -413,4 +410,36 @@ namespace Falcor vkCmdCopyBuffer(mpLowLevelData->getCommandList(), pSrc->getApiHandle(), pDst->getApiHandle(), 1, ®ion); mCommandsPending = true; } + + void CopyContext::copySubresourceRegion(const Texture* pDst, uint32_t dstSubresource, const Texture* pSrc, uint32_t srcSubresource, const uvec3& dstOffset, const uvec3& srcOffset, const uvec3& size) + { + resourceBarrier(pDst, Resource::State::CopyDest); + resourceBarrier(pSrc, Resource::State::CopySource); + + VkImageCopy region = {}; + // Source subresource + region.srcSubresource.layerCount = 1; + region.srcSubresource.baseArrayLayer = pSrc->getSubresourceArraySlice(srcSubresource); + region.srcSubresource.mipLevel = pSrc->getSubresourceMipLevel(srcSubresource); + region.srcSubresource.aspectMask = getAspectFlagsFromFormat(pSrc->getFormat()); + + // Dst subresource + region.dstSubresource.layerCount = 1; + region.dstSubresource.baseArrayLayer = pDst->getSubresourceArraySlice(dstSubresource); + region.dstSubresource.mipLevel = pDst->getSubresourceMipLevel(dstSubresource); + region.dstSubresource.aspectMask = getAspectFlagsFromFormat(pDst->getFormat()); + + region.dstOffset = { (int32_t)dstOffset.x, (int32_t)dstOffset.y, (int32_t)dstOffset.z }; + region.srcOffset = { (int32_t)srcOffset.x, (int32_t)srcOffset.y, (int32_t)srcOffset.z }; + + uint32_t mipLevel = region.srcSubresource.mipLevel; + + region.extent.width = (size.x == -1) ? pSrc->getWidth(mipLevel) - srcOffset.x : size.x; + region.extent.height = (size.y == -1) ? pSrc->getHeight(mipLevel) - srcOffset.y : size.y; + region.extent.depth = (size.z == -1) ? pSrc->getDepth(mipLevel) - srcOffset.z : size.z; + + vkCmdCopyImage(mpLowLevelData->getCommandList(), pSrc->getApiHandle(), getImageLayout(Resource::State::CopySource), pDst->getApiHandle(), getImageLayout(Resource::State::CopyDest), 1, ®ion); + + mCommandsPending = true; + } } diff --git a/Framework/Source/ArgList.cpp b/Framework/Source/ArgList.cpp index 7f20b30e4..b8f7c6177 100644 --- a/Framework/Source/ArgList.cpp +++ b/Framework/Source/ArgList.cpp @@ -5,14 +5,40 @@ namespace Falcor { + static std::string readToken(std::stringstream& args) + { + std::string token; + + while(1) + { + std::string tmp; + std::getline(args, tmp, ' '); + token += tmp; + // If there are odd number of '"', read some more + if (std::count(token.begin(), token.end(), '"') % 2) + { + // Read until the next '"' + std::string s; + std::getline(args, s, '"'); + token += ' ' + s + '"'; + // If there is a space after the '"', we're done, otherwise keep reading + if (args.eof() || args.peek() == ' ') return token; + } + else + { + return token; + } + } + } + void ArgList::parseCommandLine(const std::string& cmdLine) { std::stringstream args(cmdLine); - std::string token; std::string currentArg; while (!args.eof()) { - std::getline(args, token, ' '); + std::string token = readToken(args); + size_t dashIndex = token.find('-'); if (dashIndex == 0 && isalpha(token[1])) { diff --git a/Framework/Source/Falcor.h b/Framework/Source/Falcor.h index b2e67de81..1f475b14d 100644 --- a/Framework/Source/Falcor.h +++ b/Framework/Source/Falcor.h @@ -160,5 +160,5 @@ #define FALCOR_MAJOR_VERSION 3 #define FALCOR_MINOR_VERSION 0 #define FALCOR_DEV_STAGE "" -#define FALCOR_DEV_REVISION 3 -#define FALCOR_VERSION_STRING "3.0.3" \ No newline at end of file +#define FALCOR_DEV_REVISION 4 +#define FALCOR_VERSION_STRING "3.0.4" \ No newline at end of file diff --git a/Framework/Source/Graphics/Model/Loaders/AssimpModelImporter.cpp b/Framework/Source/Graphics/Model/Loaders/AssimpModelImporter.cpp index cf65ed375..caa6ae573 100644 --- a/Framework/Source/Graphics/Model/Loaders/AssimpModelImporter.cpp +++ b/Framework/Source/Graphics/Model/Loaders/AssimpModelImporter.cpp @@ -327,10 +327,13 @@ namespace Falcor { aiString name; pAiMaterial->Get(AI_MATKEY_NAME, name); + + // Parse the name std::string nameStr = std::string(name.C_Str()); std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower); + auto nameVec = splitString(nameStr, "."); // The name might contain information about the material + Material::SharedPtr pMaterial = Material::create(nameVec[0]); - Material::SharedPtr pMaterial = Material::create(nameStr); loadTextures(pAiMaterial, folder, pMaterial.get(), isObjFile, useSrgb); if(is_set(mFlags, Model::LoadFlags::UseSpecGlossMaterials)) @@ -400,6 +403,16 @@ namespace Falcor pMaterial->setDoubleSided((isDoubleSided != 0)); } + // Parse the information contained in the name + // The first part is the material name, the other parts provides some info about the material properties + if (nameVec.size() > 1) + { + for (size_t i = 1; i < nameVec.size(); i++) + { + if (nameVec[i] == "doublesided") pMaterial->setDoubleSided(true); + else logWarning("Unknown material property found in the material's name - `" + nameVec[i] + "`"); + } + } return pMaterial; } diff --git a/Framework/Source/Graphics/Program/Program.cpp b/Framework/Source/Graphics/Program/Program.cpp index 2609c0f3e..297e20627 100644 --- a/Framework/Source/Graphics/Program/Program.cpp +++ b/Framework/Source/Graphics/Program/Program.cpp @@ -42,6 +42,16 @@ namespace Falcor { +#ifdef FALCOR_VK + const std::string kSupportedShaderModels[] = { "400", "410", "420", "430", "440", "450" }; +#elif defined FALCOR_D3D12 + const std::string kSupportedShaderModels[] = { "4_0", "4_1", "5_0", "5_1", "6_0", "6_1", "6_2", +#ifdef FALCOR_DXR + "6_3" +#endif + }; +#endif + static Shader::SharedPtr createShaderFromBlob(const Shader::Blob& shaderBlob, ShaderType shaderType, const std::string& entryPointName, Shader::CompilerFlags flags, std::string& log) { std::string errorMsg; @@ -58,8 +68,15 @@ namespace Falcor Program::Desc& Program::Desc::addShaderLibrary(std::string const& path) { - mActiveLibraryIndex = (int)mShaderLibraries.size(); - mShaderLibraries.emplace_back(ShaderLibrary::create(path)); + mActiveSource = (int)mSources.size(); + mSources.emplace_back(ShaderLibrary::create(path)); + return *this; + } + + Program::Desc& Program::Desc::addShaderString(const std::string& shader) + { + mActiveSource = (int)mSources.size(); + mSources.emplace_back(shader); return *this; } @@ -70,16 +87,16 @@ namespace Falcor entryPoint.name = name; if (name.size() == 0) { - entryPoint.libraryIndex = -1; + entryPoint.index = -1; } else { - assert(mActiveLibraryIndex >= 0); - if (entryPoint.libraryIndex != -1) + assert(mActiveSource >= 0); + if (entryPoint.index != -1) { logWarning("Trying to set a " + to_string(shaderType) + " entry-point when one already exists. Overriding previous entry-point"); } - entryPoint.libraryIndex = mActiveLibraryIndex; + entryPoint.index = mActiveSource; entryPoint.name = name; } @@ -99,12 +116,49 @@ namespace Falcor return mEntryPoints[(uint32_t)shaderType].isValid() ? mEntryPoints[(uint32_t)shaderType].name : s; } + Program::Desc& Program::Desc::setShaderModel(const std::string& sm) + { + // Check that the model is supported + bool b = false; + for (size_t i = 0; i < arraysize(kSupportedShaderModels); i++) + { + if (kSupportedShaderModels[i] == sm) + { + b = true; + break; + } + } + + if (b == false) + { + std::string warn = "Unsupported shader-model `" + sm + "` requested. Supported shader-models are "; + for (size_t i = 0; i < arraysize(kSupportedShaderModels); i++) + { + warn += kSupportedShaderModels[i]; + warn += (i == kSupportedShaderModels->size() - 1) ? "." : ", "; + } + warn += "\nThis is not an error, but if something goes wrong try using one of the supported models."; + logWarning(warn); + } + + mShaderModel = sm; + return *this; + } + const ShaderLibrary::SharedPtr& Program::Desc::getShaderLibrary(ShaderType shaderType) const { - static ShaderLibrary::SharedPtr pM;; + static ShaderLibrary::SharedPtr pM; const auto& e = mEntryPoints[(uint32_t)shaderType]; - return e.isValid() ? mShaderLibraries[e.libraryIndex] : pM; + return e.isValid() ? mSources[e.index].pLibrary : pM; + } + + const std::string& Program::Desc::getShaderString(ShaderType shaderType) const + { + static std::string s; + const auto& e = mEntryPoints[(uint32_t)shaderType]; + + return e.isValid() ? mSources[e.index].str : s; } // Program @@ -139,15 +193,25 @@ namespace Falcor std::string desc = "Program with Shaders:\n"; int sourceCounter = 0; - for(auto pModule : mDesc.mShaderLibraries) + for(auto src : mDesc.mSources) { int sourceIndex = sourceCounter++; - desc += pModule->getFilename(); + switch (src.type) + { + case Desc::Source::Type::File: + desc += src.pLibrary->getFilename(); + break; + case Desc::Source::Type::String: + desc += "Created from string"; + break; + default: + should_not_get_here(); + } for( auto entryPoint : mDesc.mEntryPoints ) { - if(entryPoint.libraryIndex != sourceIndex) continue; + if(entryPoint.index != sourceIndex) continue; desc += "/*" + entryPoint.name + "*/"; } desc += "\n"; @@ -336,12 +400,12 @@ namespace Falcor } } - static const char* getSlangProfileString() + static std::string getSlangProfileString(const std::string& shaderModel) { #if defined FALCOR_VK - return "glsl_450"; + return "glsl_" + shaderModel; #elif defined FALCOR_D3D12 - return "sm_5_1"; + return "sm_" + shaderModel; #else #error unknown shader compilation target #endif @@ -382,20 +446,31 @@ namespace Falcor spAddPreprocessorDefine(slangRequest, shaderDefine.first.c_str(), shaderDefine.second.c_str()); } + SlangCompileTarget slangTarget = SLANG_TARGET_UNKNOWN; + const char* preprocessorDefine; // Pick the right target based on the current graphics API #ifdef FALCOR_VK - spSetCodeGenTarget(slangRequest, SLANG_SPIRV); - spAddPreprocessorDefine(slangRequest, "FALCOR_VK", "1"); + slangTarget = SLANG_SPIRV; + preprocessorDefine = "FALCOR_VK"; #elif defined FALCOR_D3D12 - spAddPreprocessorDefine(slangRequest, "FALCOR_D3D", "1"); - // Note: we could compile Slang directly to DXBC (by having Slang invoke the MS compiler for us, - // but that path seems to have more issues at present, so let's just go to HLSL instead...) - spSetCodeGenTarget(slangRequest, SLANG_HLSL); + preprocessorDefine = "FALCOR_D3D"; + // If the profile string starts with a `4_` or a `5_`, use DXBC. Otherwise, use DXIL + if (hasPrefix(mDesc.mShaderModel, "4_") || hasPrefix(mDesc.mShaderModel, "5_")) slangTarget = SLANG_DXBC; + else if (mDesc.mShaderModel == "6_3") slangTarget = SLANG_HLSL; // TODO This is actually a hack for DXR, we need to fix it + else slangTarget = SLANG_DXIL; #else #error unknown shader compilation target #endif + spSetCodeGenTarget(slangRequest, slangTarget); + spAddPreprocessorDefine(slangRequest, preprocessorDefine, "1"); - spSetTargetProfile(slangRequest, 0, spFindProfile(slangSession, getSlangProfileString())); + spSetTargetProfile(slangRequest, 0, spFindProfile(slangSession, getSlangProfileString(mDesc.mShaderModel).c_str())); + + // We always use row-major matrix layout (and when we invoke fxc/dxc we pass in the + // appropriate flags to request this behavior), so we need to inform Slang that + // this is what we want/expect so that it can compute correct reflection information. + // + spSetTargetMatrixLayoutMode(slangRequest, 0, SLANG_MATRIX_LAYOUT_ROW_MAJOR); // Configure any flags for the Slang compilation step SlangCompileFlags slangFlags = 0; @@ -406,23 +481,31 @@ namespace Falcor // Now lets add all our input shader code, one-by-one int translationUnitsAdded = 0; - for(auto pLibrary : mDesc.mShaderLibraries) - { - // If this is not an HLSL or a SLANG file, display a warning - if (!hasSuffix(pLibrary->getFilename(), ".hlsl", false) && !hasSuffix(pLibrary->getFilename(), ".slang", false)) - { - logWarning("Compiling a shader file which is not a SLANG file or an HLSL file. This is not an error, but make sure that the file contains valid shaders"); - } + for(auto src : mDesc.mSources) + { // Register the translation unit with Slang int translationUnitIndex = spAddTranslationUnit(slangRequest, SLANG_SOURCE_LANGUAGE_SLANG, nullptr); assert(translationUnitIndex == translationUnitsAdded); translationUnitsAdded++; // Add source code to the translation unit - std::string fullpath; - findFileInDataDirectories(pLibrary->getFilename(), fullpath); - spAddTranslationUnitSourceFile(slangRequest, translationUnitIndex, fullpath.c_str()); + if (src.type == Desc::Source::Type::File) + { + // If this is not an HLSL or a SLANG file, display a warning + if (!hasSuffix(src.pLibrary->getFilename(), ".hlsl", false) && !hasSuffix(src.pLibrary->getFilename(), ".slang", false)) + { + logWarning("Compiling a shader file which is not a SLANG file or an HLSL file. This is not an error, but make sure that the file contains valid shaders"); + } + std::string fullpath; + findFileInDataDirectories(src.pLibrary->getFilename(), fullpath); + spAddTranslationUnitSourceFile(slangRequest, translationUnitIndex, fullpath.c_str()); + } + else + { + assert(src.type == Desc::Source::Type::String); + spAddTranslationUnitSourceString(slangRequest, translationUnitIndex, "", src.str.c_str()); + } } // Now we make a separate pass and add the entry points. @@ -434,12 +517,12 @@ namespace Falcor auto& entryPoint = mDesc.mEntryPoints[i]; // Skip unused entry points - if(entryPoint.libraryIndex < 0) + if(entryPoint.index < 0) continue; spAddEntryPoint( slangRequest, - entryPoint.libraryIndex, + entryPoint.index, entryPoint.name.c_str(), getSlangStage(ShaderType(i))); } @@ -459,23 +542,26 @@ namespace Falcor for (uint32_t i = 0; i < kShaderCount; i++) { auto& entryPoint = mDesc.mEntryPoints[i]; - // Skip unused entry points - if(entryPoint.libraryIndex < 0) + if(entryPoint.index < 0) continue; int entryPointIndex = entryPointCounter++; - size_t size = 0; -#ifdef FALCOR_VK - const uint8_t* data = (uint8_t*)spGetEntryPointCode(slangRequest, entryPointIndex, &size); - shaderBlob[i].data.assign(data, data + size); - shaderBlob[i].type = Shader::Blob::Type::Bytecode; -#else - const char* data = spGetEntryPointSource(slangRequest, entryPointIndex); - shaderBlob[i].data.assign(data, data + strlen(data)); - shaderBlob[i].type = Shader::Blob::Type::String; -#endif + if (slangTarget == SLANG_GLSL || slangTarget == SLANG_GLSL_VULKAN || slangTarget == SLANG_HLSL) + { + shaderBlob[i].type = Shader::Blob::Type::String; + const char* data = spGetEntryPointSource(slangRequest, entryPointIndex); + shaderBlob[i].data.assign(data, data + strlen(data)); + } + else + { + shaderBlob[i].type = Shader::Blob::Type::Bytecode; + size_t size = 0; + const uint8_t* data = (uint8_t*)spGetEntryPointCode(slangRequest, entryPointIndex, &size); + shaderBlob[i].data.assign(data, data + size); + } + shaderBlob[i].shaderModel = mDesc.mShaderModel; } VersionData programVersion; @@ -585,5 +671,4 @@ namespace Falcor } } } - } diff --git a/Framework/Source/Graphics/Program/Program.h b/Framework/Source/Graphics/Program/Program.h index c48fe34e4..5e2b8e414 100644 --- a/Framework/Source/Graphics/Program/Program.h +++ b/Framework/Source/Graphics/Program/Program.h @@ -65,11 +65,16 @@ namespace Falcor */ explicit Desc(std::string const& filename); - /** Add a file of course code to use. - This also sets the given file as the "active" source for subsequent entry points. + /** Add a file of source code to use. + This also sets the given file as the "active" source for subsequent entry points. */ Desc& addShaderLibrary(const std::string& path); + /** Add a string of source code to use. + This also sets the given string as the "active" source for subsequent entry points. + */ + Desc& addShaderString(const std::string& shader); + /** Adds an entry point based on the "active" source. */ Desc& entryPoint(ShaderType shaderType, const std::string& name); @@ -81,43 +86,75 @@ namespace Falcor Desc& psEntry(const std::string& name) { return entryPoint(ShaderType::Pixel, name); } Desc& csEntry(const std::string& name) { return entryPoint(ShaderType::Compute, name); } - /** Get the source string associated with a shader stage, or an empty string if no stage found + /** Get the source library associated with a shader stage, or an empty library if one isn't bound to the shader */ const std::shared_ptr& getShaderLibrary(ShaderType shaderType) const; + /** Get the source string associated with a shader stage, or an empty string if one isn't bound to the shader + */ + const std::string& getShaderString(ShaderType shaderType) const; + /** Get the name of the shader entry point associated with a shader stage, or an empty string if no stage found */ const std::string& getShaderEntryPoint(ShaderType shaderType) const; /** Enable/disable treat-warnings-as-error compilation flag */ - Desc& warningsAsErrors(bool enable) { enable ? shaderFlags |= Shader::CompilerFlags::TreatWarningsAsErrors : shaderFlags &= ~(Shader::CompilerFlags::TreatWarningsAsErrors); return *this; } + Desc& warningsAsErrors(bool enable) { enable ? mShaderFlags |= Shader::CompilerFlags::TreatWarningsAsErrors : mShaderFlags &= ~(Shader::CompilerFlags::TreatWarningsAsErrors); return *this; } /** Enable/disable pre-processed shader dump */ - Desc& dumpIntermediates(bool enable) { enable ? shaderFlags |= Shader::CompilerFlags::DumpIntermediates : shaderFlags &= ~(Shader::CompilerFlags::DumpIntermediates); return *this; } + Desc& dumpIntermediates(bool enable) { enable ? mShaderFlags |= Shader::CompilerFlags::DumpIntermediates : mShaderFlags &= ~(Shader::CompilerFlags::DumpIntermediates); return *this; } + + + /** Set the shader model string. This depends on the API you are using. + For DirectX it should be `4_0`, `4_1`, `5_0`, `5_1`, `6_0`, `6_1` or `6_2`. The default is `5_1`. Shader model `6.x` will use dxcompiler + For Vulkan, it should be `400`, `410`, `420`, `430`, `440` or `450`. The default is `450` + */ + Desc& setShaderModel(const std::string& sm); /** Get the compiler flags */ - Shader::CompilerFlags getCompilerFlags() const { return shaderFlags; } + Shader::CompilerFlags getCompilerFlags() const { return mShaderFlags; } private: friend class Program; friend class GraphicsProgram; Desc& addDefaultVertexShaderIfNeeded(); + struct Source + { + enum class Type + { + String, + File + }; + + Source(std::shared_ptr pLib) : pLibrary(pLib), type(Type::File) {}; + Source(std::string s) : str(s), type(Type::String) {}; + + Type type; + std::shared_ptr pLibrary; + std::string str; + }; + struct EntryPoint { std::string name; // The index of the shader module that this entry point will use, or `-1` to indicate that this entry point is disabled - int libraryIndex = -1; - bool isValid() const { return libraryIndex >= 0; } + int index = -1; + bool isValid() const { return index >= 0; } }; - std::vector> mShaderLibraries; + std::vector mSources; EntryPoint mEntryPoints[kShaderCount]; - int mActiveLibraryIndex = -1; - Shader::CompilerFlags shaderFlags = Shader::CompilerFlags::None; + uint32_t mActiveSource = -1; + Shader::CompilerFlags mShaderFlags = Shader::CompilerFlags::None; +#ifdef FALCOR_VK + std::string mShaderModel = "450"; +#elif defined FALCOR_D3D12 + std::string mShaderModel = "5_1"; +#endif }; virtual ~Program() = 0; diff --git a/Framework/Source/Raytracing/RtProgram/HitProgram.cpp b/Framework/Source/Raytracing/RtProgram/HitProgram.cpp index 52f662b44..f4cde8272 100644 --- a/Framework/Source/Raytracing/RtProgram/HitProgram.cpp +++ b/Framework/Source/Raytracing/RtProgram/HitProgram.cpp @@ -53,7 +53,7 @@ namespace Falcor if (closestHitEntry.size()) desc.entryPoint(ShaderType::ClosestHit, closestHitEntry); if (anyHitEntry.size()) desc.entryPoint(ShaderType::AnyHit, anyHitEntry); if (intersectionEntry.size()) desc.entryPoint(ShaderType::Intersection, intersectionEntry); - + desc.setShaderModel("6_3"); pProg->init(desc, programDefines); return pProg; } diff --git a/Framework/Source/Raytracing/RtProgram/SingleShaderProgram.h b/Framework/Source/Raytracing/RtProgram/SingleShaderProgram.h index 45bf2eef9..fe0f503bd 100644 --- a/Framework/Source/Raytracing/RtProgram/SingleShaderProgram.h +++ b/Framework/Source/Raytracing/RtProgram/SingleShaderProgram.h @@ -59,6 +59,7 @@ namespace Falcor SharedPtr pProg = SharedPtr(new RtSingleShaderProgram(maxPayloadSize, maxAttributesSize)); Desc d(str); d.entryPoint((ShaderType)shaderType, entryPoint); + d.setShaderModel("6_3"); pProg->init(d, programDefines); return pProg; } diff --git a/Samples/Core/ProjectTemplate/ProjectTemplate.cpp b/Samples/Core/ProjectTemplate/ProjectTemplate.cpp index c12c2d83a..bf641d134 100644 --- a/Samples/Core/ProjectTemplate/ProjectTemplate.cpp +++ b/Samples/Core/ProjectTemplate/ProjectTemplate.cpp @@ -37,88 +37,8 @@ void ProjectTemplate::onGuiRender(SampleCallbacks* pSample, Gui* pGui) } } -vec3 sphericalCrdToDir(vec2 uv) -{ - static const float PI = 3.1415926535f; - static const float PI_2 = 2.0f * 3.1415926535f; - - float phi = PI * uv.y; - float theta = PI_2 * uv.x - (PI / 2.0f); - - vec3 dir; - dir.x = sin(phi) * sin(theta); - dir.y = cos(phi); - dir.z = sin(phi) * cos(theta); - - return -dir; -} - -vec2 dirToSphericalCrd(vec3 direction) -{ - static const float PI = 3.14159265f; - vec3 p = normalize(direction); - vec2 uv; - uv.x = (1.0f + atan2(-p.z, p.x) / PI) * 0.5f; - uv.y = 1.0f - (-acos(p.y) / PI); - return uv; -} - -bool intersectRaySphere(vec3 rayPosW, vec3 rayDir, vec3 spherePosW, float sphereRadius, - vec3& intersectionPosW) -{ - float3 m = rayPosW - spherePosW; - float b = dot(m, rayDir); - float c = dot(m, m) - (sphereRadius * sphereRadius); - - // If ray origin is outside sphere (c > 0) and ray is pointing away from sphere (b > 0) - // For now assume input always produces valid intersection - // if(c > 0.0f && b > 0.0f) return false; - - float discr = b * b - c; - // Negative discriminant means ray missed sphere - // if(discr < 0.0f) return false; - - float t = -b - sqrt(discr); - - // t will be negative if origin is inside sphere, - // take the abs since we want the position on the sphere's surface - intersectionPosW = normalize(rayPosW + abs(t) * rayDir); - - return true; -} - -#include "glm/gtc/random.hpp" - void ProjectTemplate::onLoad(SampleCallbacks* pSample, RenderContext::SharedPtr pRenderContext) { - vec3 output0; - intersectRaySphere(vec3(2.5f, 0, 0), normalize(vec3(.707f, .707f, 0)), vec3(), 5.0f, output0); - - vec3 output1; - intersectRaySphere(vec3(2.5f, 0, 0), normalize(vec3(0, 1, 0)), vec3(), 5.0f, output1); - - vec3 output2; - intersectRaySphere(vec3(2.5f, 0, 0), normalize(vec3(1, 0, 0)), vec3(), 5.0f, output2); - - - - //for(uint32_t i = 0; i < 1000000; i++) - //{ - // vec3 dir = normalize(linearRand(vec3(-10), vec3(10))); - // vec2 uv = dirToSphericalCrd(dir); - // vec3 outDir = sphericalCrdToDir(uv); - // vec2 outUV = dirToSphericalCrd(outDir); - - // vec2 uvError = abs(outUV - uv); - // vec3 dirError = abs(dir - outDir); - - // if (any(epsilonNotEqual(uvError, vec2(0), vec2(0.0001f))) || - // any(epsilonNotEqual(dirError, vec3(0), vec3(0.0001f)))) - // { - // __debugbreak(); - // } - //} - } void ProjectTemplate::onFrameRender(SampleCallbacks* pSample, RenderContext::SharedPtr pRenderContext, Fbo::SharedPtr pTargetFbo) diff --git a/dependencies.xml b/dependencies.xml index abc147a75..05a137373 100644 --- a/dependencies.xml +++ b/dependencies.xml @@ -29,8 +29,8 @@ - - + + @@ -41,4 +41,7 @@ + + +