Implement Maxwell3D Depth/Stencil Render Target

Support the Maxwell3D Depth RT for Z-buffering, this just creates an equivalent `RenderTarget` object with no support on the API-user side (IE: `Draw` and `ClearBuffers`).
This commit is contained in:
PixelyIon
2021-12-08 00:42:54 +05:30
parent 2a8bcc60c7
commit 68c990c041
5 changed files with 115 additions and 3 deletions

View File

@ -91,7 +91,13 @@ namespace skyline::gpu::interconnect {
std::array<RenderTarget, maxwell3d::RenderTargetCount> colorRenderTargets{}; //!< The target textures to render into as color attachments
maxwell3d::RenderTargetControl renderTargetControl{};
RenderTarget depthRenderTarget{}; //!< The target texture to render depth/stencil into
public:
void SetDepthRenderTargetEnabled(bool enabled) {
depthRenderTarget.disabled = !enabled;
}
void SetRenderTargetAddressHigh(RenderTarget &renderTarget, u32 high) {
renderTarget.iova.high = high;
renderTarget.guest.mappings.clear();
@ -102,6 +108,10 @@ namespace skyline::gpu::interconnect {
SetRenderTargetAddressHigh(colorRenderTargets.at(index), high);
}
void SetDepthRenderTargetAddressHigh(u32 high) {
SetRenderTargetAddressHigh(depthRenderTarget, high);
}
void SetRenderTargetAddressLow(RenderTarget &renderTarget, u32 low) {
renderTarget.iova.low = low;
renderTarget.guest.mappings.clear();
@ -112,6 +122,10 @@ namespace skyline::gpu::interconnect {
SetRenderTargetAddressLow(colorRenderTargets.at(index), low);
}
void SetDepthRenderTargetAddressLow(u32 low) {
SetRenderTargetAddressLow(depthRenderTarget, low);
}
void SetRenderTargetWidth(RenderTarget &renderTarget, u32 value) {
renderTarget.widthBytes = value;
if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format)
@ -124,6 +138,10 @@ namespace skyline::gpu::interconnect {
SetRenderTargetWidth(colorRenderTargets.at(index), value);
}
void SetDepthRenderTargetWidth(u32 value) {
SetRenderTargetWidth(depthRenderTarget, value);
}
void SetRenderTargetHeight(RenderTarget &renderTarget, u32 value) {
renderTarget.guest.dimensions.height = value;
renderTarget.view.reset();
@ -133,6 +151,10 @@ namespace skyline::gpu::interconnect {
SetRenderTargetHeight(colorRenderTargets.at(index), value);
}
void SetDepthRenderTargetHeight(u32 value) {
SetRenderTargetHeight(depthRenderTarget, value);
}
void SetColorRenderTargetFormat(size_t index, maxwell3d::ColorRenderTarget::Format format) {
auto &renderTarget{colorRenderTargets.at(index)};
renderTarget.guest.format = [&]() -> texture::Format {
@ -206,6 +228,23 @@ namespace skyline::gpu::interconnect {
renderTarget.view.reset();
}
void SetDepthRenderTargetFormat(maxwell3d::DepthRtFormat format) {
depthRenderTarget.guest.format = [&]() -> texture::Format {
using MaxwellDepthRtFormat = maxwell3d::DepthRtFormat;
switch (format) {
case MaxwellDepthRtFormat::S8D24Unorm:
return format::S8D24Unorm;
default:
throw exception("Cannot translate the supplied depth RT format: 0x{:X}", static_cast<u32>(format));
}
}();
if (depthRenderTarget.guest.tileConfig.mode == texture::TileMode::Linear && depthRenderTarget.guest.format)
depthRenderTarget.guest.dimensions.width = depthRenderTarget.widthBytes / depthRenderTarget.guest.format->bpb;
depthRenderTarget.view.reset();
}
void SetRenderTargetTileMode(RenderTarget &renderTarget, maxwell3d::RenderTargetTileMode mode) {
auto &config{renderTarget.guest.tileConfig};
if (mode.isLinear) {
@ -233,17 +272,25 @@ namespace skyline::gpu::interconnect {
SetRenderTargetTileMode(colorRenderTargets.at(index), mode);
}
void SetDepthRenderTargetTileMode(maxwell3d::RenderTargetTileMode mode) {
SetRenderTargetTileMode(depthRenderTarget, mode);
}
void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) {
renderTarget.guest.layerCount = mode.layerCount;
if (mode.volume)
throw exception("RT Array Volumes are not supported (with layer count = {})", mode.layerCount);
renderTarget.view.reset();
}
void SetColorRenderTargetArrayMode(size_t index, maxwell3d::RenderTargetArrayMode mode) {
if (mode.volume)
throw exception("Color RT Array Volumes are not supported (with layer count = {})", mode.layerCount);
SetRenderTargetArrayMode(colorRenderTargets.at(index), mode);
}
void SetDepthRenderTargetArrayMode(maxwell3d::RenderTargetArrayMode mode) {
SetRenderTargetArrayMode(depthRenderTarget, mode);
}
void SetRenderTargetLayerStride(RenderTarget &renderTarget, u32 layerStrideLsr2) {
renderTarget.guest.layerStride = layerStrideLsr2 << 2;
renderTarget.view.reset();
@ -253,6 +300,10 @@ namespace skyline::gpu::interconnect {
SetRenderTargetLayerStride(colorRenderTargets.at(index), layerStrideLsr2);
}
void SetDepthRenderTargetLayerStride(u32 layerStrideLsr2) {
SetRenderTargetLayerStride(depthRenderTarget, layerStrideLsr2);
}
void SetColorRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
auto &renderTarget{colorRenderTargets.at(index)};
if (baseArrayLayer > std::numeric_limits<u16>::max())
@ -262,7 +313,7 @@ namespace skyline::gpu::interconnect {
renderTarget.view.reset();
}
TextureView *GetRenderTarget(RenderTarget& renderTarget) {
TextureView *GetRenderTarget(RenderTarget &renderTarget) {
if (renderTarget.disabled)
return nullptr;
else if (renderTarget.view)
@ -284,6 +335,10 @@ namespace skyline::gpu::interconnect {
return GetRenderTarget(colorRenderTargets.at(index));
}
TextureView *GetDepthRenderTarget() {
return GetRenderTarget(depthRenderTarget);
}
void UpdateRenderTargetControl(maxwell3d::RenderTargetControl control) {
renderTargetControl = control;
}

View File

@ -11,6 +11,7 @@ namespace skyline::gpu::format {
using vka = vk::ImageAspectFlagBits;
using swc = gpu::texture::SwizzleChannel;
// Color Formats
constexpr Format R8G8B8A8Unorm{sizeof(u32), vkf::eR8G8B8A8Unorm};
constexpr Format R5G6B5Unorm{sizeof(u16), vkf::eR5G6B5UnormPack16};
constexpr Format A2B10G10R10Unorm{sizeof(u32), vkf::eA2B10G10R10UnormPack32};
@ -42,4 +43,7 @@ namespace skyline::gpu::format {
constexpr Format R16G16B16A16Float{sizeof(u16) * 4, vkf::eR16G16B16A16Sfloat};
constexpr Format B8G8R8A8Unorm{sizeof(u32), vkf::eB8G8R8A8Unorm};
constexpr Format B8G8R8A8Srgb{sizeof(u32), vkf::eB8G8R8A8Srgb};
// Depth/Stencil Formats
constexpr Format S8D24Unorm{sizeof(u32), vkf::eD24UnormS8Uint, vka::eStencil | vka::eDepth}; // TODO: Swizzle Depth/Stencil
}