Alternate resolve path with rasterization supported.

This commit is contained in:
Dario 2024-11-03 17:20:45 -03:00
parent d2fd395801
commit afbc5e41e3
16 changed files with 241 additions and 44 deletions

View File

@ -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")

View File

@ -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;

View File

@ -80,6 +80,7 @@ namespace RT64 {
Resolution resolution;
DisplayBuffering displayBuffering;
Antialiasing antialiasing;
bool hardwareResolve;
double resolutionMultiplier;
int downsampleMultiplier;
Filtering filtering;

View File

@ -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);

View File

@ -215,7 +215,7 @@ namespace RT64 {
}
// Resolve the target if necessary.
colorTarget.resolveTarget(renderWorker);
colorTarget.resolveTarget(renderWorker, shaderLibrary);
cmdListCopies.copyRegionTargets.insert(&colorTarget);

View File

@ -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);
}
{

View File

@ -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();

View File

@ -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();

View File

@ -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));

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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();
}
}
}
};

View File

@ -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);

View File

@ -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();

View 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
}