Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 0 additions & 217 deletions MarathonRecomp/gpu/cache/pipeline_state_cache.h

Large diffs are not rendered by default.

97 changes: 86 additions & 11 deletions MarathonRecomp/gpu/rhi/plume_d3d12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ namespace plume {
return DXGI_FORMAT_R32_TYPELESS;
case RenderFormat::D32_FLOAT:
return DXGI_FORMAT_D32_FLOAT;
case RenderFormat::D32_FLOAT_S8_UINT:
// In order to be able to create both depth-stencil and shader resource views,
// we must use R32G8X24_TYPELESS as the base type and specialize later.
return DXGI_FORMAT_R32G8X24_TYPELESS;
case RenderFormat::R32_FLOAT:
return DXGI_FORMAT_R32_FLOAT;
case RenderFormat::R32_UINT:
Expand Down Expand Up @@ -224,6 +228,29 @@ namespace plume {
}
}

static DXGI_FORMAT toDXGITextureView(RenderFormat format) {
const DXGI_FORMAT dxgiFormat = toDXGI(format);
if (dxgiFormat == DXGI_FORMAT_D32_FLOAT) {
// D3D12 and Vulkan disagree on whether D32 is usable as a texture view format.
// We just make D3D12 use R32 instead.
return DXGI_FORMAT_R32_FLOAT;
}
if (dxgiFormat == DXGI_FORMAT_R32G8X24_TYPELESS) {
// Specialize into depth view of depth-stencil texture.
return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
}
return dxgiFormat;
}

static DXGI_FORMAT toDXGIDepthStencilView(RenderFormat format) {
const DXGI_FORMAT dxgiFormat = toDXGI(format);
if (dxgiFormat == DXGI_FORMAT_R32G8X24_TYPELESS) {
// Specialize into full depth-stencil view.
return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
}
return dxgiFormat;
}

static D3D12_BLEND toD3D12(RenderBlend blend) {
switch (blend) {
case RenderBlend::ZERO:
Expand Down Expand Up @@ -472,6 +499,30 @@ namespace plume {
}
}

static D3D12_STENCIL_OP toD3D12(RenderStencilOp function) {
switch (function) {
case RenderStencilOp::KEEP:
return D3D12_STENCIL_OP_KEEP;
case RenderStencilOp::ZERO:
return D3D12_STENCIL_OP_ZERO;
case RenderStencilOp::REPLACE:
return D3D12_STENCIL_OP_REPLACE;
case RenderStencilOp::INCREMENT_AND_CLAMP:
return D3D12_STENCIL_OP_INCR_SAT;
case RenderStencilOp::DECREMENT_AND_CLAMP:
return D3D12_STENCIL_OP_DECR_SAT;
case RenderStencilOp::INVERT:
return D3D12_STENCIL_OP_INVERT;
case RenderStencilOp::INCREMENT_AND_WRAP:
return D3D12_STENCIL_OP_INCR;
case RenderStencilOp::DECREMENT_AND_WRAP:
return D3D12_STENCIL_OP_DECR;
default:
assert(false && "Unknown stencil operation.");
return D3D12_STENCIL_OP_KEEP;
}
}

static D3D12_PRIMITIVE_TOPOLOGY toD3D12(RenderPrimitiveTopology topology) {
switch (topology) {
case RenderPrimitiveTopology::POINT_LIST:
Expand Down Expand Up @@ -1664,12 +1715,14 @@ namespace plume {

void D3D12CommandList::drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) {
checkTopology();
checkStencilRef();
checkFramebufferSamplePositions();
d3d->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
}

void D3D12CommandList::drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) {
checkTopology();
checkStencilRef();
checkFramebufferSamplePositions();
d3d->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
}
Expand Down Expand Up @@ -1900,7 +1953,7 @@ namespace plume {
d3d->ClearRenderTargetView(targetFramebuffer->colorHandles[attachmentIndex], colorValue.rgba, clearRectsCount, (clearRectsCount > 0) ? rectVector.data() : nullptr);
}

void D3D12CommandList::clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) {
void D3D12CommandList::clearDepthStencil(bool clearDepth, bool clearStencil, float depthValue, uint32_t stencilValue, const RenderRect *clearRects, uint32_t clearRectsCount) {
assert(targetFramebuffer != nullptr);
assert(targetFramebuffer->depthHandle.ptr != 0);
assert((clearRectsCount == 0) || (clearRects != nullptr));
Expand All @@ -1916,8 +1969,13 @@ namespace plume {
}

D3D12_CLEAR_FLAGS clearFlags = {};
clearFlags |= clearDepth ? D3D12_CLEAR_FLAG_DEPTH : D3D12_CLEAR_FLAGS(0);
d3d->ClearDepthStencilView(targetFramebuffer->depthHandle, clearFlags, depthValue, 0, clearRectsCount, (clearRectsCount > 0) ? rectVector.data() : nullptr);
if (clearDepth) {
clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
}
if (clearStencil) {
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
}
d3d->ClearDepthStencilView(targetFramebuffer->depthHandle, clearFlags, depthValue, stencilValue, clearRectsCount, (clearRectsCount > 0) ? rectVector.data() : nullptr);
}

void D3D12CommandList::copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) {
Expand Down Expand Up @@ -2085,6 +2143,17 @@ namespace plume {
activeTopology = graphicsPipeline->topology;
}
}

void D3D12CommandList::checkStencilRef() {
assert(activeGraphicsPipeline != nullptr);
assert(activeGraphicsPipeline->type == D3D12Pipeline::Type::Graphics);

const D3D12GraphicsPipeline *graphicsPipeline = static_cast<const D3D12GraphicsPipeline *>(activeGraphicsPipeline);
if (activeStencilRef != graphicsPipeline->stencilRef) {
d3d->OMSetStencilRef(graphicsPipeline->stencilRef);
activeStencilRef = graphicsPipeline->stencilRef;
}
}

void D3D12CommandList::checkFramebufferSamplePositions() {
if (!targetFramebufferSamplePositionsSet && (targetFramebuffer != nullptr)) {
Expand Down Expand Up @@ -2430,16 +2499,11 @@ namespace plume {
assert(texture != nullptr);

this->texture = texture;
this->format = toDXGI(desc.format);
this->format = toDXGITextureView(desc.format);
this->dimension = desc.dimension;
this->mipLevels = desc.mipLevels;
this->mipSlice = desc.mipSlice;
this->shader4ComponentMapping = toD3D12(desc.componentMapping);

// D3D12 and Vulkan disagree on whether D32 is usable as a texture view format. We just make D3D12 use R32 instead.
if (format == DXGI_FORMAT_D32_FLOAT) {
format = DXGI_FORMAT_R32_FLOAT;
}
}

D3D12TextureView::~D3D12TextureView() { }
Expand Down Expand Up @@ -2566,7 +2630,7 @@ namespace plume {
targetHeapDepth = true;

D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = toDXGI(desc.format);
dsvDesc.Format = toDXGIDepthStencilView(desc.format);

const bool isMSAA = (desc.multisampling.sampleCount > RenderSampleCount::COUNT_1);
switch (desc.dimension) {
Expand Down Expand Up @@ -2820,6 +2884,17 @@ namespace plume {
psoDesc.DepthStencilState.DepthEnable = desc.depthEnabled;
psoDesc.DepthStencilState.DepthWriteMask = desc.depthWriteEnabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
psoDesc.DepthStencilState.DepthFunc = toD3D12(desc.depthFunction);
psoDesc.DepthStencilState.StencilEnable = desc.stencilEnabled;
psoDesc.DepthStencilState.StencilReadMask = desc.stencilReadMask;
psoDesc.DepthStencilState.StencilWriteMask = desc.stencilWriteMask;
psoDesc.DepthStencilState.FrontFace.StencilFailOp = toD3D12(desc.stencilFrontFace.failOp);
psoDesc.DepthStencilState.FrontFace.StencilDepthFailOp = toD3D12(desc.stencilFrontFace.depthFailOp);
psoDesc.DepthStencilState.FrontFace.StencilPassOp = toD3D12(desc.stencilFrontFace.passOp);
psoDesc.DepthStencilState.FrontFace.StencilFunc = toD3D12(desc.stencilFrontFace.compareFunction);
psoDesc.DepthStencilState.BackFace.StencilFailOp = toD3D12(desc.stencilBackFace.failOp);
psoDesc.DepthStencilState.BackFace.StencilDepthFailOp = toD3D12(desc.stencilBackFace.depthFailOp);
psoDesc.DepthStencilState.BackFace.StencilPassOp = toD3D12(desc.stencilBackFace.passOp);
psoDesc.DepthStencilState.BackFace.StencilFunc = toD3D12(desc.stencilBackFace.compareFunction);
psoDesc.NumRenderTargets = desc.renderTargetCount;
psoDesc.BlendState.AlphaToCoverageEnable = desc.alphaToCoverageEnabled;

Expand All @@ -2840,7 +2915,7 @@ namespace plume {
targetDesc.RenderTargetWriteMask = renderDesc.renderTargetWriteMask;
}

psoDesc.DSVFormat = toDXGI(desc.depthTargetFormat);
psoDesc.DSVFormat = toDXGIDepthStencilView(desc.depthTargetFormat);

std::vector<D3D12_INPUT_ELEMENT_DESC> inputElements;
for (uint32_t i = 0; i < desc.inputElementsCount; i++) {
Expand Down
5 changes: 4 additions & 1 deletion MarathonRecomp/gpu/rhi/plume_d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ namespace plume {
const D3D12GraphicsPipeline *activeGraphicsPipeline = nullptr;
bool descriptorHeapsSet = false;
D3D12_PRIMITIVE_TOPOLOGY activeTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
uint32_t activeStencilRef = 0;
bool activeSamplePositions = false;

D3D12CommandList(D3D12Device *device, RenderCommandListType type);
Expand Down Expand Up @@ -199,7 +200,7 @@ namespace plume {
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void clearDepthStencil(bool clearDepth, bool clearStencil, float depthValue, uint32_t stencilValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
Expand All @@ -214,6 +215,7 @@ namespace plume {
void checkDescriptorHeaps();
void notifyDescriptorHeapWasChangedExternally();
void checkTopology();
void checkStencilRef();
void checkFramebufferSamplePositions();
void setSamplePositions(const RenderTexture *texture);
void resetSamplePositions();
Expand Down Expand Up @@ -384,6 +386,7 @@ namespace plume {
ID3D12PipelineState *d3d = nullptr;
std::vector<RenderInputSlot> inputSlots;
D3D12_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
uint32_t stencilRef = 0;

D3D12GraphicsPipeline(D3D12Device *device, const RenderGraphicsPipelineDesc &desc);
~D3D12GraphicsPipeline() override;
Expand Down
6 changes: 5 additions & 1 deletion MarathonRecomp/gpu/rhi/plume_render_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ namespace plume {
virtual void setFramebuffer(const RenderFramebuffer *framebuffer) = 0;
virtual void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) = 0;
virtual void clearColor(uint32_t attachmentIndex = 0, RenderColor colorValue = RenderColor(), const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void clearDepth(bool clearDepth = true, float depthValue = 1.0f, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void clearDepthStencil(bool clearDepth = true, bool clearStencil = true, float depthValue = 1.0f, uint32_t stencilValue = 0, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) = 0;
virtual void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX = 0, uint32_t dstY = 0, uint32_t dstZ = 0, const RenderBox *srcBox = nullptr) = 0;
virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0;
Expand Down Expand Up @@ -191,6 +191,10 @@ namespace plume {
inline void setScissors(const RenderRect &scissorRect) {
setScissors(&scissorRect, 1);
}

inline void clearDepth(bool clearDepth = true, float depthValue = 1.0f, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) {
clearDepthStencil(clearDepth, false, depthValue, 0, clearRects, clearRectsCount);
}
};

struct RenderCommandQueue {
Expand Down
43 changes: 43 additions & 0 deletions MarathonRecomp/gpu/rhi/plume_render_interface_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ namespace plume {
R16G16_SINT,
R32_TYPELESS,
D32_FLOAT,
D32_FLOAT_S8_UINT,
R32_FLOAT,
R32_UINT,
R32_SINT,
Expand Down Expand Up @@ -226,6 +227,18 @@ namespace plume {
ALWAYS
};

enum class RenderStencilOp {
UNKNOWN,
KEEP,
ZERO,
REPLACE,
INCREMENT_AND_CLAMP,
DECREMENT_AND_CLAMP,
INVERT,
INCREMENT_AND_WRAP,
DECREMENT_AND_WRAP
};

enum class RenderInputSlotClassification {
UNKNOWN,
PER_VERTEX_DATA,
Expand Down Expand Up @@ -523,6 +536,7 @@ namespace plume {
case RenderFormat::R32G32_FLOAT:
case RenderFormat::R32G32_UINT:
case RenderFormat::R32G32_SINT:
case RenderFormat::D32_FLOAT_S8_UINT: // Has 24 unused bits
return 8;
case RenderFormat::R8G8B8A8_TYPELESS:
case RenderFormat::R8G8B8A8_UNORM:
Expand Down Expand Up @@ -621,6 +635,7 @@ namespace plume {
case RenderFormat::R16G16_SINT:
case RenderFormat::R32_TYPELESS:
case RenderFormat::D32_FLOAT:
case RenderFormat::D32_FLOAT_S8_UINT:
case RenderFormat::R32_FLOAT:
case RenderFormat::R32_UINT:
case RenderFormat::R32_SINT:
Expand Down Expand Up @@ -670,6 +685,21 @@ namespace plume {
}
};

constexpr bool RenderFormatIsDepth(RenderFormat format) {
switch (format) {
case RenderFormat::D16_UNORM:
case RenderFormat::D32_FLOAT:
case RenderFormat::D32_FLOAT_S8_UINT:
return true;
default:
return false;
}
}

constexpr bool RenderFormatIsStencil(RenderFormat format) {
return format == RenderFormat::D32_FLOAT_S8_UINT;
}

// Concrete structs.

struct RenderColor {
Expand Down Expand Up @@ -1158,6 +1188,13 @@ namespace plume {
}
};

struct RenderStencilFaceDesc {
RenderStencilOp passOp = RenderStencilOp::KEEP;
RenderStencilOp failOp = RenderStencilOp::KEEP;
RenderStencilOp depthFailOp = RenderStencilOp::KEEP;
RenderComparisonFunction compareFunction = RenderComparisonFunction::ALWAYS;
};

struct RenderSpecConstant {
uint32_t index = 0;
uint32_t value = 0;
Expand Down Expand Up @@ -1198,6 +1235,12 @@ namespace plume {
bool dynamicDepthBiasEnabled = false;
bool depthEnabled = false;
bool depthWriteEnabled = false;
bool stencilEnabled = false;
uint32_t stencilReadMask = 0xFFFFFFFF;
uint32_t stencilWriteMask = 0xFFFFFFFF;
uint32_t stencilReference = 0;
RenderStencilFaceDesc stencilFrontFace;
RenderStencilFaceDesc stencilBackFace;
RenderMultisampling multisampling;
bool alphaToCoverageEnabled = false;
RenderPrimitiveTopology primitiveTopology = RenderPrimitiveTopology::TRIANGLE_LIST;
Expand Down
Loading
Loading