Skip to content

Commit ca8c955

Browse files
committed
Merge branch 'dev-3.0.3' into rel-3.0.3
2 parents 0b561ca + 5ab1324 commit ca8c955

34 files changed

+1277
-110
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
v3.0.3
2+
------
3+
- Added FXAA as an effect
4+
- Support programmable sample position - `Fbo::setSamplePositions()` (DX only)
5+
- Added RenderContext::resolveResource() and RenderContext::resolveSubresource() MSAA resolve functions
6+
- Added support for setting shading model through fscene files and load flags. Also editable in Scene Editor
7+
8+
v3.0.2
9+
------
10+
- Various bug fixes
11+
- Fixed Vulkan error spam seen when running Falcor's included samples
12+
- Updated API abstraction interfaces to return const-ref where applicable
13+
- Fixed crash when handling mouse/keyboard messages after the renderer has shut down
14+
115
v3.0.1
216
------
317
- Added RenderContext::StateBindFlags, which allows the user to control which part of the `GraphicsState` will be bound to the pipeline

Framework/Source/API/D3D12/D3D12RenderContext.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,38 @@ namespace Falcor
188188
}
189189
}
190190
}
191+
ID3D12GraphicsCommandList* pCmdList = pCtx->getLowLevelData()->getCommandList().GetInterfacePtr();
192+
pCmdList->OMSetRenderTargets(colorTargets, pRTV.data(), FALSE, &pDSV);
193+
}
194+
195+
static void D3D12SetSamplePositions(ID3D12GraphicsCommandList* pList, const Fbo* pFbo)
196+
{
197+
if (!pFbo) return;
198+
ID3D12GraphicsCommandList1* pList1;
199+
pList->QueryInterface(IID_PPV_ARGS(&pList1));
200+
const auto& samplePos = pFbo->getSamplePositions();
201+
202+
if (!pList1)
203+
{
204+
if (samplePos.size())
205+
{
206+
logError("The FBO specifies programmable sample positions, but the hardware doesn't support it");
207+
}
208+
}
209+
else
210+
{
211+
static_assert(offsetof(Fbo::SamplePosition, xOffset) == offsetof(D3D12_SAMPLE_POSITION, X), "SamplePosition.X");
212+
static_assert(offsetof(Fbo::SamplePosition, yOffset) == offsetof(D3D12_SAMPLE_POSITION, Y), "SamplePosition.Y");
191213

192-
pCtx->getLowLevelData()->getCommandList()->OMSetRenderTargets(colorTargets, pRTV.data(), FALSE, &pDSV);
214+
if (samplePos.size())
215+
{
216+
pList1->SetSamplePositions(pFbo->getSampleCount(), pFbo->getSamplePositionsPixelCount(), (D3D12_SAMPLE_POSITION*)samplePos.data());
217+
}
218+
else
219+
{
220+
pList1->SetSamplePositions(0, 0, nullptr);
221+
}
222+
}
193223
}
194224

195225
static void D3D12SetViewports(ID3D12GraphicsCommandList* pList, const GraphicsState::Viewport* vp)
@@ -258,6 +288,10 @@ namespace Falcor
258288
{
259289
D3D12SetFbo(this, mpGraphicsState->getFbo().get());
260290
}
291+
if (is_set(StateBindFlags::SamplePositions, mBindFlags))
292+
{
293+
D3D12SetSamplePositions(pList, mpGraphicsState->getFbo().get());
294+
}
261295
if (is_set(StateBindFlags::Viewports, mBindFlags))
262296
{
263297
D3D12SetViewports(pList, &mpGraphicsState->getViewport(0));
@@ -270,6 +304,13 @@ namespace Falcor
270304
{
271305
pList->SetPipelineState(mpGraphicsState->getGSO(mpGraphicsVars.get())->getApiHandle());
272306
}
307+
if (is_set(StateBindFlags::SamplePositions, mBindFlags))
308+
{
309+
if (mpGraphicsState->getFbo() && mpGraphicsState->getFbo()->getSamplePositions().size())
310+
{
311+
logWarning("The Vulkan backend doesn't support programmable sample positions");
312+
}
313+
}
273314

274315
BlendState::SharedPtr blendState = mpGraphicsState->getBlendState();
275316
if (blendState != nullptr)
@@ -419,4 +460,31 @@ namespace Falcor
419460
popGraphicsState();
420461
popGraphicsVars();
421462
}
463+
464+
void RenderContext::resolveSubresource(const Texture* pSrc, uint32_t srcSubresource, const Texture* pDst, uint32_t dstSubresource)
465+
{
466+
DXGI_FORMAT format = getDxgiFormat(pDst->getFormat());
467+
mpLowLevelData->getCommandList()->ResolveSubresource(pDst->getApiHandle(), dstSubresource, pSrc->getApiHandle(), srcSubresource, format);
468+
mCommandsPending = true;
469+
}
470+
471+
void RenderContext::resolveResource(const Texture* pSrc, const Texture* pDst)
472+
{
473+
bool match = true;
474+
match = match && (pSrc->getMipCount() == pDst->getMipCount());
475+
match = match && (pSrc->getArraySize() == pDst->getArraySize());
476+
if (!match)
477+
{
478+
logWarning("Can't resolve a resource. The src and dst textures have a different array-size or mip-count");
479+
}
480+
481+
resourceBarrier(pSrc, Resource::State::ResolveSource);
482+
resourceBarrier(pDst, Resource::State::ResolveDest);
483+
484+
uint32_t subresourceCount = pSrc->getMipCount() * pSrc->getArraySize();
485+
for (uint32_t s = 0; s < subresourceCount; s++)
486+
{
487+
resolveSubresource(pSrc, s, pDst, s);
488+
}
489+
}
422490
}

Framework/Source/API/D3D12/LowLevel/D3D12LowLevelContextData.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ namespace Falcor
4444
return pAllocator;
4545
}
4646

47+
template<typename ApiType>
48+
ApiType createCommandList(ID3D12Device* pDevice, D3D12_COMMAND_LIST_TYPE type, CommandAllocatorHandle allocator)
49+
{
50+
ApiType pList;
51+
HRESULT hr = pDevice->CreateCommandList(0, type, allocator, nullptr, IID_PPV_ARGS(&pList));
52+
return (FAILED(hr)) ? nullptr : pList;
53+
}
54+
4755
LowLevelContextData::SharedPtr LowLevelContextData::create(CommandQueueType type, CommandQueueHandle queue)
4856
{
4957
SharedPtr pThis = SharedPtr(new LowLevelContextData);
@@ -69,9 +77,15 @@ namespace Falcor
6977
}
7078
pThis->mpAllocator = pThis->mpApiData->pAllocatorPool->newObject();
7179

72-
// Create a command list
80+
// Create a command list. Try to create the latest version the device supports
7381
ID3D12Device* pDevice = gpDevice->getApiHandle().GetInterfacePtr();
74-
if (FAILED(pDevice->CreateCommandList(0, cmdListType, pThis->mpAllocator, nullptr, IID_PPV_ARGS(&pThis->mpList))))
82+
#ifdef FALCOR_DXR
83+
pThis->mpList = createCommandList<ID3D12GraphicsCommandList2*>(pDevice, cmdListType, pThis->mpAllocator);
84+
#endif
85+
if (!pThis->mpList) pThis->mpList = createCommandList<ID3D12GraphicsCommandList1*>(pDevice, cmdListType, pThis->mpAllocator);
86+
if (!pThis->mpList) pThis->mpList = createCommandList<ID3D12GraphicsCommandList*>(pDevice, cmdListType, pThis->mpAllocator);
87+
88+
if (pThis->mpList == nullptr)
7589
{
7690
logError("Failed to create command list for LowLevelContextData");
7791
return nullptr;

Framework/Source/API/FBO.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,17 @@ namespace Falcor
272272
// Check depth
273273
if (verifyAttachment(mDepthStencil) == false) return false;
274274

275+
// In case there are sample positions, make sure they are valid
276+
if (mSamplePositions.size())
277+
{
278+
uint32_t expectedCount = mSamplePositionsPixelCount * mTempDesc.getSampleCount();
279+
if (expectedCount != mSamplePositions.size())
280+
{
281+
logError("Error when validating FBO. The sample-positions array-size has the wrong size.\n");
282+
return false;
283+
}
284+
}
285+
275286
// Insert the attachment into the static array and initialize the address
276287
mpDesc = &(*(sDescs.insert(mTempDesc).first));
277288

@@ -303,4 +314,18 @@ namespace Falcor
303314
}
304315
return true;
305316
}
317+
318+
void Fbo::setSamplePositions(uint32_t samplesPerPixel, uint32_t pixelCount, const SamplePosition positions[])
319+
{
320+
if (positions)
321+
{
322+
mSamplePositions = std::vector<SamplePosition>(positions, positions + (samplesPerPixel * pixelCount));
323+
mSamplePositionsPixelCount = pixelCount;
324+
}
325+
else
326+
{
327+
mSamplePositionsPixelCount = 0;
328+
mSamplePositions.clear();
329+
}
330+
}
306331
}

Framework/Source/API/FBO.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,29 @@ namespace Falcor
190190
*/
191191
RenderTargetView::SharedPtr getRenderTargetView(uint32_t rtIndex) const;
192192

193+
194+
struct SamplePosition
195+
{
196+
int8 xOffset = 0;
197+
int8 yOffset = 0;
198+
};
199+
200+
/** Configure the sample positions used by multi-sampled buffers.
201+
\param[in] samplesPerPixel The number of samples-per-pixel. This value has to match the FBO's sample count
202+
\param[in] pixelCount the number if pixels the sample pattern is specified for
203+
\param[in] positions The sample positions. (0,0) is a pixel's center. The size of this array should be samplesPerPixel*pixelCount
204+
To reset the positions to their original location pass `nullptr` for positions
205+
*/
206+
void setSamplePositions(uint32_t samplesPerPixel, uint32_t pixelCount, const SamplePosition positions[]);
207+
208+
/** Get the sample positions
209+
*/
210+
const std::vector<SamplePosition> getSamplePositions() const { return mSamplePositions; }
211+
212+
/** Get the number of pixels the sample positions are configured for
213+
*/
214+
uint32_t getSamplePositionsPixelCount() const { return mSamplePositionsPixelCount; }
215+
193216
struct Attachment
194217
{
195218
Texture::SharedPtr pTexture = nullptr;
@@ -215,6 +238,9 @@ namespace Falcor
215238

216239
Fbo();
217240
std::vector<Attachment> mColorAttachments;
241+
std::vector<SamplePosition> mSamplePositions;
242+
uint32_t mSamplePositionsPixelCount = 0;
243+
218244
Attachment mDepthStencil;
219245

220246
mutable Desc mTempDesc;

Framework/Source/API/RenderContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,4 @@ namespace Falcor
125125
mBindGraphicsRootSig = true;
126126
}
127127
}
128+

Framework/Source/API/RenderContext.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ namespace Falcor
6666
Viewports = 0x10, ///<Bind Viewport
6767
Scissors = 0x20, ///<Bind scissors
6868
PipelineState = 0x40, ///<Bind Pipeline State Object
69+
SamplePositions = 0x80, ///<Set the programmable sample positions
6970
All = uint32_t(-1)
7071
};
7172

@@ -188,11 +189,21 @@ namespace Falcor
188189
*/
189190
void setBindFlags(StateBindFlags flags) { mBindFlags = flags; }
190191

192+
/** Resolve an entire multi-sampled resource. The dst and src resources must have the same dimensions, array-size, mip-count and format.
193+
If any of these properties don't match, you'll have to use `resolveSubresource`
194+
*/
195+
void resolveResource(const Texture* pSrc, const Texture* pDst);
196+
197+
/** Resolve a multi-sampled sub-resource
198+
*/
199+
void resolveSubresource(const Texture* pSrc, uint32_t srcSubresource, const Texture* pDst, uint32_t dstSubresource);
200+
191201
#ifdef FALCOR_DXR
192202
/** Submit a raytrace command. This function doesn't change the state of the render-context. Graphics/compute vars and state will stay the same
193203
*/
194204
void raytrace(std::shared_ptr<RtProgramVars> pVars, std::shared_ptr<RtState> pState, uint32_t width, uint32_t height);
195205
#endif
206+
196207
private:
197208
RenderContext();
198209
GraphicsVars::SharedPtr mpGraphicsVars;

Framework/Source/API/Vulkan/VKCopyContext.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ namespace Falcor
6464
return size;
6565
}
6666

67-
static VkImageLayout getImageLayout(Resource::State state)
67+
VkImageLayout getImageLayout(Resource::State state)
6868
{
6969
switch (state)
7070
{
@@ -76,15 +76,15 @@ namespace Falcor
7676
case Resource::State::UnorderedAccess:
7777
return VK_IMAGE_LAYOUT_GENERAL;
7878
case Resource::State::RenderTarget:
79-
case Resource::State::ResolveDest:
8079
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
8180
case Resource::State::DepthStencil:
8281
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
8382
case Resource::State::ShaderResource:
84-
case Resource::State::ResolveSource:
8583
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
84+
case Resource::State::ResolveDest:
8685
case Resource::State::CopyDest:
8786
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
87+
case Resource::State::ResolveSource:
8888
case Resource::State::CopySource:
8989
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9090
break;
@@ -121,14 +121,12 @@ namespace Falcor
121121
return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
122122
case Resource::State::IndirectArg:
123123
return VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
124+
case Resource::State::ResolveDest:
124125
case Resource::State::CopyDest:
125126
return VK_ACCESS_TRANSFER_WRITE_BIT;
127+
case Resource::State::ResolveSource:
126128
case Resource::State::CopySource:
127129
return VK_ACCESS_TRANSFER_READ_BIT;
128-
case Resource::State::ResolveDest:
129-
return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
130-
case Resource::State::ResolveSource:
131-
return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
132130
default:
133131
should_not_get_here();
134132
return VkAccessFlagBits(-1);

Framework/Source/API/Vulkan/VKGpuTimer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace Falcor
3333
{
3434
void GpuTimer::apiBegin()
3535
{
36+
vkCmdResetQueryPool(mpLowLevelData->getCommandList(), mpHeap, mStart, 2);
3637
vkCmdWriteTimestamp(mpLowLevelData->getCommandList(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, mpHeap, mStart);
3738
}
3839

@@ -43,6 +44,6 @@ namespace Falcor
4344

4445
void GpuTimer::apiResolve(uint64_t result[2])
4546
{
46-
vk_call(vkGetQueryPoolResults(gpDevice->getApiHandle(), mpHeap, mStart, 2, sizeof(uint64_t)*2, result, sizeof(result[0]), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
47+
vk_call(vkGetQueryPoolResults(gpDevice->getApiHandle(), mpHeap, mStart, 2, sizeof(uint64_t) * 2, result, sizeof(result[0]), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
4748
}
4849
}

Framework/Source/API/Vulkan/VKRenderContext.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
namespace Falcor
3636
{
3737
VkImageAspectFlags getAspectFlagsFromFormat(ResourceFormat format);
38-
38+
VkImageLayout getImageLayout(Resource::State state);
39+
3940
RenderContext::SharedPtr RenderContext::create(CommandQueueHandle queue)
4041
{
4142
SharedPtr pCtx = SharedPtr(new RenderContext());
@@ -319,5 +320,25 @@ namespace Falcor
319320
VkFilter vkFilter = isDepthStencilFormat(pTexture->getFormat()) ? VK_FILTER_NEAREST : getVkFilter(filter);
320321
vkCmdBlitImage(mpLowLevelData->getCommandList(), pSrc->getResource()->getApiHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, pDst->getResource()->getApiHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blt, vkFilter);
321322
}
323+
mCommandsPending = true;
324+
}
325+
326+
void RenderContext::resolveResource(const Texture* pSrc, const Texture* pDst)
327+
{
328+
// Just blit. It will work
329+
blit(pSrc->getSRV(), pDst->getRTV());
330+
}
331+
332+
void RenderContext::resolveSubresource(const Texture* pSrc, uint32_t srcSubresource, const Texture* pDst, uint32_t dstSubresource)
333+
{
334+
uint32_t srcArray = pSrc->getSubresourceArraySlice(srcSubresource);
335+
uint32_t srcMip = pSrc->getSubresourceMipLevel(srcSubresource);
336+
const auto& pSrcSrv = pSrc->getSRV(srcMip, 1, srcArray, 1);
337+
338+
uint32_t dstArray = pDst->getSubresourceArraySlice(dstSubresource);
339+
uint32_t dstMip = pDst->getSubresourceMipLevel(dstSubresource);
340+
const auto& pDstRtv = pDst->getRTV(dstMip, dstArray, 1);
341+
342+
blit(pSrcSrv, pDstRtv);
322343
}
323344
}

0 commit comments

Comments
 (0)