Skip to content

Commit

Permalink
- Added d3d12-specific calls for SamplerFeedbackTexture data decoding…
Browse files Browse the repository at this point in the history
… and state tracking based on a regular texture state tracking

- Fix for UpdateTileMappings with ZERO pages
  • Loading branch information
emakarov-cmd committed Oct 29, 2024
1 parent 828b523 commit 4e32b91
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 33 deletions.
4 changes: 3 additions & 1 deletion include/nvrhi/d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ namespace nvrhi::d3d12
virtual void updateGraphicsVolatileBuffers() = 0;
virtual void updateComputeVolatileBuffers() = 0;

virtual void clearSamplerFeedbackTexture(ISamplerFeedbackTexture* t) = 0;
virtual void clearSamplerFeedbackTexture(ISamplerFeedbackTexture* texture) = 0;
virtual void decodeSamplerFeedbackTexture(IBuffer* buffer, ISamplerFeedbackTexture* texture, nvrhi::Format format) = 0;
virtual void setSamplerFeedbackTextureState(ISamplerFeedbackTexture* texture, ResourceStates stateBits) = 0;
};

typedef RefCountPtr<ICommandList> CommandListHandle;
Expand Down
1 change: 1 addition & 0 deletions include/nvrhi/nvrhi.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ namespace nvrhi
uint32_t samplerFeedbackMipRegionY = 0;
uint32_t samplerFeedbackMipRegionZ = 0;
ResourceStates initialState = ResourceStates::Unknown;
bool keepInitialState = false;
};

class ISamplerFeedbackTexture : public IResource
Expand Down
1 change: 1 addition & 0 deletions src/common/state-tracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace nvrhi
const TextureDesc& descRef;
ResourceStates permanentState = ResourceStates::Unknown;
bool stateInitialized = false;
bool isSamplerFeedback = false;

explicit TextureStateExtension(const TextureDesc& desc)
: descRef(desc)
Expand Down
31 changes: 12 additions & 19 deletions src/d3d12/d3d12-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ namespace nvrhi::d3d12
}

~Texture() override;

const TextureDesc& getDesc() const override { return desc; }

Object getNativeObject(ObjectType objectType) override;
Expand Down Expand Up @@ -358,46 +358,36 @@ namespace nvrhi::d3d12
Object getNativeObject(ObjectType objectType) override;
};

class SamplerFeedbackTexture : public RefCounter<ISamplerFeedbackTexture>
class SamplerFeedbackTexture : public RefCounter<ISamplerFeedbackTexture>, public TextureStateExtension
{
public:
const SamplerFeedbackTextureDesc desc;
const D3D12_RESOURCE_DESC1 resourceDesc;
const TextureDesc textureDesc; // used with state tracking
RefCountPtr<ID3D12Resource> resource;
TextureHandle pairedTexture;

SamplerFeedbackTexture(const Context& context, DeviceResources& resources, SamplerFeedbackTextureDesc desc, const D3D12_RESOURCE_DESC1& resourceDesc, ITexture* pairedTexture)
SamplerFeedbackTexture(const Context& context, DeviceResources& resources, SamplerFeedbackTextureDesc desc, TextureDesc textureDesc, ITexture* pairedTexture)
: desc(std::move(desc))
, resourceDesc(resourceDesc)
, textureDesc(std::move(textureDesc))
, m_Context(context)
, m_Resources(resources)
, pairedTexture(pairedTexture)
, TextureStateExtension(SamplerFeedbackTexture::textureDesc)
{
TextureStateExtension::stateInitialized = true;
TextureStateExtension::isSamplerFeedback = true;
}

const SamplerFeedbackTextureDesc& getDesc() const override { return desc; }
TextureHandle getPairedTexture() override { return pairedTexture; }

void createUAV(size_t descriptor) const;

DescriptorIndex SamplerFeedbackTexture::getClearUAV()
{
if (m_ClearUAV != c_InvalidDescriptorIndex)
return m_ClearUAV;

m_ClearUAV = m_Resources.shaderResourceViewHeap.allocateDescriptor();
createUAV(m_Resources.shaderResourceViewHeap.getCpuHandle(m_ClearUAV).ptr);
m_Resources.shaderResourceViewHeap.copyToShaderVisibleHeap(m_ClearUAV);

return m_ClearUAV;
}

Object getNativeObject(ObjectType objectType) override;

private:
const Context& m_Context;
DeviceResources& m_Resources;
DescriptorIndex m_ClearUAV = c_InvalidDescriptorIndex;
};

class Sampler : public RefCounter<ISampler>
Expand Down Expand Up @@ -912,6 +902,7 @@ namespace nvrhi::d3d12
~CommandList() override;
std::shared_ptr<CommandListInstance> executed(Queue* pQueue);
void requireTextureState(ITexture* texture, TextureSubresourceSet subresources, ResourceStates state);
void requireSamplerFeedbackTextureState(ISamplerFeedbackTexture* texture, ResourceStates state);
void requireBufferState(IBuffer* buffer, ResourceStates state);
ID3D12CommandList* getD3D12CommandList() const { return m_ActiveCommandList->commandList; }

Expand All @@ -928,7 +919,9 @@ namespace nvrhi::d3d12
void clearTextureFloat(ITexture* t, TextureSubresourceSet subresources, const Color& clearColor) override;
void clearDepthStencilTexture(ITexture* t, TextureSubresourceSet subresources, bool clearDepth, float depth, bool clearStencil, uint8_t stencil) override;
void clearTextureUInt(ITexture* t, TextureSubresourceSet subresources, uint32_t clearColor) override;
void clearSamplerFeedbackTexture(ISamplerFeedbackTexture* t) override;
void clearSamplerFeedbackTexture(ISamplerFeedbackTexture* texture) override;
void decodeSamplerFeedbackTexture(IBuffer* buffer, ISamplerFeedbackTexture* texture, Format format) override;
void setSamplerFeedbackTextureState(ISamplerFeedbackTexture* texture, ResourceStates stateBits) override;

void copyTexture(ITexture* dest, const TextureSlice& destSlice, ITexture* src, const TextureSlice& srcSlice) override;
void copyTexture(IStagingTexture* dest, const TextureSlice& destSlice, ITexture* src, const TextureSlice& srcSlice) override;
Expand Down
12 changes: 7 additions & 5 deletions src/d3d12/d3d12-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,15 +432,15 @@ namespace nvrhi::d3d12

for (size_t i = 0; i < numTileMappings; i++)
{
ID3D12Heap* heap = tileMappings[i].heap ? checked_cast<Heap*>(tileMappings[i].heap)->heap : nullptr;

uint32_t numRegions = tileMappings[i].numTextureRegions;
std::vector<D3D12_TILED_RESOURCE_COORDINATE> resourceCoordinates(numRegions);
std::vector<D3D12_TILE_REGION_SIZE> regionSizes(numRegions);
std::vector<D3D12_TILE_RANGE_FLAGS> rangeFlags(numRegions, D3D12_TILE_RANGE_FLAG_NONE);
std::vector<D3D12_TILE_RANGE_FLAGS> rangeFlags(numRegions, heap ? D3D12_TILE_RANGE_FLAG_NONE : D3D12_TILE_RANGE_FLAG_NULL);
std::vector<UINT> heapStartOffsets(numRegions);
std::vector<UINT> rangeTileCounts(numRegions);

Heap* heap = tileMappings[i].heap ? checked_cast<Heap*>(tileMappings[i].heap) : nullptr;

for (uint32_t j = 0; j < numRegions; ++j)
{
const TiledTextureCoordinate& tiledTextureCoordinate = tileMappings[i].tiledTextureCoordinates[j];
Expand Down Expand Up @@ -471,11 +471,13 @@ namespace nvrhi::d3d12
}

// Offset in tiles
heapStartOffsets[j] = heap ? (uint32_t)(tileMappings[i].byteOffsets[j] / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) : 0;
if (heap)
heapStartOffsets[j] = (uint32_t)(tileMappings[i].byteOffsets[j] / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES);

rangeTileCounts[j] = regionSizes[j].NumTiles;
}

queue->queue->UpdateTileMappings(texture->resource, tileMappings[i].numTextureRegions, resourceCoordinates.data(), regionSizes.data(), heap ? heap->heap : nullptr, numRegions, rangeFlags.data(), heapStartOffsets.data(), rangeTileCounts.data(), D3D12_TILE_MAPPING_FLAG_NONE);
queue->queue->UpdateTileMappings(texture->resource, tileMappings[i].numTextureRegions, resourceCoordinates.data(), regionSizes.data(), heap, numRegions, rangeFlags.data(), heap ? heapStartOffsets.data() : nullptr, rangeTileCounts.data(), D3D12_TILE_MAPPING_FLAG_NONE);
}
}

Expand Down
24 changes: 21 additions & 3 deletions src/d3d12/d3d12-state-tracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ namespace nvrhi::d3d12

m_StateTracker.requireTextureState(texture, subresources, state);
}

void CommandList::requireSamplerFeedbackTextureState(ISamplerFeedbackTexture* _texture, ResourceStates state)
{
SamplerFeedbackTexture* texture = checked_cast<SamplerFeedbackTexture*>(_texture);

m_StateTracker.requireTextureState(texture, AllSubresources, state);
}

void CommandList::requireBufferState(IBuffer* _buffer, ResourceStates state)
{
Expand All @@ -106,7 +113,18 @@ namespace nvrhi::d3d12
// Convert the texture barriers into D3D equivalents
for (const auto& barrier : textureBarriers)
{
const Texture* texture = static_cast<const Texture*>(barrier.texture);
const Texture* texture = nullptr;
ID3D12Resource* resource = nullptr;

if (barrier.texture->isSamplerFeedback)
{
resource = static_cast<const SamplerFeedbackTexture*>(barrier.texture)->resource;
}
else
{
texture = static_cast<const Texture*>(barrier.texture);
resource = texture->resource;
}

D3D12_RESOURCE_BARRIER d3dbarrier{};
const D3D12_RESOURCE_STATES stateBefore = convertResourceStates(barrier.stateBefore);
Expand All @@ -116,7 +134,7 @@ namespace nvrhi::d3d12
d3dbarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
d3dbarrier.Transition.StateBefore = stateBefore;
d3dbarrier.Transition.StateAfter = stateAfter;
d3dbarrier.Transition.pResource = texture->resource;
d3dbarrier.Transition.pResource = resource;
if (barrier.entireTexture)
{
d3dbarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
Expand All @@ -134,7 +152,7 @@ namespace nvrhi::d3d12
else if (stateAfter & D3D12_RESOURCE_STATE_UNORDERED_ACCESS)
{
d3dbarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
d3dbarrier.UAV.pResource = texture->resource;
d3dbarrier.UAV.pResource = resource;
m_D3DBarriers.push_back(d3dbarrier);
}
}
Expand Down
40 changes: 35 additions & 5 deletions src/d3d12/d3d12-texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,11 @@ namespace nvrhi::d3d12
}
rdFeedback.SamplerFeedbackMipRegion = D3D12_MIP_REGION{ desc.samplerFeedbackMipRegionX, desc.samplerFeedbackMipRegionY, desc.samplerFeedbackMipRegionZ };

SamplerFeedbackTexture* texture = new SamplerFeedbackTexture(m_Context, m_Resources, desc, rdFeedback, pairedTexture);
TextureDesc textureDesc = pairedTexture->getDesc();
textureDesc.initialState = desc.initialState;
textureDesc.keepInitialState = desc.keepInitialState;

SamplerFeedbackTexture* texture = new SamplerFeedbackTexture(m_Context, m_Resources, desc, textureDesc, pairedTexture);

HRESULT hr = m_Context.device8->CreateCommittedResource2(
&heapPropsDefault,
Expand Down Expand Up @@ -948,7 +952,11 @@ namespace nvrhi::d3d12
desc.samplerFeedbackMipRegionY = rdFeedback.SamplerFeedbackMipRegion.Height;
desc.samplerFeedbackMipRegionZ = rdFeedback.SamplerFeedbackMipRegion.Depth;

SamplerFeedbackTexture* texture = new SamplerFeedbackTexture(m_Context, m_Resources, desc, rdFeedback, pairedTexture);
TextureDesc textureDesc = pairedTexture->getDesc();
textureDesc.initialState = ResourceStates::Unknown;
textureDesc.keepInitialState = false;

SamplerFeedbackTexture* texture = new SamplerFeedbackTexture(m_Context, m_Resources, desc, textureDesc, pairedTexture);
texture->resource = pResource;

return SamplerFeedbackTextureHandle::Create(texture);
Expand Down Expand Up @@ -1119,11 +1127,33 @@ namespace nvrhi::d3d12
}
}

void CommandList::clearSamplerFeedbackTexture(ISamplerFeedbackTexture* _t)
void CommandList::clearSamplerFeedbackTexture(ISamplerFeedbackTexture* _texture)
{
SamplerFeedbackTexture* texture = checked_cast<SamplerFeedbackTexture*>(_texture);

m_ActiveCommandList->commandList->DiscardResource(texture->resource, nullptr);
}

void CommandList::decodeSamplerFeedbackTexture(IBuffer* _buffer, ISamplerFeedbackTexture* _texture, nvrhi::Format format)
{
SamplerFeedbackTexture* t = checked_cast<SamplerFeedbackTexture*>(_t);
Buffer* buffer = checked_cast<Buffer*>(_buffer);
SamplerFeedbackTexture* texture = checked_cast<SamplerFeedbackTexture*>(_texture);

m_ActiveCommandList->commandList->DiscardResource(t->resource, nullptr);
if (m_EnableAutomaticBarriers)
{
requireBufferState(buffer, ResourceStates::ResolveDest);
requireSamplerFeedbackTextureState(texture, ResourceStates::ResolveSource);
}
commitBarriers();

const DxgiFormatMapping& formatMapping = getDxgiFormatMapping(format);

m_ActiveCommandList->commandList4->ResolveSubresourceRegion(buffer->resource, 0, 0, 0, texture->resource, 0, nullptr, formatMapping.srvFormat, D3D12_RESOLVE_MODE_DECODE_SAMPLER_FEEDBACK);
}

void CommandList::setSamplerFeedbackTextureState(ISamplerFeedbackTexture* texture, ResourceStates stateBits)
{
requireSamplerFeedbackTextureState(texture, stateBits);
}

void CommandList::copyTexture(ITexture* _dst, const TextureSlice& dstSlice,
Expand Down

0 comments on commit 4e32b91

Please sign in to comment.