mirror of
https://github.com/rt64/rt64.git
synced 2025-03-14 13:21:24 +00:00
Alternate resolve path with rasterization supported.
This commit is contained in:
parent
d2fd395801
commit
afbc5e41e3
@ -459,6 +459,9 @@ build_pixel_shader( rt64 "src/shaders/RtCopyDepthToColorPS.hlsl")
|
||||
build_pixel_shader( rt64 "src/shaders/RtCopyDepthToColorPS.hlsl" "src/shaders/RtCopyDepthToColorPSMS.hlsl" "-D MULTISAMPLING")
|
||||
build_pixel_shader( rt64 "src/shaders/TextureCopyPS.hlsl")
|
||||
build_compute_shader(rt64 "src/shaders/TextureDecodeCS.hlsl")
|
||||
build_pixel_shader( rt64 "src/shaders/TextureResolvePS.hlsl" "src/shaders/TextureResolveSamples2XPS.hlsl" "-D SAMPLES_2X")
|
||||
build_pixel_shader( rt64 "src/shaders/TextureResolvePS.hlsl" "src/shaders/TextureResolveSamples4XPS.hlsl" "-D SAMPLES_4X")
|
||||
build_pixel_shader( rt64 "src/shaders/TextureResolvePS.hlsl" "src/shaders/TextureResolveSamples8XPS.hlsl" "-D SAMPLES_8X")
|
||||
build_pixel_shader( rt64 "src/shaders/VideoInterfacePS.hlsl" "src/shaders/VideoInterfacePSRegular.hlsl")
|
||||
build_pixel_shader( rt64 "src/shaders/VideoInterfacePS.hlsl" "src/shaders/VideoInterfacePSPixel.hlsl" "-D PIXEL_ANTIALIASING")
|
||||
build_vertex_shader( rt64 "src/shaders/FullScreenVS.hlsl")
|
||||
|
@ -18,6 +18,7 @@ namespace RT64 {
|
||||
j["resolution"] = cfg.resolution;
|
||||
j["displayBuffering"] = cfg.displayBuffering;
|
||||
j["antialiasing"] = cfg.antialiasing;
|
||||
j["hardwareResolve"] = cfg.hardwareResolve;
|
||||
j["resolutionMultiplier"] = cfg.resolutionMultiplier;
|
||||
j["downsampleMultiplier"] = cfg.downsampleMultiplier;
|
||||
j["filtering"] = cfg.filtering;
|
||||
@ -40,6 +41,7 @@ namespace RT64 {
|
||||
cfg.resolution = j.value("resolution", defaultCfg.resolution);
|
||||
cfg.displayBuffering = j.value("displayBuffering", defaultCfg.displayBuffering);
|
||||
cfg.antialiasing = j.value("antialiasing", defaultCfg.antialiasing);
|
||||
cfg.hardwareResolve = j.value("hardwareResolve", defaultCfg.hardwareResolve);
|
||||
cfg.resolutionMultiplier = j.value("resolutionMultiplier", defaultCfg.resolutionMultiplier);
|
||||
cfg.downsampleMultiplier = j.value("downsampleMultiplier", defaultCfg.downsampleMultiplier);
|
||||
cfg.filtering = j.value("filtering", defaultCfg.filtering);
|
||||
@ -70,6 +72,7 @@ namespace RT64 {
|
||||
resolution = Resolution::WindowIntegerScale;
|
||||
displayBuffering = DisplayBuffering::Double;
|
||||
antialiasing = Antialiasing::None;
|
||||
hardwareResolve = true;
|
||||
resolutionMultiplier = 2.0f;
|
||||
downsampleMultiplier = 1;
|
||||
filtering = Filtering::AntiAliasedPixelScaling;
|
||||
|
@ -80,6 +80,7 @@ namespace RT64 {
|
||||
Resolution resolution;
|
||||
DisplayBuffering displayBuffering;
|
||||
Antialiasing antialiasing;
|
||||
bool hardwareResolve;
|
||||
double resolutionMultiplier;
|
||||
int downsampleMultiplier;
|
||||
Filtering filtering;
|
||||
|
@ -227,7 +227,7 @@ namespace RT64 {
|
||||
|
||||
// Create the shader library.
|
||||
const RenderMultisampling multisampling = RasterShader::generateMultisamplingPattern(userConfig.msaaSampleCount(), device->getCapabilities().sampleLocations);
|
||||
shaderLibrary = std::make_unique<ShaderLibrary>(usesHDR);
|
||||
shaderLibrary = std::make_unique<ShaderLibrary>(usesHDR, userConfig.hardwareResolve);
|
||||
shaderLibrary->setupCommonShaders(renderInterface.get(), device.get());
|
||||
shaderLibrary->setupMultisamplingShaders(renderInterface.get(), device.get(), multisampling);
|
||||
|
||||
|
@ -215,7 +215,7 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
// Resolve the target if necessary.
|
||||
colorTarget.resolveTarget(renderWorker);
|
||||
colorTarget.resolveTarget(renderWorker, shaderLibrary);
|
||||
|
||||
cmdListCopies.copyRegionTargets.insert(&colorTarget);
|
||||
|
||||
|
@ -308,11 +308,9 @@ namespace RT64 {
|
||||
RenderCommandList *commandList = ext.presentGraphicsWorker->commandList.get();
|
||||
commandList->begin();
|
||||
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(swapChainTexture, RenderTextureLayout::COLOR_WRITE));
|
||||
commandList->setFramebuffer(swapChainFramebuffer);
|
||||
commandList->clearColor();
|
||||
|
||||
|
||||
VIRenderer::RenderParams renderParams;
|
||||
if (colorTarget != nullptr) {
|
||||
VIRenderer::RenderParams renderParams;
|
||||
renderParams.device = ext.device;
|
||||
renderParams.commandList = commandList;
|
||||
renderParams.swapChain = ext.swapChain;
|
||||
@ -332,21 +330,24 @@ namespace RT64 {
|
||||
renderParams.downsamplingScale = colorTarget->downsampleMultiplier;
|
||||
}
|
||||
else {
|
||||
colorTarget->resolveTarget(ext.presentGraphicsWorker);
|
||||
colorTarget->resolveTarget(ext.presentGraphicsWorker, ext.shaderLibrary);
|
||||
renderParams.texture = colorTarget->getResolvedTexture();
|
||||
renderParams.textureWidth = colorTarget->width;
|
||||
renderParams.textureHeight = colorTarget->height;
|
||||
}
|
||||
}
|
||||
|
||||
commandList->setFramebuffer(swapChainFramebuffer);
|
||||
commandList->clearColor();
|
||||
|
||||
if (renderParams.texture != nullptr) {
|
||||
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(renderParams.texture, RenderTextureLayout::SHADER_READ));
|
||||
viRenderer->render(renderParams);
|
||||
}
|
||||
|
||||
{
|
||||
RenderHookDraw *drawHook = GetRenderHookDraw();
|
||||
if (drawHook) {
|
||||
drawHook(commandList, swapChainFramebuffer);
|
||||
}
|
||||
RenderHookDraw *drawHook = GetRenderHookDraw();
|
||||
if (drawHook != nullptr) {
|
||||
drawHook(commandList, swapChainFramebuffer);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -2082,6 +2082,12 @@ namespace RT64 {
|
||||
|
||||
genConfigChanged = ImGui::Checkbox("Three-Point Filtering", &userConfig.threePointFiltering) || genConfigChanged;
|
||||
genConfigChanged = ImGui::Checkbox("High Performance State", &userConfig.idleWorkActive) || genConfigChanged;
|
||||
|
||||
if (ImGui::Checkbox("Hardware Resolve", &userConfig.hardwareResolve)) {
|
||||
// Update shader library to automatically control all logic around hardware resolve.
|
||||
ext.shaderLibrary->usesHardwareResolve = userConfig.hardwareResolve;
|
||||
genConfigChanged = true;
|
||||
}
|
||||
|
||||
// Emulator configuration.
|
||||
ImGui::NewLine();
|
||||
|
@ -749,7 +749,7 @@ namespace RT64 {
|
||||
// Do the resolve if using MSAA while target override is active and we're on the correct framebuffer pair index.
|
||||
if (usingMSAA && (overrideTarget != nullptr) && ((uint32_t)overrideTargetFbPairIndex == f)) {
|
||||
overrideTarget->resize(ext.workloadGraphicsWorker, colorTarget->width, colorTarget->height);
|
||||
overrideTarget->resolveFromTarget(ext.workloadGraphicsWorker, colorTarget);
|
||||
overrideTarget->resolveFromTarget(ext.workloadGraphicsWorker, colorTarget, ext.shaderLibrary);
|
||||
}
|
||||
|
||||
const uint64_t writeTimestamp = fbManager.nextWriteTimestamp();
|
||||
|
@ -744,7 +744,7 @@ namespace RT64 {
|
||||
worker->commandList->setFramebuffer(nullptr);
|
||||
|
||||
// Resolve the color target if necessary before using it as the RT scene background.
|
||||
colorTarget->resolveTarget(worker);
|
||||
colorTarget->resolveTarget(worker, shaderLibrary);
|
||||
worker->commandList->barriers(RenderBarrierStage::COMPUTE, RenderTextureBarrier(colorTarget->getResolvedTexture(), RenderTextureLayout::SHADER_READ));
|
||||
|
||||
if (rtResources->transitionOutputBuffers) {
|
||||
@ -1254,7 +1254,7 @@ namespace RT64 {
|
||||
|
||||
// Resolve the interleaved scene.
|
||||
// TODO: Depth textures need to be thrown into a separate view vector for multisampled textures.
|
||||
fbStorage->colorTarget->resolveTarget(worker);
|
||||
fbStorage->colorTarget->resolveTarget(worker, shaderLibrary);
|
||||
|
||||
interleavedBarriers.emplace_back(RenderTextureBarrier(colorRenderTarget->texture.get(), RenderTextureLayout::SHADER_READ));
|
||||
interleavedBarriers.emplace_back(RenderTextureBarrier(depthRenderTarget->texture.get(), RenderTextureLayout::DEPTH_READ));
|
||||
|
@ -234,7 +234,7 @@ namespace RT64 {
|
||||
void NativeTarget::copyToNative(RenderWorker *worker, RenderTarget *srcTarget, uint32_t rowWidth, uint32_t rowStart, uint32_t rowEnd, uint8_t siz, uint8_t fmt, uint32_t ditherPattern, uint32_t ditherRandomSeed, const ShaderLibrary *shaderLibrary) {
|
||||
assert(worker != nullptr);
|
||||
|
||||
srcTarget->resolveTarget(worker);
|
||||
srcTarget->resolveTarget(worker, shaderLibrary);
|
||||
|
||||
if (srcTarget->fbWriteDescSet == nullptr) {
|
||||
srcTarget->fbWriteDescSet = std::make_unique<FramebufferWriteDescriptorTextureSet>(worker->device);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "gbi/rt64_f3d.h"
|
||||
#include "shared/rt64_fb_common.h"
|
||||
#include "shared/rt64_render_target_copy.h"
|
||||
#include "shared/rt64_texture_copy.h"
|
||||
|
||||
#include "rt64_raster_shader.h"
|
||||
|
||||
@ -44,8 +45,10 @@ namespace RT64 {
|
||||
downsampledTexture.reset();
|
||||
dummyTexture.reset();
|
||||
textureFramebuffer.reset();
|
||||
resolveFramebuffer.reset();
|
||||
targetCopyDescSet.reset();
|
||||
textureCopyDescSet.reset();
|
||||
textureResolveDescSet.reset();
|
||||
filterDescSet.reset();
|
||||
fbWriteDescSet.reset();
|
||||
}
|
||||
@ -131,6 +134,16 @@ namespace RT64 {
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTarget::setupResolveFramebuffer(RenderWorker *worker) {
|
||||
assert(worker != nullptr);
|
||||
assert(resolvedTexture != nullptr);
|
||||
|
||||
if (resolveFramebuffer == nullptr) {
|
||||
const RenderTexture *colorTexture = resolvedTexture.get();
|
||||
resolveFramebuffer = worker->device->createFramebuffer(RenderFramebufferDesc(&colorTexture, 1));
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTarget::setupDepthFramebuffer(RenderWorker *worker) {
|
||||
assert(worker != nullptr);
|
||||
|
||||
@ -201,17 +214,29 @@ namespace RT64 {
|
||||
markForResolve();
|
||||
}
|
||||
|
||||
void RenderTarget::resolveFromTarget(RenderWorker *worker, RenderTarget *src) {
|
||||
void RenderTarget::resolveFromTarget(RenderWorker *worker, RenderTarget *src, const ShaderLibrary *shaderLibrary) {
|
||||
assert(!usesResolve() && "The target must not be an MSAA target to allow resolving from other targets.");
|
||||
|
||||
const bool hwResolve = shaderLibrary->usesHardwareResolve;
|
||||
RenderTextureBarrier resolveBarriers[] = {
|
||||
RenderTextureBarrier(src->texture.get(), RenderTextureLayout::RESOLVE_SOURCE),
|
||||
RenderTextureBarrier(texture.get(), RenderTextureLayout::RESOLVE_DEST)
|
||||
RenderTextureBarrier(src->texture.get(), hwResolve ? RenderTextureLayout::RESOLVE_SOURCE : RenderTextureLayout::SHADER_READ),
|
||||
RenderTextureBarrier(texture.get(), hwResolve ? RenderTextureLayout::RESOLVE_DEST : RenderTextureLayout::COLOR_WRITE)
|
||||
};
|
||||
|
||||
const RenderRect srcRect(0, 0, std::min(width, src->width), std::min(height, src->height));
|
||||
worker->commandList->barriers(RenderBarrierStage::COPY, resolveBarriers, uint32_t(std::size(resolveBarriers)));
|
||||
worker->commandList->resolveTextureRegion(texture.get(), 0, 0, src->texture.get(), &srcRect);
|
||||
worker->commandList->barriers(hwResolve ? RenderBarrierStage::COPY : RenderBarrierStage::GRAPHICS, resolveBarriers, uint32_t(std::size(resolveBarriers)));
|
||||
|
||||
if (hwResolve) {
|
||||
worker->commandList->resolveTextureRegion(texture.get(), 0, 0, src->texture.get(), &srcRect);
|
||||
}
|
||||
else {
|
||||
if (src->textureResolveDescSet == nullptr) {
|
||||
src->textureResolveDescSet = std::make_unique<TextureCopyDescriptorSet>(worker->device);
|
||||
src->textureResolveDescSet->setTexture(src->textureResolveDescSet->gInput, src->texture.get(), RenderTextureLayout::SHADER_READ, src->textureView.get());
|
||||
}
|
||||
|
||||
recordRasterResolve(worker, src->textureResolveDescSet.get(), srcRect.left, srcRect.top, srcRect.right - srcRect.left, srcRect.bottom - srcRect.top, shaderLibrary);
|
||||
}
|
||||
|
||||
// Copy scaling attributes from source.
|
||||
resolutionScale = src->resolutionScale;
|
||||
@ -329,7 +354,7 @@ namespace RT64 {
|
||||
void RenderTarget::downsampleTarget(RenderWorker *worker, const ShaderLibrary *shaderLibrary) {
|
||||
assert(worker != nullptr);
|
||||
|
||||
resolveTarget(worker);
|
||||
resolveTarget(worker, shaderLibrary);
|
||||
|
||||
struct BoxFilterCB {
|
||||
interop::int2 Resolution;
|
||||
@ -382,21 +407,63 @@ namespace RT64 {
|
||||
worker->commandList->dispatch(dispatchX, dispatchY, 1);
|
||||
}
|
||||
|
||||
void RenderTarget::resolveTarget(RenderWorker *worker) {
|
||||
void RenderTarget::resolveTarget(RenderWorker *worker, const ShaderLibrary *shaderLibrary) {
|
||||
if (!resolvedTextureDirty || !usesResolve()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const bool hwResolve = shaderLibrary->usesHardwareResolve;
|
||||
RenderTextureBarrier resolveBarriers[] = {
|
||||
RenderTextureBarrier(texture.get(), RenderTextureLayout::RESOLVE_SOURCE),
|
||||
RenderTextureBarrier(resolvedTexture.get(), RenderTextureLayout::RESOLVE_DEST)
|
||||
RenderTextureBarrier(texture.get(), hwResolve ? RenderTextureLayout::RESOLVE_SOURCE : RenderTextureLayout::SHADER_READ),
|
||||
RenderTextureBarrier(resolvedTexture.get(), hwResolve ? RenderTextureLayout::RESOLVE_DEST : RenderTextureLayout::COLOR_WRITE)
|
||||
};
|
||||
|
||||
worker->commandList->barriers(RenderBarrierStage::COPY, resolveBarriers, uint32_t(std::size(resolveBarriers)));
|
||||
worker->commandList->resolveTexture(resolvedTexture.get(), texture.get());
|
||||
worker->commandList->barriers(hwResolve ? RenderBarrierStage::COPY : RenderBarrierStage::GRAPHICS, resolveBarriers, uint32_t(std::size(resolveBarriers)));
|
||||
|
||||
if (hwResolve) {
|
||||
worker->commandList->resolveTexture(resolvedTexture.get(), texture.get());
|
||||
}
|
||||
else {
|
||||
if (textureResolveDescSet == nullptr) {
|
||||
textureResolveDescSet = std::make_unique<TextureCopyDescriptorSet>(worker->device);
|
||||
textureResolveDescSet->setTexture(textureResolveDescSet->gInput, texture.get(), RenderTextureLayout::SHADER_READ, textureView.get());
|
||||
}
|
||||
|
||||
recordRasterResolve(worker, textureResolveDescSet.get(), 0, 0, width, height, shaderLibrary);
|
||||
}
|
||||
|
||||
resolvedTextureDirty = false;
|
||||
}
|
||||
|
||||
void RenderTarget::recordRasterResolve(RenderWorker *worker, const TextureCopyDescriptorSet *srcDescriptorSet, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const ShaderLibrary *shaderLibrary) {
|
||||
assert(format != depthBufferFormat() && "Rasterization path should not be used for depth targets.");
|
||||
|
||||
if (resolvedTexture != nullptr) {
|
||||
setupResolveFramebuffer(worker);
|
||||
worker->commandList->setFramebuffer(resolveFramebuffer.get());
|
||||
}
|
||||
else {
|
||||
setupColorFramebuffer(worker);
|
||||
worker->commandList->setFramebuffer(textureFramebuffer.get());
|
||||
}
|
||||
|
||||
interop::TextureCopyCB textureCopyCB;
|
||||
textureCopyCB.uvScroll.x = float(x);
|
||||
textureCopyCB.uvScroll.y = float(y);
|
||||
textureCopyCB.uvScale.x = float(width);
|
||||
textureCopyCB.uvScale.y = float(height);
|
||||
|
||||
const ShaderRecord &textureResolve = shaderLibrary->textureResolve;
|
||||
worker->commandList->setPipeline(textureResolve.pipeline.get());
|
||||
worker->commandList->setGraphicsPipelineLayout(textureResolve.pipelineLayout.get());
|
||||
worker->commandList->setVertexBuffers(0, nullptr, 0, nullptr);
|
||||
worker->commandList->setViewports(RenderViewport(float(x), float(y), float(width), float(height)));
|
||||
worker->commandList->setScissors(RenderRect(x, y, x + width, y + height));
|
||||
worker->commandList->setGraphicsDescriptorSet(srcDescriptorSet->get(), 0);
|
||||
worker->commandList->setGraphicsPushConstants(0, &textureCopyCB);
|
||||
worker->commandList->drawInstanced(3, 1, 0, 0);
|
||||
}
|
||||
|
||||
void RenderTarget::markForResolve() {
|
||||
resolvedTextureDirty = true;
|
||||
}
|
||||
|
@ -27,10 +27,12 @@ namespace RT64 {
|
||||
uint32_t downsampledTextureMultiplier = 0;
|
||||
std::unique_ptr<RenderTexture> dummyTexture;
|
||||
std::unique_ptr<RenderFramebuffer> textureFramebuffer;
|
||||
std::unique_ptr<RenderFramebuffer> resolveFramebuffer;
|
||||
RenderMultisampling multisampling;
|
||||
RenderFormat format = RenderFormat::UNKNOWN;
|
||||
std::unique_ptr<RenderTargetCopyDescriptorSet> targetCopyDescSet;
|
||||
std::unique_ptr<TextureCopyDescriptorSet> textureCopyDescSet;
|
||||
std::unique_ptr<TextureCopyDescriptorSet> textureResolveDescSet;
|
||||
std::unique_ptr<BoxFilterDescriptorSet> filterDescSet;
|
||||
std::unique_ptr<FramebufferWriteDescriptorTextureSet> fbWriteDescSet;
|
||||
uint32_t addressForName = 0;
|
||||
@ -53,14 +55,16 @@ namespace RT64 {
|
||||
void setupDepth(RenderWorker *worker, uint32_t width, uint32_t height);
|
||||
void setupDummy(RenderWorker *worker);
|
||||
void setupColorFramebuffer(RenderWorker *worker);
|
||||
void setupResolveFramebuffer(RenderWorker *worker);
|
||||
void setupDepthFramebuffer(RenderWorker *worker);
|
||||
void copyFromTarget(RenderWorker *worker, RenderTarget *src, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const ShaderLibrary *shaderLibrary);
|
||||
void resolveFromTarget(RenderWorker *worker, RenderTarget *src);
|
||||
void resolveFromTarget(RenderWorker *worker, RenderTarget *src, const ShaderLibrary *shaderLibrary);
|
||||
void copyFromChanges(RenderWorker *worker, const FramebufferChange &fbChange, uint32_t fbWidth, uint32_t fbHeight, uint32_t rowStart, const ShaderLibrary *shaderLibrary);
|
||||
void clearColorTarget(RenderWorker *worker);
|
||||
void clearDepthTarget(RenderWorker *worker);
|
||||
void downsampleTarget(RenderWorker *worker, const ShaderLibrary *shaderLibrary);
|
||||
void resolveTarget(RenderWorker *worker);
|
||||
void resolveTarget(RenderWorker *worker, const ShaderLibrary *shaderLibrary);
|
||||
void recordRasterResolve(RenderWorker *worker, const TextureCopyDescriptorSet *srcDescriptorSet, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const ShaderLibrary *shaderLibrary);
|
||||
void markForResolve();
|
||||
bool usesResolve() const;
|
||||
RenderTexture *getResolvedTexture() const;
|
||||
|
@ -37,6 +37,9 @@
|
||||
#include "shaders/RtCopyDepthToColorPSMS.hlsl.spirv.h"
|
||||
#include "shaders/TextureCopyPS.hlsl.spirv.h"
|
||||
#include "shaders/TextureDecodeCS.hlsl.spirv.h"
|
||||
#include "shaders/TextureResolveSamples2XPS.hlsl.spirv.h"
|
||||
#include "shaders/TextureResolveSamples4XPS.hlsl.spirv.h"
|
||||
#include "shaders/TextureResolveSamples8XPS.hlsl.spirv.h"
|
||||
#include "shaders/VideoInterfacePSRegular.hlsl.spirv.h"
|
||||
#include "shaders/VideoInterfacePSPixel.hlsl.spirv.h"
|
||||
#include "shaders/FullScreenVS.hlsl.spirv.h"
|
||||
@ -78,6 +81,9 @@
|
||||
# include "shaders/RtCopyDepthToColorPSMS.hlsl.dxil.h"
|
||||
# include "shaders/TextureCopyPS.hlsl.dxil.h"
|
||||
# include "shaders/TextureDecodeCS.hlsl.dxil.h"
|
||||
# include "shaders/TextureResolveSamples2XPS.hlsl.dxil.h"
|
||||
# include "shaders/TextureResolveSamples4XPS.hlsl.dxil.h"
|
||||
# include "shaders/TextureResolveSamples8XPS.hlsl.dxil.h"
|
||||
# include "shaders/VideoInterfacePSRegular.hlsl.dxil.h"
|
||||
# include "shaders/VideoInterfacePSPixel.hlsl.dxil.h"
|
||||
# include "shaders/FullScreenVS.hlsl.dxil.h"
|
||||
@ -115,8 +121,9 @@
|
||||
namespace RT64 {
|
||||
// ShaderLibrary
|
||||
|
||||
ShaderLibrary::ShaderLibrary(bool usesHDR) {
|
||||
ShaderLibrary::ShaderLibrary(bool usesHDR, bool usesHardwareResolve) {
|
||||
this->usesHDR = usesHDR;
|
||||
this->usesHardwareResolve = usesHardwareResolve;
|
||||
}
|
||||
|
||||
ShaderLibrary::~ShaderLibrary() { }
|
||||
@ -706,5 +713,69 @@ namespace RT64 {
|
||||
std::unique_ptr<RenderShader> computeShaderMS = device->createShader(CREATE_SHADER_INPUTS(RSPVertexTestZCSMSBlobDXIL, RSPVertexTestZCSMSBlobSPIRV, "CSMain", shaderFormat));
|
||||
rspVertexTestZMS.pipeline = device->createComputePipeline(RenderComputePipelineDesc(rspVertexTestZMS.pipelineLayout.get(), computeShaderMS.get()));
|
||||
}
|
||||
|
||||
// Texture Resolve.
|
||||
{
|
||||
const void *PSBlob = nullptr;
|
||||
uint32_t PSBlobSize = 0;
|
||||
if (shaderFormat == RenderShaderFormat::DXIL) {
|
||||
switch (multisampling.sampleCount) {
|
||||
case RenderSampleCount::COUNT_2:
|
||||
PSBlob = TextureResolveSamples2XPSBlobDXIL;
|
||||
PSBlobSize = std::size(TextureResolveSamples2XPSBlobDXIL);
|
||||
break;
|
||||
case RenderSampleCount::COUNT_4:
|
||||
PSBlob = TextureResolveSamples4XPSBlobDXIL;
|
||||
PSBlobSize = std::size(TextureResolveSamples4XPSBlobDXIL);
|
||||
break;
|
||||
case RenderSampleCount::COUNT_8:
|
||||
PSBlob = TextureResolveSamples8XPSBlobDXIL;
|
||||
PSBlobSize = std::size(TextureResolveSamples8XPSBlobDXIL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (shaderFormat == RenderShaderFormat::SPIRV) {
|
||||
switch (multisampling.sampleCount) {
|
||||
case RenderSampleCount::COUNT_2:
|
||||
PSBlob = TextureResolveSamples2XPSBlobSPIRV;
|
||||
PSBlobSize = std::size(TextureResolveSamples2XPSBlobSPIRV);
|
||||
break;
|
||||
case RenderSampleCount::COUNT_4:
|
||||
PSBlob = TextureResolveSamples4XPSBlobSPIRV;
|
||||
PSBlobSize = std::size(TextureResolveSamples4XPSBlobSPIRV);
|
||||
break;
|
||||
case RenderSampleCount::COUNT_8:
|
||||
PSBlob = TextureResolveSamples8XPSBlobSPIRV;
|
||||
PSBlobSize = std::size(TextureResolveSamples8XPSBlobSPIRV);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(false && "Unknown shader format.");
|
||||
}
|
||||
|
||||
if (PSBlob != nullptr) {
|
||||
TextureCopyDescriptorSet descriptorSet;
|
||||
layoutBuilder.begin();
|
||||
layoutBuilder.addPushConstant(0, 0, sizeof(interop::TextureCopyCB), RenderShaderStageFlag::PIXEL);
|
||||
layoutBuilder.addDescriptorSet(descriptorSet);
|
||||
layoutBuilder.end();
|
||||
textureResolve.pipelineLayout = layoutBuilder.create(device);
|
||||
|
||||
std::unique_ptr<RenderShader> pixelShader = device->createShader(PSBlob, PSBlobSize, "PSMain", shaderFormat);
|
||||
RenderGraphicsPipelineDesc pipelineDesc;
|
||||
pipelineDesc.pipelineLayout = textureResolve.pipelineLayout.get();
|
||||
pipelineDesc.renderTargetBlend[0] = RenderBlendDesc::Copy();
|
||||
pipelineDesc.renderTargetFormat[0] = RenderTarget::colorBufferFormat(usesHDR);
|
||||
pipelineDesc.renderTargetCount = 1;
|
||||
pipelineDesc.vertexShader = fullScreenVertexShader.get();
|
||||
pipelineDesc.pixelShader = pixelShader.get();
|
||||
textureResolve.pipeline = device->createGraphicsPipeline(pipelineDesc);
|
||||
}
|
||||
else {
|
||||
textureResolve.pipeline.reset();
|
||||
textureResolve.pipelineLayout.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -15,8 +15,9 @@ namespace RT64 {
|
||||
};
|
||||
|
||||
struct ShaderLibrary {
|
||||
bool usesHDR = false;
|
||||
SamplerLibrary samplerLibrary;
|
||||
bool usesHDR = false;
|
||||
bool usesHardwareResolve = false;
|
||||
|
||||
// All shaders.
|
||||
ShaderRecord bicubicScaling;
|
||||
@ -54,11 +55,12 @@ namespace RT64 {
|
||||
ShaderRecord rtCopyDepthToColorMS;
|
||||
ShaderRecord textureDecode;
|
||||
ShaderRecord textureCopy;
|
||||
ShaderRecord textureResolve;
|
||||
ShaderRecord videoInterfaceLinear;
|
||||
ShaderRecord videoInterfaceNearest;
|
||||
ShaderRecord videoInterfacePixel;
|
||||
|
||||
ShaderLibrary(bool usesHDR);
|
||||
ShaderLibrary(bool usesHDR, bool usesHardwareResolve);
|
||||
~ShaderLibrary();
|
||||
void setupCommonShaders(RenderInterface *rhi, RenderDevice *device);
|
||||
void setupMultisamplingShaders(RenderInterface *rhi, RenderDevice *device, const RenderMultisampling &multisampling);
|
||||
|
@ -16,18 +16,18 @@ namespace RT64 {
|
||||
const RenderSampler *descriptorSetSampler = nullptr;
|
||||
|
||||
struct RenderParams {
|
||||
RenderDevice *device;
|
||||
RenderCommandList *commandList;
|
||||
RenderTexture *texture;
|
||||
const RenderSwapChain *swapChain;
|
||||
const ShaderLibrary *shaderLibrary;
|
||||
RenderFormat textureFormat;
|
||||
RenderDevice *device = nullptr;
|
||||
RenderCommandList *commandList = nullptr;
|
||||
RenderTexture *texture = nullptr;
|
||||
const RenderSwapChain *swapChain = nullptr;
|
||||
const ShaderLibrary *shaderLibrary = nullptr;
|
||||
RenderFormat textureFormat = RenderFormat::UNKNOWN;
|
||||
hlslpp::float2 resolutionScale;
|
||||
uint32_t downsamplingScale;
|
||||
uint32_t textureWidth;
|
||||
uint32_t textureHeight;
|
||||
UserConfiguration::Filtering filtering;
|
||||
const VI *vi;
|
||||
uint32_t downsamplingScale = 0;
|
||||
uint32_t textureWidth = 0;
|
||||
uint32_t textureHeight = 0;
|
||||
UserConfiguration::Filtering filtering = UserConfiguration::Filtering::Linear;
|
||||
const VI *vi = nullptr;
|
||||
};
|
||||
|
||||
VIRenderer();
|
||||
|
39
src/shaders/TextureResolvePS.hlsl
Normal file
39
src/shaders/TextureResolvePS.hlsl
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// RT64
|
||||
//
|
||||
|
||||
#include "shared/rt64_texture_copy.h"
|
||||
|
||||
[[vk::push_constant]] ConstantBuffer<TextureCopyCB> gConstants : register(b0);
|
||||
|
||||
Texture2DMS<float4> gInput : register(t1);
|
||||
|
||||
float4 PSMain(in float4 pos : SV_Position, in float2 uv : TEXCOORD0) : SV_TARGET {
|
||||
uint2 pixelPos = gConstants.uvScroll + uv.xy * gConstants.uvScale;
|
||||
#if defined(SAMPLES_8X)
|
||||
return (
|
||||
gInput.Load(pixelPos, 0) +
|
||||
gInput.Load(pixelPos, 1) +
|
||||
gInput.Load(pixelPos, 2) +
|
||||
gInput.Load(pixelPos, 3) +
|
||||
gInput.Load(pixelPos, 4) +
|
||||
gInput.Load(pixelPos, 5) +
|
||||
gInput.Load(pixelPos, 6) +
|
||||
gInput.Load(pixelPos, 7)
|
||||
) / 8.0f;
|
||||
#elif defined(SAMPLES_4X)
|
||||
return (
|
||||
gInput.Load(pixelPos, 0) +
|
||||
gInput.Load(pixelPos, 1) +
|
||||
gInput.Load(pixelPos, 2) +
|
||||
gInput.Load(pixelPos, 3)
|
||||
) / 4.0f;
|
||||
#elif defined(SAMPLES_2X)
|
||||
return (
|
||||
gInput.Load(pixelPos, 0) +
|
||||
gInput.Load(pixelPos, 1)
|
||||
) / 2.0f;
|
||||
#else
|
||||
return gInput.Load(pixelPos, 0);
|
||||
#endif
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user