mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 12:51:42 +00:00
Implement hardware resolve path for both color and depth targets.
This commit is contained in:
parent
7487cfd337
commit
472b136272
7 changed files with 170 additions and 95 deletions
|
|
@ -27,6 +27,8 @@
|
||||||
//# define D3D12_DEBUG_LAYER_GPU_BASED_VALIDATION_ENABLED
|
//# define D3D12_DEBUG_LAYER_GPU_BASED_VALIDATION_ENABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//#define D3D12_DEBUG_SET_STABLE_POWER_STATE
|
||||||
|
|
||||||
// Old Windows SDK versions don't provide this macro, so we workaround it by making sure it is defined.
|
// Old Windows SDK versions don't provide this macro, so we workaround it by making sure it is defined.
|
||||||
#ifndef D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE
|
#ifndef D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE
|
||||||
#define D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)
|
#define D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)
|
||||||
|
|
@ -692,6 +694,20 @@ namespace plume {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static D3D12_RESOLVE_MODE toD3D12(RenderResolveMode resolveMode) {
|
||||||
|
switch (resolveMode) {
|
||||||
|
case RenderResolveMode::MIN:
|
||||||
|
return D3D12_RESOLVE_MODE_MIN;
|
||||||
|
case RenderResolveMode::MAX:
|
||||||
|
return D3D12_RESOLVE_MODE_MAX;
|
||||||
|
case RenderResolveMode::AVERAGE:
|
||||||
|
return D3D12_RESOLVE_MODE_AVERAGE;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown resolve mode.");
|
||||||
|
return D3D12_RESOLVE_MODE_AVERAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void setObjectName(ID3D12Object *object, const std::string &name) {
|
static void setObjectName(ID3D12Object *object, const std::string &name) {
|
||||||
const std::wstring wideCharName = Utf8ToUtf16(name);
|
const std::wstring wideCharName = Utf8ToUtf16(name);
|
||||||
object->SetName(wideCharName.c_str());
|
object->SetName(wideCharName.c_str());
|
||||||
|
|
@ -1916,7 +1932,7 @@ namespace plume {
|
||||||
resetSamplePositions();
|
resetSamplePositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandList::resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect) {
|
void D3D12CommandList::resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) {
|
||||||
assert(dstTexture != nullptr);
|
assert(dstTexture != nullptr);
|
||||||
assert(srcTexture != nullptr);
|
assert(srcTexture != nullptr);
|
||||||
|
|
||||||
|
|
@ -1931,7 +1947,7 @@ namespace plume {
|
||||||
}
|
}
|
||||||
|
|
||||||
setSamplePositions(interfaceDstTexture);
|
setSamplePositions(interfaceDstTexture);
|
||||||
d3d->ResolveSubresourceRegion(interfaceDstTexture->d3d, 0, dstX, dstY, interfaceSrcTexture->d3d, 0, (srcRect != nullptr) ? &rect : nullptr, toDXGI(interfaceDstTexture->desc.format), D3D12_RESOLVE_MODE_AVERAGE);
|
d3d->ResolveSubresourceRegion(interfaceDstTexture->d3d, 0, dstX, dstY, interfaceSrcTexture->d3d, 0, (srcRect != nullptr) ? &rect : nullptr, toDXGI(interfaceDstTexture->desc.format), toD3D12(resolveMode));
|
||||||
resetSamplePositions();
|
resetSamplePositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3373,6 +3389,10 @@ namespace plume {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef D3D12_DEBUG_SET_STABLE_POWER_STATE
|
||||||
|
d3d->SetStablePowerState(TRUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
D3D12MA::ALLOCATOR_DESC allocatorDesc = {};
|
D3D12MA::ALLOCATOR_DESC allocatorDesc = {};
|
||||||
allocatorDesc.pDevice = d3d;
|
allocatorDesc.pDevice = d3d;
|
||||||
allocatorDesc.pAdapter = adapter;
|
allocatorDesc.pAdapter = adapter;
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ namespace plume {
|
||||||
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
|
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
|
||||||
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||||
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||||
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect) override;
|
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
|
||||||
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
||||||
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
||||||
void discardTexture(const RenderTexture* texture) override;
|
void discardTexture(const RenderTexture* texture) override;
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ namespace plume {
|
||||||
virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0;
|
virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0;
|
||||||
virtual void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
|
virtual void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
|
||||||
virtual void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
|
virtual void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
|
||||||
virtual void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect = nullptr) = 0;
|
virtual void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect = nullptr, RenderResolveMode resolveMode = RenderResolveMode::AVERAGE) = 0;
|
||||||
virtual void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) = 0;
|
virtual void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) = 0;
|
||||||
virtual void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) = 0;
|
virtual void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) = 0;
|
||||||
virtual void discardTexture(const RenderTexture* texture) = 0; // D3D12 only.
|
virtual void discardTexture(const RenderTexture* texture) = 0; // D3D12 only.
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,12 @@ namespace plume {
|
||||||
CPU
|
CPU
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class RenderResolveMode {
|
||||||
|
MIN,
|
||||||
|
MAX,
|
||||||
|
AVERAGE
|
||||||
|
};
|
||||||
|
|
||||||
// Global functions.
|
// Global functions.
|
||||||
|
|
||||||
constexpr uint32_t RenderFormatSize(RenderFormat format) {
|
constexpr uint32_t RenderFormatSize(RenderFormat format) {
|
||||||
|
|
|
||||||
|
|
@ -3074,12 +3074,13 @@ namespace plume {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanCommandList::resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) {
|
void VulkanCommandList::resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) {
|
||||||
resolveTextureRegion(dstTexture, 0, 0, srcTexture, nullptr);
|
resolveTextureRegion(dstTexture, 0, 0, srcTexture, nullptr, RenderResolveMode::AVERAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanCommandList::resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect) {
|
void VulkanCommandList::resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) {
|
||||||
assert(dstTexture != nullptr);
|
assert(dstTexture != nullptr);
|
||||||
assert(srcTexture != nullptr);
|
assert(srcTexture != nullptr);
|
||||||
|
assert(resolveMode == RenderResolveMode::AVERAGE && "Vulkan only supports AVERAGE resolve mode.");
|
||||||
|
|
||||||
thread_local std::vector<VkImageResolve> imageResolves;
|
thread_local std::vector<VkImageResolve> imageResolves;
|
||||||
imageResolves.clear();
|
imageResolves.clear();
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ namespace plume {
|
||||||
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
|
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
|
||||||
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||||
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||||
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect) override;
|
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
|
||||||
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
||||||
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
||||||
void discardTexture(const RenderTexture* texture) override;
|
void discardTexture(const RenderTexture* texture) override;
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,9 @@ static bool g_vulkan = false;
|
||||||
static constexpr bool g_vulkan = true;
|
static constexpr bool g_vulkan = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static constexpr bool g_hardwareResolve = true;
|
||||||
|
static constexpr bool g_hardwareDepthResolve = true;
|
||||||
|
|
||||||
static std::unique_ptr<RenderInterface> g_interface;
|
static std::unique_ptr<RenderInterface> g_interface;
|
||||||
static std::unique_ptr<RenderDevice> g_device;
|
static std::unique_ptr<RenderDevice> g_device;
|
||||||
|
|
||||||
|
|
@ -3024,10 +3027,35 @@ static bool PopulateBarriersForStretchRect(GuestSurface* renderTarget, GuestSurf
|
||||||
{
|
{
|
||||||
if (surface != nullptr && !surface->destinationTextures.empty())
|
if (surface != nullptr && !surface->destinationTextures.empty())
|
||||||
{
|
{
|
||||||
AddBarrier(surface, RenderTextureLayout::SHADER_READ);
|
const bool multiSampling = surface->sampleCount != RenderSampleCount::COUNT_1;
|
||||||
|
|
||||||
|
RenderTextureLayout srcLayout;
|
||||||
|
RenderTextureLayout dstLayout;
|
||||||
|
bool shaderResolve = true;
|
||||||
|
|
||||||
|
if (multiSampling && g_hardwareResolve)
|
||||||
|
{
|
||||||
|
// Hardware depth resolve is only supported on D3D12 when programmable sample positions are available.
|
||||||
|
bool hardwareDepthResolveAvailable = g_hardwareDepthResolve && !g_vulkan && g_capabilities.sampleLocations;
|
||||||
|
|
||||||
|
if (surface->format != RenderFormat::D32_FLOAT || hardwareDepthResolveAvailable)
|
||||||
|
{
|
||||||
|
srcLayout = RenderTextureLayout::RESOLVE_SOURCE;
|
||||||
|
dstLayout = RenderTextureLayout::RESOLVE_DEST;
|
||||||
|
shaderResolve = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shaderResolve)
|
||||||
|
{
|
||||||
|
srcLayout = RenderTextureLayout::SHADER_READ;
|
||||||
|
dstLayout = (surface->format == RenderFormat::D32_FLOAT ? RenderTextureLayout::DEPTH_WRITE : RenderTextureLayout::COLOR_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddBarrier(surface, srcLayout);
|
||||||
|
|
||||||
for (const auto texture : surface->destinationTextures)
|
for (const auto texture : surface->destinationTextures)
|
||||||
AddBarrier(texture, texture->format == RenderFormat::D32_FLOAT ? RenderTextureLayout::DEPTH_WRITE : RenderTextureLayout::COLOR_WRITE);
|
AddBarrier(texture, dstLayout);
|
||||||
|
|
||||||
addedAny = true;
|
addedAny = true;
|
||||||
}
|
}
|
||||||
|
|
@ -3048,113 +3076,133 @@ static void ExecutePendingStretchRectCommands(GuestSurface* renderTarget, GuestS
|
||||||
|
|
||||||
for (const auto texture : surface->destinationTextures)
|
for (const auto texture : surface->destinationTextures)
|
||||||
{
|
{
|
||||||
RenderPipeline* pipeline = nullptr;
|
bool shaderResolve = true;
|
||||||
|
|
||||||
if (multiSampling)
|
if (multiSampling && g_hardwareResolve)
|
||||||
{
|
{
|
||||||
uint32_t pipelineIndex = 0;
|
bool hardwareDepthResolveAvailable = g_hardwareDepthResolve && !g_vulkan && g_capabilities.sampleLocations;
|
||||||
|
|
||||||
switch (surface->sampleCount)
|
if (surface->format != RenderFormat::D32_FLOAT || hardwareDepthResolveAvailable)
|
||||||
{
|
{
|
||||||
case RenderSampleCount::COUNT_2:
|
if (surface->format == RenderFormat::D32_FLOAT)
|
||||||
pipelineIndex = 0;
|
commandList->resolveTextureRegion(texture->texture, 0, 0, surface->texture, nullptr, RenderResolveMode::MIN);
|
||||||
break;
|
else
|
||||||
case RenderSampleCount::COUNT_4:
|
commandList->resolveTexture(texture->texture, surface->texture);
|
||||||
pipelineIndex = 1;
|
|
||||||
break;
|
|
||||||
case RenderSampleCount::COUNT_8:
|
|
||||||
pipelineIndex = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false && "Unsupported MSAA sample count");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture->format == RenderFormat::D32_FLOAT)
|
shaderResolve = false;
|
||||||
{
|
|
||||||
pipeline = g_resolveMsaaDepthPipelines[pipelineIndex].get();
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (shaderResolve)
|
||||||
|
{
|
||||||
|
RenderPipeline* pipeline = nullptr;
|
||||||
|
|
||||||
|
if (multiSampling)
|
||||||
{
|
{
|
||||||
auto& resolveMsaaColorPipeline = g_resolveMsaaColorPipelines[surface->format][pipelineIndex];
|
uint32_t pipelineIndex = 0;
|
||||||
if (resolveMsaaColorPipeline == nullptr)
|
|
||||||
|
switch (surface->sampleCount)
|
||||||
{
|
{
|
||||||
RenderGraphicsPipelineDesc desc;
|
case RenderSampleCount::COUNT_2:
|
||||||
desc.pipelineLayout = g_pipelineLayout.get();
|
pipelineIndex = 0;
|
||||||
desc.vertexShader = g_copyShader.get();
|
break;
|
||||||
desc.pixelShader = g_resolveMsaaColorShaders[pipelineIndex].get();
|
case RenderSampleCount::COUNT_4:
|
||||||
desc.renderTargetFormat[0] = texture->format;
|
pipelineIndex = 1;
|
||||||
desc.renderTargetBlend[0] = RenderBlendDesc::Copy();
|
break;
|
||||||
desc.renderTargetCount = 1;
|
case RenderSampleCount::COUNT_8:
|
||||||
resolveMsaaColorPipeline = g_device->createGraphicsPipeline(desc);
|
pipelineIndex = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "Unsupported MSAA sample count");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline = resolveMsaaColorPipeline.get();
|
if (texture->format == RenderFormat::D32_FLOAT)
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (texture->format == RenderFormat::D32_FLOAT)
|
|
||||||
{
|
|
||||||
pipeline = g_copyDepthPipeline.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto& copyColorPipeline = g_copyColorPipelines[surface->format];
|
|
||||||
if (copyColorPipeline == nullptr)
|
|
||||||
{
|
{
|
||||||
RenderGraphicsPipelineDesc desc;
|
pipeline = g_resolveMsaaDepthPipelines[pipelineIndex].get();
|
||||||
desc.pipelineLayout = g_pipelineLayout.get();
|
|
||||||
desc.vertexShader = g_copyShader.get();
|
|
||||||
desc.pixelShader = g_copyColorShader.get();
|
|
||||||
desc.renderTargetFormat[0] = texture->format;
|
|
||||||
desc.renderTargetBlend[0] = RenderBlendDesc::Copy();
|
|
||||||
desc.renderTargetCount = 1;
|
|
||||||
copyColorPipeline = g_device->createGraphicsPipeline(desc);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto& resolveMsaaColorPipeline = g_resolveMsaaColorPipelines[surface->format][pipelineIndex];
|
||||||
|
if (resolveMsaaColorPipeline == nullptr)
|
||||||
|
{
|
||||||
|
RenderGraphicsPipelineDesc desc;
|
||||||
|
desc.pipelineLayout = g_pipelineLayout.get();
|
||||||
|
desc.vertexShader = g_copyShader.get();
|
||||||
|
desc.pixelShader = g_resolveMsaaColorShaders[pipelineIndex].get();
|
||||||
|
desc.renderTargetFormat[0] = texture->format;
|
||||||
|
desc.renderTargetBlend[0] = RenderBlendDesc::Copy();
|
||||||
|
desc.renderTargetCount = 1;
|
||||||
|
resolveMsaaColorPipeline = g_device->createGraphicsPipeline(desc);
|
||||||
|
}
|
||||||
|
|
||||||
pipeline = copyColorPipeline.get();
|
pipeline = resolveMsaaColorPipeline.get();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (texture->framebuffer == nullptr)
|
|
||||||
{
|
|
||||||
if (texture->format == RenderFormat::D32_FLOAT)
|
|
||||||
{
|
|
||||||
RenderFramebufferDesc desc;
|
|
||||||
desc.depthAttachment = texture->texture;
|
|
||||||
texture->framebuffer = g_device->createFramebuffer(desc);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RenderFramebufferDesc desc;
|
if (texture->format == RenderFormat::D32_FLOAT)
|
||||||
desc.colorAttachments = const_cast<const RenderTexture**>(&texture->texture);
|
{
|
||||||
desc.colorAttachmentsCount = 1;
|
pipeline = g_copyDepthPipeline.get();
|
||||||
texture->framebuffer = g_device->createFramebuffer(desc);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto& copyColorPipeline = g_copyColorPipelines[surface->format];
|
||||||
|
if (copyColorPipeline == nullptr)
|
||||||
|
{
|
||||||
|
RenderGraphicsPipelineDesc desc;
|
||||||
|
desc.pipelineLayout = g_pipelineLayout.get();
|
||||||
|
desc.vertexShader = g_copyShader.get();
|
||||||
|
desc.pixelShader = g_copyColorShader.get();
|
||||||
|
desc.renderTargetFormat[0] = texture->format;
|
||||||
|
desc.renderTargetBlend[0] = RenderBlendDesc::Copy();
|
||||||
|
desc.renderTargetCount = 1;
|
||||||
|
copyColorPipeline = g_device->createGraphicsPipeline(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline = copyColorPipeline.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (g_framebuffer != texture->framebuffer.get())
|
if (texture->framebuffer == nullptr)
|
||||||
{
|
{
|
||||||
commandList->setFramebuffer(texture->framebuffer.get());
|
if (texture->format == RenderFormat::D32_FLOAT)
|
||||||
g_framebuffer = texture->framebuffer.get();
|
{
|
||||||
}
|
RenderFramebufferDesc desc;
|
||||||
|
desc.depthAttachment = texture->texture;
|
||||||
|
texture->framebuffer = g_device->createFramebuffer(desc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenderFramebufferDesc desc;
|
||||||
|
desc.colorAttachments = const_cast<const RenderTexture**>(&texture->texture);
|
||||||
|
desc.colorAttachmentsCount = 1;
|
||||||
|
texture->framebuffer = g_device->createFramebuffer(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
commandList->setPipeline(pipeline);
|
if (g_framebuffer != texture->framebuffer.get())
|
||||||
commandList->setViewports(RenderViewport(0.0f, 0.0f, float(texture->width), float(texture->height), 0.0f, 1.0f));
|
{
|
||||||
commandList->setScissors(RenderRect(0, 0, texture->width, texture->height));
|
commandList->setFramebuffer(texture->framebuffer.get());
|
||||||
commandList->setGraphicsPushConstants(0, &surface->descriptorIndex, 0, sizeof(uint32_t));
|
g_framebuffer = texture->framebuffer.get();
|
||||||
commandList->drawInstanced(6, 1, 0, 0);
|
}
|
||||||
|
|
||||||
g_dirtyStates.renderTargetAndDepthStencil = true;
|
commandList->setPipeline(pipeline);
|
||||||
g_dirtyStates.viewport = true;
|
commandList->setViewports(RenderViewport(0.0f, 0.0f, float(texture->width), float(texture->height), 0.0f, 1.0f));
|
||||||
g_dirtyStates.pipelineState = true;
|
commandList->setScissors(RenderRect(0, 0, texture->width, texture->height));
|
||||||
g_dirtyStates.scissorRect = true;
|
commandList->setGraphicsPushConstants(0, &surface->descriptorIndex, 0, sizeof(uint32_t));
|
||||||
|
commandList->drawInstanced(6, 1, 0, 0);
|
||||||
|
|
||||||
if (g_vulkan)
|
g_dirtyStates.renderTargetAndDepthStencil = true;
|
||||||
{
|
g_dirtyStates.viewport = true;
|
||||||
g_dirtyStates.vertexShaderConstants = true; // The push constant call invalidates vertex shader constants.
|
g_dirtyStates.pipelineState = true;
|
||||||
g_dirtyStates.depthBias = true; // Static depth bias in copy pipeline invalidates dynamic depth bias.
|
g_dirtyStates.scissorRect = true;
|
||||||
|
|
||||||
|
if (g_vulkan)
|
||||||
|
{
|
||||||
|
g_dirtyStates.vertexShaderConstants = true; // The push constant call invalidates vertex shader constants.
|
||||||
|
g_dirtyStates.depthBias = true; // Static depth bias in copy pipeline invalidates dynamic depth bias.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->sourceSurface = nullptr;
|
texture->sourceSurface = nullptr;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue