mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 20:41:50 +01:00
Adjust blit src{X,Y} to account for centred sampling before calling into helper shader
Since the blit engine itself samples from pixel corners and the helper shader from pixel centres teh src coordinates need to be adjusted to avoid the helper shader wrapping round on the final column.
This commit is contained in:
parent
08f36aac33
commit
c32bec071c
@ -108,7 +108,7 @@ namespace skyline::gpu::interconnect {
|
||||
|
||||
Fermi2D::Fermi2D(GPU &gpu, soc::gm20b::ChannelContext &channelCtx, gpu::interconnect::CommandExecutor &executor) : gpu(gpu), channelCtx(channelCtx), executor(executor) {}
|
||||
|
||||
void Fermi2D::Blit(const Surface &srcSurface, const Surface &dstSurface, float srcRectX, float srcRectY, u32 dstRectWidth, u32 dstRectHeight, u32 dstRectX, u32 dstRectY, float duDx, float dvDy, bool resolve, bool bilinearFilter) {
|
||||
void Fermi2D::Blit(const Surface &srcSurface, const Surface &dstSurface, float srcRectX, float srcRectY, u32 dstRectWidth, u32 dstRectHeight, u32 dstRectX, u32 dstRectY, float duDx, float dvDy, SampleModeOrigin sampleOrigin, bool resolve, SampleModeFilter filter) {
|
||||
// TODO: When we support MSAA perform a resolve operation rather than blit when the `resolve` flag is set.
|
||||
auto srcGuestTexture{GetGuestTexture(srcSurface)};
|
||||
auto dstGuestTexture{GetGuestTexture(dstSurface)};
|
||||
@ -120,13 +120,17 @@ namespace skyline::gpu::interconnect {
|
||||
auto dstTextureView{textureManager.FindOrCreate(dstGuestTexture, executor.tag)};
|
||||
executor.AttachTexture(dstTextureView.get());
|
||||
|
||||
// Blit shader always samples from centre so adjust if necessary
|
||||
float centredSrcRectX{sampleOrigin == SampleModeOrigin::Corner ? srcRectX - 0.5f : srcRectX};
|
||||
float centredSrcRectY{sampleOrigin == SampleModeOrigin::Corner ? srcRectY - 0.5f : srcRectY};
|
||||
|
||||
gpu.helperShaders.blitHelperShader.Blit(
|
||||
gpu,
|
||||
{
|
||||
.width = duDx * dstRectWidth,
|
||||
.height = dvDy * dstRectHeight,
|
||||
.x = srcRectX,
|
||||
.y = srcRectY,
|
||||
.x = centredSrcRectX,
|
||||
.y = centredSrcRectY,
|
||||
},
|
||||
{
|
||||
.width = static_cast<float>(dstRectWidth),
|
||||
@ -136,7 +140,7 @@ namespace skyline::gpu::interconnect {
|
||||
},
|
||||
srcGuestTexture.dimensions, dstGuestTexture.dimensions,
|
||||
duDx, dvDy,
|
||||
bilinearFilter,
|
||||
filter == SampleModeFilter::Bilinear,
|
||||
srcTextureView.get(), dstTextureView.get(),
|
||||
[=](auto &&executionCallback) {
|
||||
auto dst{dstTextureView.get()};
|
||||
|
@ -26,6 +26,8 @@ namespace skyline::gpu::interconnect {
|
||||
private:
|
||||
using IOVA = soc::gm20b::IOVA;
|
||||
using Surface = skyline::soc::gm20b::engine::fermi2d::type::Surface;
|
||||
using SampleModeOrigin = skyline::soc::gm20b::engine::fermi2d::type::SampleModeOrigin;
|
||||
using SampleModeFilter = skyline::soc::gm20b::engine::fermi2d::type::SampleModeFilter;
|
||||
|
||||
GPU &gpu;
|
||||
soc::gm20b::ChannelContext &channelCtx;
|
||||
@ -36,6 +38,6 @@ namespace skyline::gpu::interconnect {
|
||||
public:
|
||||
Fermi2D(GPU &gpu, soc::gm20b::ChannelContext &channelCtx, gpu::interconnect::CommandExecutor &executor);
|
||||
|
||||
void Blit(const Surface &srcSurface, const Surface &dstSurface, float srcRectX, float srcRectY, u32 dstRectWidth, u32 dstRectHeight, u32 dstRectX, u32 dstRectY, float duDx, float dvDy, bool resolve, bool bilinearFilter);
|
||||
void Blit(const Surface &srcSurface, const Surface &dstSurface, float srcRectX, float srcRectY, u32 dstRectWidth, u32 dstRectHeight, u32 dstRectX, u32 dstRectY, float duDx, float dvDy, SampleModeOrigin sampleOrigin, bool resolve, SampleModeFilter filter);
|
||||
};
|
||||
}
|
||||
|
@ -89,5 +89,15 @@ namespace skyline::soc::gm20b::engine::fermi2d::type {
|
||||
Address address;
|
||||
};
|
||||
|
||||
enum class SampleModeOrigin : u8 {
|
||||
Center = 0,
|
||||
Corner = 1
|
||||
};
|
||||
|
||||
enum class SampleModeFilter : u8 {
|
||||
Point = 0,
|
||||
Bilinear = 1
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace skyline::soc::gm20b::engine::fermi2d {
|
||||
float duDx{fixedToFloating(pixelsFromMemory.duDx)};
|
||||
float dvDy{fixedToFloating(pixelsFromMemory.dvDy)};
|
||||
|
||||
if (registers.pixelsFromMemory->sampleMode.origin == Registers::PixelsFromMemory::SampleModeOrigin::Center) {
|
||||
if (registers.pixelsFromMemory->sampleMode.origin == type::SampleModeOrigin::Center) {
|
||||
// This is an MSAA resolve operation, sampling from the center of each pixel in order to resolve the final image from the MSAA samples
|
||||
// MSAA images are stored in memory like regular images but each pixels dimensions are scaled: e.g for 2x2 MSAA
|
||||
/* 112233
|
||||
@ -61,8 +61,9 @@ namespace skyline::soc::gm20b::engine::fermi2d {
|
||||
pixelsFromMemory.dstWidth, pixelsFromMemory.dstHeight,
|
||||
pixelsFromMemory.dstX0, pixelsFromMemory.dstY0,
|
||||
duDx, dvDy,
|
||||
registers.pixelsFromMemory->sampleMode.origin == Registers::PixelsFromMemory::SampleModeOrigin::Center,
|
||||
pixelsFromMemory.sampleMode.filter == Registers::PixelsFromMemory::SampleModeFilter::Bilinear);
|
||||
registers.pixelsFromMemory->sampleMode.origin,
|
||||
registers.pixelsFromMemory->sampleMode.origin == type::SampleModeOrigin::Center,
|
||||
pixelsFromMemory.sampleMode.filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,16 +46,6 @@ namespace skyline::soc::gm20b::engine::fermi2d {
|
||||
Shape16x4 = 2
|
||||
};
|
||||
|
||||
enum class SampleModeOrigin : u8 {
|
||||
Center = 0,
|
||||
Corner = 1
|
||||
};
|
||||
|
||||
enum class SampleModeFilter : u8 {
|
||||
Point = 0,
|
||||
Bilinear = 1
|
||||
};
|
||||
|
||||
BlockShapeV blockShape : 3;
|
||||
u32 _pad0_ : 29;
|
||||
u16 corralSize : 10;
|
||||
@ -63,9 +53,9 @@ namespace skyline::soc::gm20b::engine::fermi2d {
|
||||
bool safeOverlap : 1;
|
||||
u32 _pad2_ : 31;
|
||||
struct {
|
||||
SampleModeOrigin origin : 1;
|
||||
type::SampleModeOrigin origin : 1;
|
||||
u8 _pad0_ : 3;
|
||||
SampleModeFilter filter : 1;
|
||||
type::SampleModeFilter filter : 1;
|
||||
u32 _pad1_ : 27;
|
||||
} sampleMode;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user