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
|
std::array<RenderTarget, maxwell3d::RenderTargetCount> colorRenderTargets{}; //!< The target textures to render into as color attachments
|
||||||
maxwell3d::RenderTargetControl renderTargetControl{};
|
maxwell3d::RenderTargetControl renderTargetControl{};
|
||||||
|
|
||||||
|
RenderTarget depthRenderTarget{}; //!< The target texture to render depth/stencil into
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void SetDepthRenderTargetEnabled(bool enabled) {
|
||||||
|
depthRenderTarget.disabled = !enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void SetRenderTargetAddressHigh(RenderTarget &renderTarget, u32 high) {
|
void SetRenderTargetAddressHigh(RenderTarget &renderTarget, u32 high) {
|
||||||
renderTarget.iova.high = high;
|
renderTarget.iova.high = high;
|
||||||
renderTarget.guest.mappings.clear();
|
renderTarget.guest.mappings.clear();
|
||||||
@ -102,6 +108,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
SetRenderTargetAddressHigh(colorRenderTargets.at(index), high);
|
SetRenderTargetAddressHigh(colorRenderTargets.at(index), high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetAddressHigh(u32 high) {
|
||||||
|
SetRenderTargetAddressHigh(depthRenderTarget, high);
|
||||||
|
}
|
||||||
|
|
||||||
void SetRenderTargetAddressLow(RenderTarget &renderTarget, u32 low) {
|
void SetRenderTargetAddressLow(RenderTarget &renderTarget, u32 low) {
|
||||||
renderTarget.iova.low = low;
|
renderTarget.iova.low = low;
|
||||||
renderTarget.guest.mappings.clear();
|
renderTarget.guest.mappings.clear();
|
||||||
@ -112,6 +122,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
SetRenderTargetAddressLow(colorRenderTargets.at(index), low);
|
SetRenderTargetAddressLow(colorRenderTargets.at(index), low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetAddressLow(u32 low) {
|
||||||
|
SetRenderTargetAddressLow(depthRenderTarget, low);
|
||||||
|
}
|
||||||
|
|
||||||
void SetRenderTargetWidth(RenderTarget &renderTarget, u32 value) {
|
void SetRenderTargetWidth(RenderTarget &renderTarget, u32 value) {
|
||||||
renderTarget.widthBytes = value;
|
renderTarget.widthBytes = value;
|
||||||
if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format)
|
if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format)
|
||||||
@ -124,6 +138,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
SetRenderTargetWidth(colorRenderTargets.at(index), value);
|
SetRenderTargetWidth(colorRenderTargets.at(index), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetWidth(u32 value) {
|
||||||
|
SetRenderTargetWidth(depthRenderTarget, value);
|
||||||
|
}
|
||||||
|
|
||||||
void SetRenderTargetHeight(RenderTarget &renderTarget, u32 value) {
|
void SetRenderTargetHeight(RenderTarget &renderTarget, u32 value) {
|
||||||
renderTarget.guest.dimensions.height = value;
|
renderTarget.guest.dimensions.height = value;
|
||||||
renderTarget.view.reset();
|
renderTarget.view.reset();
|
||||||
@ -133,6 +151,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
SetRenderTargetHeight(colorRenderTargets.at(index), value);
|
SetRenderTargetHeight(colorRenderTargets.at(index), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetHeight(u32 value) {
|
||||||
|
SetRenderTargetHeight(depthRenderTarget, value);
|
||||||
|
}
|
||||||
|
|
||||||
void SetColorRenderTargetFormat(size_t index, maxwell3d::ColorRenderTarget::Format format) {
|
void SetColorRenderTargetFormat(size_t index, maxwell3d::ColorRenderTarget::Format format) {
|
||||||
auto &renderTarget{colorRenderTargets.at(index)};
|
auto &renderTarget{colorRenderTargets.at(index)};
|
||||||
renderTarget.guest.format = [&]() -> texture::Format {
|
renderTarget.guest.format = [&]() -> texture::Format {
|
||||||
@ -206,6 +228,23 @@ namespace skyline::gpu::interconnect {
|
|||||||
renderTarget.view.reset();
|
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) {
|
void SetRenderTargetTileMode(RenderTarget &renderTarget, maxwell3d::RenderTargetTileMode mode) {
|
||||||
auto &config{renderTarget.guest.tileConfig};
|
auto &config{renderTarget.guest.tileConfig};
|
||||||
if (mode.isLinear) {
|
if (mode.isLinear) {
|
||||||
@ -233,17 +272,25 @@ namespace skyline::gpu::interconnect {
|
|||||||
SetRenderTargetTileMode(colorRenderTargets.at(index), mode);
|
SetRenderTargetTileMode(colorRenderTargets.at(index), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetTileMode(maxwell3d::RenderTargetTileMode mode) {
|
||||||
|
SetRenderTargetTileMode(depthRenderTarget, mode);
|
||||||
|
}
|
||||||
|
|
||||||
void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) {
|
void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) {
|
||||||
renderTarget.guest.layerCount = mode.layerCount;
|
renderTarget.guest.layerCount = mode.layerCount;
|
||||||
if (mode.volume)
|
|
||||||
throw exception("RT Array Volumes are not supported (with layer count = {})", mode.layerCount);
|
|
||||||
renderTarget.view.reset();
|
renderTarget.view.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetColorRenderTargetArrayMode(size_t index, maxwell3d::RenderTargetArrayMode mode) {
|
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);
|
SetRenderTargetArrayMode(colorRenderTargets.at(index), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetArrayMode(maxwell3d::RenderTargetArrayMode mode) {
|
||||||
|
SetRenderTargetArrayMode(depthRenderTarget, mode);
|
||||||
|
}
|
||||||
|
|
||||||
void SetRenderTargetLayerStride(RenderTarget &renderTarget, u32 layerStrideLsr2) {
|
void SetRenderTargetLayerStride(RenderTarget &renderTarget, u32 layerStrideLsr2) {
|
||||||
renderTarget.guest.layerStride = layerStrideLsr2 << 2;
|
renderTarget.guest.layerStride = layerStrideLsr2 << 2;
|
||||||
renderTarget.view.reset();
|
renderTarget.view.reset();
|
||||||
@ -253,6 +300,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
SetRenderTargetLayerStride(colorRenderTargets.at(index), layerStrideLsr2);
|
SetRenderTargetLayerStride(colorRenderTargets.at(index), layerStrideLsr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDepthRenderTargetLayerStride(u32 layerStrideLsr2) {
|
||||||
|
SetRenderTargetLayerStride(depthRenderTarget, layerStrideLsr2);
|
||||||
|
}
|
||||||
|
|
||||||
void SetColorRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
|
void SetColorRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
|
||||||
auto &renderTarget{colorRenderTargets.at(index)};
|
auto &renderTarget{colorRenderTargets.at(index)};
|
||||||
if (baseArrayLayer > std::numeric_limits<u16>::max())
|
if (baseArrayLayer > std::numeric_limits<u16>::max())
|
||||||
@ -262,7 +313,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
renderTarget.view.reset();
|
renderTarget.view.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureView *GetRenderTarget(RenderTarget& renderTarget) {
|
TextureView *GetRenderTarget(RenderTarget &renderTarget) {
|
||||||
if (renderTarget.disabled)
|
if (renderTarget.disabled)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (renderTarget.view)
|
else if (renderTarget.view)
|
||||||
@ -284,6 +335,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
return GetRenderTarget(colorRenderTargets.at(index));
|
return GetRenderTarget(colorRenderTargets.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextureView *GetDepthRenderTarget() {
|
||||||
|
return GetRenderTarget(depthRenderTarget);
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateRenderTargetControl(maxwell3d::RenderTargetControl control) {
|
void UpdateRenderTargetControl(maxwell3d::RenderTargetControl control) {
|
||||||
renderTargetControl = control;
|
renderTargetControl = control;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ namespace skyline::gpu::format {
|
|||||||
using vka = vk::ImageAspectFlagBits;
|
using vka = vk::ImageAspectFlagBits;
|
||||||
using swc = gpu::texture::SwizzleChannel;
|
using swc = gpu::texture::SwizzleChannel;
|
||||||
|
|
||||||
|
// Color Formats
|
||||||
constexpr Format R8G8B8A8Unorm{sizeof(u32), vkf::eR8G8B8A8Unorm};
|
constexpr Format R8G8B8A8Unorm{sizeof(u32), vkf::eR8G8B8A8Unorm};
|
||||||
constexpr Format R5G6B5Unorm{sizeof(u16), vkf::eR5G6B5UnormPack16};
|
constexpr Format R5G6B5Unorm{sizeof(u16), vkf::eR5G6B5UnormPack16};
|
||||||
constexpr Format A2B10G10R10Unorm{sizeof(u32), vkf::eA2B10G10R10UnormPack32};
|
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 R16G16B16A16Float{sizeof(u16) * 4, vkf::eR16G16B16A16Sfloat};
|
||||||
constexpr Format B8G8R8A8Unorm{sizeof(u32), vkf::eB8G8R8A8Unorm};
|
constexpr Format B8G8R8A8Unorm{sizeof(u32), vkf::eB8G8R8A8Unorm};
|
||||||
constexpr Format B8G8R8A8Srgb{sizeof(u32), vkf::eB8G8R8A8Srgb};
|
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)));
|
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
|
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);
|
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef RENDER_TARGET_ARRAY
|
#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) \
|
#define VIEWPORT_TRANSFORM_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleX, { \
|
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleX, { \
|
||||||
context.SetViewportX(index, scaleX, registers.viewportTransforms[index].translateX); \
|
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<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<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<0x458, std::array<type::VertexAttribute, type::VertexAttributeCount>> vertexAttributeState;
|
||||||
Register<0x487, type::RenderTargetControl> renderTargetControl;
|
Register<0x487, type::RenderTargetControl> renderTargetControl;
|
||||||
|
|
||||||
|
Register<0x48A, u32> depthTargetWidth;
|
||||||
|
Register<0x48B, u32> depthTargetHeight;
|
||||||
|
Register<0x48C, type::RenderTargetArrayMode> depthTargetArrayMode;
|
||||||
|
|
||||||
Register<0x4B9, u32> independentBlendEnable;
|
Register<0x4B9, u32> independentBlendEnable;
|
||||||
Register<0x4BB, u32> alphaTestEnable;
|
Register<0x4BB, u32> alphaTestEnable;
|
||||||
Register<0x4C3, type::CompareOp> depthTestFunc;
|
Register<0x4C3, type::CompareOp> depthTestFunc;
|
||||||
|
Loading…
Reference in New Issue
Block a user