mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 17:01:49 +01:00
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:
parent
2a8bcc60c7
commit
68c990c041
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -108,6 +108,20 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
};
|
||||
static_assert(sizeof(ColorRenderTarget) == (0x10 * sizeof(u32)));
|
||||
|
||||
enum class DepthRtFormat : u32 {
|
||||
D32Float = 0x0A,
|
||||
D16Unorm = 0x13,
|
||||
S8D24Unorm = 0x14,
|
||||
D24X8Unorm = 0x15,
|
||||
D24S8Unorm = 0x16,
|
||||
S8Uint = 0x17,
|
||||
D24C8Unorm = 0x18,
|
||||
D32S8X24Float = 0x19,
|
||||
D24X8S8C8X16Unorm = 0x1D,
|
||||
D32X8C8X16Float = 0x1E,
|
||||
D32S8C8X16Float = 0x1F,
|
||||
};
|
||||
|
||||
constexpr static size_t ViewportCount{16}; //!< Amount of viewports on Maxwell 3D, array size for any per-viewport parameter such as transform, scissors, etc
|
||||
|
||||
/**
|
||||
|
@ -115,6 +115,34 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
||||
#undef RENDER_TARGET_ARRAY
|
||||
|
||||
MAXWELL3D_CASE(depthTargetEnable, {
|
||||
context.SetDepthRenderTargetEnabled(depthTargetEnable);
|
||||
})
|
||||
MAXWELL3D_STRUCT_CASE(depthTargetAddress, high, {
|
||||
context.SetDepthRenderTargetAddressHigh(high);
|
||||
})
|
||||
MAXWELL3D_STRUCT_CASE(depthTargetAddress, low, {
|
||||
context.SetDepthRenderTargetAddressLow(low);
|
||||
})
|
||||
MAXWELL3D_CASE(depthTargetFormat, {
|
||||
context.SetDepthRenderTargetFormat(depthTargetFormat);
|
||||
})
|
||||
MAXWELL3D_CASE(depthTargetTileMode, {
|
||||
context.SetDepthRenderTargetTileMode(depthTargetTileMode);
|
||||
})
|
||||
MAXWELL3D_CASE(depthTargetLayerStride, {
|
||||
context.SetDepthRenderTargetLayerStride(depthTargetLayerStride);
|
||||
})
|
||||
MAXWELL3D_CASE(depthTargetWidth, {
|
||||
context.SetDepthRenderTargetWidth(depthTargetWidth);
|
||||
})
|
||||
MAXWELL3D_CASE(depthTargetHeight, {
|
||||
context.SetDepthRenderTargetHeight(depthTargetHeight);
|
||||
})
|
||||
MAXWELL3D_CASE(depthTargetArrayMode, {
|
||||
context.SetDepthRenderTargetArrayMode(depthTargetArrayMode);
|
||||
})
|
||||
|
||||
#define VIEWPORT_TRANSFORM_CALLBACKS(z, index, data) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleX, { \
|
||||
context.SetViewportX(index, scaleX, registers.viewportTransforms[index].translateX); \
|
||||
|
@ -109,8 +109,19 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x3E4, u32> commonColorWriteMask; //!< If enabled, the color write masks for all RTs must be set to that of the first RT
|
||||
Register<0x3EB, u32> rtSeparateFragData;
|
||||
|
||||
Register<0x3F8, type::Address> depthTargetAddress;
|
||||
Register<0x3FA, type::DepthRtFormat> depthTargetFormat;
|
||||
Register<0x3FB, type::RenderTargetTileMode> depthTargetTileMode;
|
||||
Register<0x3FC, u32> depthTargetLayerStride;
|
||||
|
||||
Register<0x458, std::array<type::VertexAttribute, type::VertexAttributeCount>> vertexAttributeState;
|
||||
Register<0x487, type::RenderTargetControl> renderTargetControl;
|
||||
|
||||
Register<0x48A, u32> depthTargetWidth;
|
||||
Register<0x48B, u32> depthTargetHeight;
|
||||
Register<0x48C, type::RenderTargetArrayMode> depthTargetArrayMode;
|
||||
|
||||
Register<0x4B9, u32> independentBlendEnable;
|
||||
Register<0x4BB, u32> alphaTestEnable;
|
||||
Register<0x4C3, type::CompareOp> depthTestFunc;
|
||||
|
Loading…
Reference in New Issue
Block a user