mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 10:45:28 +03:00
Make Render Targets Abstract for Color/Depth RTs
This prefixes all RT functions that deal with color RTs with `Color` and abstracts out common functions that will be used for both color and depth RTs. All common Maxwell3D structures are also moved out of the `ColorRenderTarget` (`RenderTarget` previously) structure.
This commit is contained in:
parent
b0f084ae32
commit
2a8bcc60c7
@ -88,26 +88,31 @@ namespace skyline::gpu::interconnect {
|
||||
}
|
||||
};
|
||||
|
||||
std::array<RenderTarget, maxwell3d::RenderTargetCount> renderTargets{}; //!< 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{};
|
||||
|
||||
public:
|
||||
void SetRenderTargetAddressHigh(size_t index, u32 high) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetRenderTargetAddressHigh(RenderTarget &renderTarget, u32 high) {
|
||||
renderTarget.iova.high = high;
|
||||
renderTarget.guest.mappings.clear();
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetAddressLow(size_t index, u32 low) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetAddressHigh(size_t index, u32 high) {
|
||||
SetRenderTargetAddressHigh(colorRenderTargets.at(index), high);
|
||||
}
|
||||
|
||||
void SetRenderTargetAddressLow(RenderTarget &renderTarget, u32 low) {
|
||||
renderTarget.iova.low = low;
|
||||
renderTarget.guest.mappings.clear();
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetWidth(size_t index, u32 value) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetAddressLow(size_t index, u32 low) {
|
||||
SetRenderTargetAddressLow(colorRenderTargets.at(index), low);
|
||||
}
|
||||
|
||||
void SetRenderTargetWidth(RenderTarget &renderTarget, u32 value) {
|
||||
renderTarget.widthBytes = value;
|
||||
if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format)
|
||||
value /= renderTarget.guest.format->bpb; // Width is in bytes rather than format units for linear textures
|
||||
@ -115,74 +120,82 @@ namespace skyline::gpu::interconnect {
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetHeight(size_t index, u32 value) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetWidth(size_t index, u32 value) {
|
||||
SetRenderTargetWidth(colorRenderTargets.at(index), value);
|
||||
}
|
||||
|
||||
void SetRenderTargetHeight(RenderTarget &renderTarget, u32 value) {
|
||||
renderTarget.guest.dimensions.height = value;
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetFormat(size_t index, maxwell3d::RenderTarget::ColorFormat format) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetHeight(size_t index, u32 value) {
|
||||
SetRenderTargetHeight(colorRenderTargets.at(index), value);
|
||||
}
|
||||
|
||||
void SetColorRenderTargetFormat(size_t index, maxwell3d::ColorRenderTarget::Format format) {
|
||||
auto &renderTarget{colorRenderTargets.at(index)};
|
||||
renderTarget.guest.format = [&]() -> texture::Format {
|
||||
using MaxwellColorRtFormat = maxwell3d::ColorRenderTarget::Format;
|
||||
switch (format) {
|
||||
case maxwell3d::RenderTarget::ColorFormat::None:
|
||||
case MaxwellColorRtFormat::None:
|
||||
return {};
|
||||
case maxwell3d::RenderTarget::ColorFormat::R32B32G32A32Float:
|
||||
case MaxwellColorRtFormat::R32B32G32A32Float:
|
||||
return format::R32B32G32A32Float;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Unorm:
|
||||
case MaxwellColorRtFormat::R16G16B16A16Unorm:
|
||||
return format::R16G16B16A16Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Snorm:
|
||||
case MaxwellColorRtFormat::R16G16B16A16Snorm:
|
||||
return format::R16G16B16A16Snorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Sint:
|
||||
case MaxwellColorRtFormat::R16G16B16A16Sint:
|
||||
return format::R16G16B16A16Sint;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Uint:
|
||||
case MaxwellColorRtFormat::R16G16B16A16Uint:
|
||||
return format::R16G16B16A16Uint;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Float:
|
||||
case MaxwellColorRtFormat::R16G16B16A16Float:
|
||||
return format::R16G16B16A16Float;
|
||||
case maxwell3d::RenderTarget::ColorFormat::B8G8R8A8Unorm:
|
||||
case MaxwellColorRtFormat::B8G8R8A8Unorm:
|
||||
return format::B8G8R8A8Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::B8G8R8A8Srgb:
|
||||
case MaxwellColorRtFormat::B8G8R8A8Srgb:
|
||||
return format::B8G8R8A8Srgb;
|
||||
case maxwell3d::RenderTarget::ColorFormat::A2B10G10R10Unorm:
|
||||
case MaxwellColorRtFormat::A2B10G10R10Unorm:
|
||||
return format::A2B10G10R10Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8G8B8A8Unorm:
|
||||
case MaxwellColorRtFormat::R8G8B8A8Unorm:
|
||||
return format::R8G8B8A8Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::A8B8G8R8Srgb:
|
||||
case MaxwellColorRtFormat::A8B8G8R8Srgb:
|
||||
return format::A8B8G8R8Srgb;
|
||||
case maxwell3d::RenderTarget::ColorFormat::A8B8G8R8Snorm:
|
||||
case MaxwellColorRtFormat::A8B8G8R8Snorm:
|
||||
return format::A8B8G8R8Snorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Unorm:
|
||||
case MaxwellColorRtFormat::R16G16Unorm:
|
||||
return format::R16G16Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Snorm:
|
||||
case MaxwellColorRtFormat::R16G16Snorm:
|
||||
return format::R16G16Snorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Sint:
|
||||
case MaxwellColorRtFormat::R16G16Sint:
|
||||
return format::R16G16Sint;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Uint:
|
||||
case MaxwellColorRtFormat::R16G16Uint:
|
||||
return format::R16G16Uint;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Float:
|
||||
case MaxwellColorRtFormat::R16G16Float:
|
||||
return format::R16G16Float;
|
||||
case maxwell3d::RenderTarget::ColorFormat::B10G11R11Float:
|
||||
case MaxwellColorRtFormat::B10G11R11Float:
|
||||
return format::B10G11R11Float;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R32Float:
|
||||
case MaxwellColorRtFormat::R32Float:
|
||||
return format::R32Float;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8G8Unorm:
|
||||
case MaxwellColorRtFormat::R8G8Unorm:
|
||||
return format::R8G8Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8G8Snorm:
|
||||
case MaxwellColorRtFormat::R8G8Snorm:
|
||||
return format::R8G8Snorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16Unorm:
|
||||
case MaxwellColorRtFormat::R16Unorm:
|
||||
return format::R16Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R16Float:
|
||||
case MaxwellColorRtFormat::R16Float:
|
||||
return format::R16Float;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8Unorm:
|
||||
case MaxwellColorRtFormat::R8Unorm:
|
||||
return format::R8Unorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8Snorm:
|
||||
case MaxwellColorRtFormat::R8Snorm:
|
||||
return format::R8Snorm;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8Sint:
|
||||
case MaxwellColorRtFormat::R8Sint:
|
||||
return format::R8Sint;
|
||||
case maxwell3d::RenderTarget::ColorFormat::R8Uint:
|
||||
case MaxwellColorRtFormat::R8Uint:
|
||||
return format::R8Uint;
|
||||
default:
|
||||
throw exception("Cannot translate the supplied RT format: 0x{:X}", static_cast<u32>(format));
|
||||
throw exception("Cannot translate the supplied color RT format: 0x{:X}", static_cast<u32>(format));
|
||||
}
|
||||
}();
|
||||
|
||||
@ -193,8 +206,7 @@ namespace skyline::gpu::interconnect {
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetTileMode(size_t index, maxwell3d::RenderTarget::TileMode mode) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetRenderTargetTileMode(RenderTarget &renderTarget, maxwell3d::RenderTargetTileMode mode) {
|
||||
auto &config{renderTarget.guest.tileConfig};
|
||||
if (mode.isLinear) {
|
||||
if (config.mode != texture::TileMode::Linear && renderTarget.guest.format) {
|
||||
@ -217,22 +229,32 @@ namespace skyline::gpu::interconnect {
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetArrayMode(size_t index, maxwell3d::RenderTarget::ArrayMode mode) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetTileMode(size_t index, maxwell3d::RenderTargetTileMode mode) {
|
||||
SetRenderTargetTileMode(colorRenderTargets.at(index), 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 SetRenderTargetLayerStride(size_t index, u32 layerStrideLsr2) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetArrayMode(size_t index, maxwell3d::RenderTargetArrayMode mode) {
|
||||
SetRenderTargetArrayMode(colorRenderTargets.at(index), mode);
|
||||
}
|
||||
|
||||
void SetRenderTargetLayerStride(RenderTarget &renderTarget, u32 layerStrideLsr2) {
|
||||
renderTarget.guest.layerStride = layerStrideLsr2 << 2;
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
void SetRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
void SetColorRenderTargetLayerStride(size_t index, u32 layerStrideLsr2) {
|
||||
SetRenderTargetLayerStride(colorRenderTargets.at(index), layerStrideLsr2);
|
||||
}
|
||||
|
||||
void SetColorRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
|
||||
auto &renderTarget{colorRenderTargets.at(index)};
|
||||
if (baseArrayLayer > std::numeric_limits<u16>::max())
|
||||
throw exception("Base array layer ({}) exceeds the range of array count ({}) (with layer count = {})", baseArrayLayer, std::numeric_limits<u16>::max(), renderTarget.guest.layerCount);
|
||||
|
||||
@ -240,8 +262,7 @@ namespace skyline::gpu::interconnect {
|
||||
renderTarget.view.reset();
|
||||
}
|
||||
|
||||
TextureView *GetRenderTarget(size_t index) {
|
||||
auto &renderTarget{renderTargets.at(index)};
|
||||
TextureView *GetRenderTarget(RenderTarget& renderTarget) {
|
||||
if (renderTarget.disabled)
|
||||
return nullptr;
|
||||
else if (renderTarget.view)
|
||||
@ -259,6 +280,10 @@ namespace skyline::gpu::interconnect {
|
||||
return renderTarget.view.get();
|
||||
}
|
||||
|
||||
TextureView *GetColorRenderTarget(size_t index) {
|
||||
return GetRenderTarget(colorRenderTargets.at(index));
|
||||
}
|
||||
|
||||
void UpdateRenderTargetControl(maxwell3d::RenderTargetControl control) {
|
||||
renderTargetControl = control;
|
||||
}
|
||||
@ -333,7 +358,7 @@ namespace skyline::gpu::interconnect {
|
||||
|
||||
void ClearBuffers(maxwell3d::ClearBuffers clear) {
|
||||
auto renderTargetIndex{renderTargetControl[clear.renderTargetId]};
|
||||
auto renderTarget{GetRenderTarget(renderTargetIndex)};
|
||||
auto renderTarget{GetColorRenderTarget(renderTargetIndex)};
|
||||
if (renderTarget) {
|
||||
std::lock_guard lock(*renderTarget->texture);
|
||||
|
||||
@ -1141,7 +1166,7 @@ namespace skyline::gpu::interconnect {
|
||||
std::vector<TextureView *> activeRenderTargets;
|
||||
|
||||
for (u32 index{}; index < maxwell3d::RenderTargetCount; index++) {
|
||||
auto renderTarget{GetRenderTarget(index)};
|
||||
auto renderTarget{GetColorRenderTarget(index)};
|
||||
if (renderTarget) {
|
||||
renderTargetLocks.emplace_back(*renderTarget);
|
||||
activeRenderTargets.push_back(renderTarget);
|
||||
|
@ -42,16 +42,32 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
|
||||
constexpr static size_t RenderTargetCount{8}; //!< Maximum amount of render targets that can be bound at once on Maxwell 3D
|
||||
|
||||
struct RenderTargetTileMode {
|
||||
u8 blockWidthLog2 : 4; //!< The width of a block in GOBs with log2 encoding, this is always assumed to be 1 as it is the only configuration the X1 supports
|
||||
u8 blockHeightLog2 : 4; //!< The height of a block in GOBs with log2 encoding
|
||||
u8 blockDepthLog2 : 4; //!< The depth of a block in GOBs with log2 encoding
|
||||
bool isLinear : 1;
|
||||
u8 _pad0_ : 3;
|
||||
bool is3d : 1;
|
||||
u16 _pad1_ : 15;
|
||||
};
|
||||
|
||||
struct RenderTargetArrayMode {
|
||||
u16 layerCount;
|
||||
bool volume : 1;
|
||||
u16 _pad_ : 15;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The target image's metadata for any rendering operations
|
||||
* @note Any render target with ColorFormat::None as their format are effectively disabled
|
||||
*/
|
||||
struct RenderTarget {
|
||||
struct ColorRenderTarget {
|
||||
Address address;
|
||||
u32 width;
|
||||
u32 height;
|
||||
|
||||
enum class ColorFormat : u32 {
|
||||
enum class Format : u32 {
|
||||
None = 0x0,
|
||||
R32B32G32A32Float = 0xC0,
|
||||
R16G16B16A16Unorm = 0xC6,
|
||||
@ -82,27 +98,15 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
R8Uint = 0xF6,
|
||||
} format;
|
||||
|
||||
struct TileMode {
|
||||
u8 blockWidthLog2 : 4; //!< The width of a block in GOBs with log2 encoding, this is always assumed to be 1 as it is the only configuration the X1 supports
|
||||
u8 blockHeightLog2 : 4; //!< The height of a block in GOBs with log2 encoding
|
||||
u8 blockDepthLog2 : 4; //!< The depth of a block in GOBs with log2 encoding
|
||||
bool isLinear : 1;
|
||||
u8 _pad0_ : 3;
|
||||
bool is3d : 1;
|
||||
u16 _pad1_ : 15;
|
||||
} tileMode;
|
||||
RenderTargetTileMode tileMode;
|
||||
|
||||
struct ArrayMode {
|
||||
u16 layerCount;
|
||||
bool volume : 1;
|
||||
u16 _pad_ : 15;
|
||||
} arrayMode;
|
||||
RenderTargetArrayMode arrayMode;
|
||||
|
||||
u32 layerStrideLsr2; //!< The length of the stride of a layer shifted right by 2 bits
|
||||
u32 baseLayer;
|
||||
u32 _pad_[0x7];
|
||||
};
|
||||
static_assert(sizeof(RenderTarget) == (0x10 * sizeof(u32)));
|
||||
static_assert(sizeof(ColorRenderTarget) == (0x10 * sizeof(u32)));
|
||||
|
||||
constexpr static size_t ViewportCount{16}; //!< Amount of viewports on Maxwell 3D, array size for any per-viewport parameter such as transform, scissors, etc
|
||||
|
||||
|
@ -84,31 +84,31 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
#define RENDER_TARGET_ARRAY(z, index, data) \
|
||||
MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(renderTargets, index, address, high, { \
|
||||
context.SetRenderTargetAddressHigh(index, high); \
|
||||
context.SetColorRenderTargetAddressHigh(index, high); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(renderTargets, index, address, low, { \
|
||||
context.SetRenderTargetAddressLow(index, low); \
|
||||
context.SetColorRenderTargetAddressLow(index, low); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, width, { \
|
||||
context.SetRenderTargetWidth(index, width); \
|
||||
context.SetColorRenderTargetWidth(index, width); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, height, { \
|
||||
context.SetRenderTargetHeight(index, height); \
|
||||
context.SetColorRenderTargetHeight(index, height); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, format, { \
|
||||
context.SetRenderTargetFormat(index, format); \
|
||||
context.SetColorRenderTargetFormat(index, format); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, tileMode, { \
|
||||
context.SetRenderTargetTileMode(index, tileMode); \
|
||||
context.SetColorRenderTargetTileMode(index, tileMode); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, arrayMode, { \
|
||||
context.SetRenderTargetArrayMode(index, arrayMode); \
|
||||
context.SetColorRenderTargetArrayMode(index, arrayMode); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, layerStrideLsr2, { \
|
||||
context.SetRenderTargetLayerStride(index, layerStrideLsr2); \
|
||||
context.SetColorRenderTargetLayerStride(index, layerStrideLsr2); \
|
||||
}) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, baseLayer, { \
|
||||
context.SetRenderTargetBaseLayer(index, baseLayer); \
|
||||
context.SetColorRenderTargetBaseLayer(index, baseLayer); \
|
||||
})
|
||||
|
||||
BOOST_PP_REPEAT(8, RENDER_TARGET_ARRAY, 0)
|
||||
|
@ -68,7 +68,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0xB2, type::SyncpointAction> syncpointAction;
|
||||
|
||||
Register<0xDF, u32> rasterizerEnable;
|
||||
Register<0x200, std::array<type::RenderTarget, type::RenderTargetCount>> renderTargets;
|
||||
Register<0x200, std::array<type::ColorRenderTarget, type::RenderTargetCount>> renderTargets;
|
||||
Register<0x280, std::array<type::ViewportTransform, type::ViewportCount>> viewportTransforms;
|
||||
Register<0x300, std::array<type::Viewport, type::ViewportCount>> viewports;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user