mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 13:01:50 +01:00
Track RT format info in PackedPipelineState and move VK conv code there
When caching pipelines we can't cache whole images, only their formats so refactor PackedPipelineState so that it can be used for pipeline creation, as opposed to passing in a list of attachments.
This commit is contained in:
parent
bc7e1eb380
commit
2e96248fb6
@ -10,12 +10,17 @@
|
||||
#pragma clang diagnostic ignored "-Wbitfield-enum-conversion"
|
||||
|
||||
namespace skyline::gpu::interconnect::maxwell3d {
|
||||
static constexpr u8 DepthDisabledMagic{0x1f}; // Format value (unused in HW) used to signal that depth is disabled
|
||||
|
||||
void PackedPipelineState::SetColorRenderTargetFormat(size_t index, engine::ColorTarget::Format format) {
|
||||
colorRenderTargetFormats[index] = static_cast<u8>(format);
|
||||
}
|
||||
|
||||
void PackedPipelineState::SetDepthRenderTargetFormat(engine::ZtFormat format) {
|
||||
void PackedPipelineState::SetDepthRenderTargetFormat(engine::ZtFormat format, bool enabled) {
|
||||
if (enabled)
|
||||
depthRenderTargetFormat = static_cast<u8>(format) - static_cast<u8>(engine::ZtFormat::ZF32);
|
||||
else
|
||||
depthRenderTargetFormat = DepthDisabledMagic;
|
||||
}
|
||||
|
||||
void PackedPipelineState::SetVertexBinding(u32 index, engine::VertexStream stream, engine::VertexStreamInstance instance) {
|
||||
@ -103,6 +108,133 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
return static_cast<vk::LogicOp>(logicOp);
|
||||
}
|
||||
|
||||
texture::Format PackedPipelineState::GetColorRenderTargetFormat(size_t rawIndex) const {
|
||||
auto format{static_cast<engine::ColorTarget::Format>(colorRenderTargetFormats[rawIndex])};
|
||||
#define FORMAT_CASE_BASE(engineFormat, skFormat, warn) \
|
||||
case engine::ColorTarget::Format::engineFormat: \
|
||||
if constexpr (warn) \
|
||||
Logger::Warn("Partially supported RT format: " #engineFormat " used!"); \
|
||||
return skyline::gpu::format::skFormat
|
||||
|
||||
#define FORMAT_CASE(engineFormat, skFormat) FORMAT_CASE_BASE(engineFormat, skFormat, false)
|
||||
#define FORMAT_CASE_WARN(engineFormat, skFormat) FORMAT_CASE_BASE(engineFormat, skFormat, true)
|
||||
|
||||
switch (format) {
|
||||
case engine::ColorTarget::Format::Disabled:
|
||||
return texture::Format{};
|
||||
FORMAT_CASE(RF32_GF32_BF32_AF32, R32G32B32A32Float);
|
||||
FORMAT_CASE(RS32_GS32_BS32_AS32, R32G32B32A32Sint);
|
||||
FORMAT_CASE(RU32_GU32_BU32_AU32, R32G32B32A32Uint);
|
||||
FORMAT_CASE_WARN(RF32_GF32_BF32_X32, R32G32B32A32Float); // TODO: ignore X32 component with blend
|
||||
FORMAT_CASE_WARN(RS32_GS32_BS32_X32, R32G32B32A32Sint); // TODO: ^
|
||||
FORMAT_CASE_WARN(RU32_GU32_BU32_X32, R32G32B32A32Uint); // TODO: ^
|
||||
FORMAT_CASE(R16_G16_B16_A16, R16G16B16A16Unorm);
|
||||
FORMAT_CASE(RN16_GN16_BN16_AN16, R16G16B16A16Snorm);
|
||||
FORMAT_CASE(RS16_GS16_BS16_AS16, R16G16B16A16Sint);
|
||||
FORMAT_CASE(RU16_GU16_BU16_AU16, R16G16B16A16Uint);
|
||||
FORMAT_CASE(RF16_GF16_BF16_AF16, R16G16B16A16Float);
|
||||
FORMAT_CASE(RF32_GF32, R32G32Float);
|
||||
FORMAT_CASE(RS32_GS32, R32G32Sint);
|
||||
FORMAT_CASE(RU32_GU32, R32G32Uint);
|
||||
FORMAT_CASE_WARN(RF16_GF16_BF16_X16, R16G16B16A16Float); // TODO: ^^
|
||||
FORMAT_CASE(A8R8G8B8, B8G8R8A8Unorm);
|
||||
FORMAT_CASE(A8RL8GL8BL8, B8G8R8A8Srgb);
|
||||
FORMAT_CASE(A2B10G10R10, A2B10G10R10Unorm);
|
||||
FORMAT_CASE(AU2BU10GU10RU10, A2B10G10R10Uint);
|
||||
FORMAT_CASE(A8B8G8R8, R8G8B8A8Unorm);
|
||||
FORMAT_CASE(A8BL8GL8RL8, R8G8B8A8Srgb);
|
||||
FORMAT_CASE(AN8BN8GN8RN8, R8G8B8A8Snorm);
|
||||
FORMAT_CASE(AS8BS8GS8RS8, R8G8B8A8Sint);
|
||||
FORMAT_CASE(AU8BU8GU8RU8, R8G8B8A8Uint);
|
||||
FORMAT_CASE(R16_G16, R16G16Unorm);
|
||||
FORMAT_CASE(RN16_GN16, R16G16Snorm);
|
||||
FORMAT_CASE(RS16_GS16, R16G16Sint);
|
||||
FORMAT_CASE(RU16_GU16, R16G16Uint);
|
||||
FORMAT_CASE(RF16_GF16, R16G16Float);
|
||||
FORMAT_CASE(A2R10G10B10, A2B10G10R10Unorm);
|
||||
FORMAT_CASE(BF10GF11RF11, B10G11R11Float);
|
||||
FORMAT_CASE(RS32, R32Sint);
|
||||
FORMAT_CASE(RU32, R32Uint);
|
||||
FORMAT_CASE(RF32, R32Float);
|
||||
FORMAT_CASE_WARN(X8R8G8B8, B8G8R8A8Unorm); // TODO: ^^
|
||||
FORMAT_CASE_WARN(X8RL8GL8BL8, B8G8R8A8Srgb); // TODO: ^^
|
||||
FORMAT_CASE(R5G6B5, R5G6B5Unorm);
|
||||
FORMAT_CASE(A1R5G5B5, A1R5G5B5Unorm);
|
||||
FORMAT_CASE(G8R8, R8G8Unorm);
|
||||
FORMAT_CASE(GN8RN8, R8G8Snorm);
|
||||
FORMAT_CASE(GS8RS8, R8G8Sint);
|
||||
FORMAT_CASE(GU8RU8, R8G8Uint);
|
||||
FORMAT_CASE(R16, R16Unorm);
|
||||
FORMAT_CASE(RN16, R16Snorm);
|
||||
FORMAT_CASE(RS16, R16Sint);
|
||||
FORMAT_CASE(RU16, R16Uint);
|
||||
FORMAT_CASE(RF16, R16Float);
|
||||
FORMAT_CASE(R8, R8Unorm);
|
||||
FORMAT_CASE(RN8, R8Snorm);
|
||||
FORMAT_CASE(RS8, R8Sint);
|
||||
FORMAT_CASE(RU8, R8Uint);
|
||||
// FORMAT_CASE(A8, A8Unorm);
|
||||
FORMAT_CASE_WARN(X1R5G5B5, A1R5G5B5Unorm); // TODO: ^^
|
||||
FORMAT_CASE_WARN(X8B8G8R8, R8G8B8A8Unorm); // TODO: ^^
|
||||
FORMAT_CASE_WARN(X8BL8GL8RL8, R8G8B8A8Srgb); // TODO: ^^
|
||||
FORMAT_CASE_WARN(Z1R5G5B5, A1R5G5B5Unorm); // TODO: ^^ but with zero blend
|
||||
FORMAT_CASE_WARN(O1R5G5B5, A1R5G5B5Unorm); // TODO: ^^ but with one blend
|
||||
FORMAT_CASE_WARN(Z8R8G8B8, B8G8R8A8Unorm); // TODO: ^^ but with zero blend
|
||||
FORMAT_CASE_WARN(O8R8G8B8, B8G8R8A8Unorm); // TODO: ^^ but with one blend
|
||||
// FORMAT_CASE(R32, R32Unorm);
|
||||
// FORMAT_CASE(A16, A16Unorm);
|
||||
// FORMAT_CASE(AF16, A16Float);
|
||||
// FORMAT_CASE(AF32, A32Float);
|
||||
// FORMAT_CASE(A8R8, R8A8Unorm);
|
||||
// FORMAT_CASE(R16_A16, R16A16Unorm);
|
||||
// FORMAT_CASE(RF16_AF16, R16A16Float);
|
||||
// FORMAT_CASE(RF32_AF32, R32A32Float);
|
||||
// FORMAT_CASE(B8G8R8A8, A8R8G8B8Unorm)
|
||||
default:
|
||||
throw exception("Unsupported colour rendertarget format: 0x{:X}", static_cast<u32>(format));
|
||||
}
|
||||
|
||||
#undef FORMAT_CASE
|
||||
#undef FORMAT_CASE_WARN
|
||||
#undef FORMAT_CASE_BASE
|
||||
}
|
||||
|
||||
bool PackedPipelineState::IsColorRenderTargetEnabled(size_t rawIndex) const {
|
||||
return colorRenderTargetFormats[rawIndex] != 0;
|
||||
}
|
||||
|
||||
size_t PackedPipelineState::GetColorRenderTargetCount() const {
|
||||
for (size_t i{engine::ColorTargetCount}; i > 0 ; i--)
|
||||
if (IsColorRenderTargetEnabled(i - 1))
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture::Format PackedPipelineState::GetDepthRenderTargetFormat() const {
|
||||
if (depthRenderTargetFormat == DepthDisabledMagic)
|
||||
return texture::Format{};
|
||||
|
||||
auto format{static_cast<engine::ZtFormat>(depthRenderTargetFormat + static_cast<u8>(engine::ZtFormat::ZF32))};
|
||||
#define FORMAT_CASE(engineFormat, skFormat) \
|
||||
case engine::ZtFormat::engineFormat: \
|
||||
return skyline::gpu::format::skFormat
|
||||
|
||||
switch (format) {
|
||||
FORMAT_CASE(Z16, D16Unorm);
|
||||
FORMAT_CASE(Z24S8, S8UintD24Unorm);
|
||||
FORMAT_CASE(X8Z24, D24UnormX8Uint);
|
||||
FORMAT_CASE(S8Z24, D24UnormS8Uint);
|
||||
FORMAT_CASE(S8, S8Uint);
|
||||
FORMAT_CASE(ZF32, D32Float);
|
||||
FORMAT_CASE(ZF32_X24S8, D32FloatS8Uint);
|
||||
default:
|
||||
throw exception("Unsupported depth rendertarget format: 0x{:X}", static_cast<u32>(format));
|
||||
}
|
||||
|
||||
#undef FORMAT_CASE
|
||||
}
|
||||
|
||||
static u8 ConvertStencilOp(engine::StencilOps::Op op) {
|
||||
auto conv{[&]() {
|
||||
switch (op) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <gpu/texture/format.h>
|
||||
#include <shader_compiler/runtime_info.h>
|
||||
#include "common.h"
|
||||
|
||||
@ -67,7 +68,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
float pointSize;
|
||||
std::array<engine::VertexAttribute, engine::VertexAttributeCount> vertexAttributes;
|
||||
std::array<u8, engine::ColorTargetCount> colorRenderTargetFormats; //!< Use {Set, Get}ColorRenderTargetFormat
|
||||
std::bitset<8> activeColorTargets;
|
||||
engine::CtSelect ctSelect;
|
||||
std::array<u32, 8> postVtgShaderAttributeSkipMask;
|
||||
|
||||
struct VertexBinding {
|
||||
@ -105,9 +106,12 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
};
|
||||
std::array<TransformFeedbackVarying, 0x100> transformFeedbackVaryings{};
|
||||
|
||||
void SetColorRenderTargetFormat(size_t index, engine::ColorTarget::Format format);
|
||||
/**
|
||||
* @param rawIndex Index in HW ignoring the ctSelect register
|
||||
*/
|
||||
void SetColorRenderTargetFormat(size_t rawIndex, engine::ColorTarget::Format format);
|
||||
|
||||
void SetDepthRenderTargetFormat(engine::ZtFormat format);
|
||||
void SetDepthRenderTargetFormat(engine::ZtFormat format, bool enabled);
|
||||
|
||||
void SetVertexBinding(u32 index, engine::VertexStream stream, engine::VertexStreamInstance instance);
|
||||
|
||||
@ -133,6 +137,20 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
void SetAttachmentBlendState(u32 index, bool enable, engine::CtWrite writeMask, engine::BlendPerTarget blend);
|
||||
|
||||
/**
|
||||
* @param rawIndex Index in HW ignoring the ctSelect register
|
||||
*/
|
||||
texture::Format GetColorRenderTargetFormat(size_t rawIndex) const;
|
||||
|
||||
/**
|
||||
* @param rawIndex Index in HW ignoring the ctSelect register
|
||||
*/
|
||||
bool IsColorRenderTargetEnabled(size_t rawIndex) const;
|
||||
|
||||
size_t GetColorRenderTargetCount() const;
|
||||
|
||||
texture::Format GetDepthRenderTargetFormat() const;
|
||||
|
||||
std::array<vk::StencilOpState, 2> GetStencilOpsState() const;
|
||||
|
||||
vk::PipelineColorBlendAttachmentState GetAttachmentBlendState(u32 index) const;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <kernel/memory.h>
|
||||
#include <soc/gm20b/channel.h>
|
||||
#include <soc/gm20b/gmmu.h>
|
||||
#include <gpu/texture/format.h>
|
||||
#include <gpu.h>
|
||||
#include "pipeline_state.h"
|
||||
|
||||
@ -34,94 +33,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
ColorRenderTargetState::ColorRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine, size_t index) : engine{manager, dirtyHandle, engine}, index{index} {}
|
||||
|
||||
static texture::Format ConvertColorRenderTargetFormat(engine::ColorTarget::Format format) {
|
||||
#define FORMAT_CASE_BASE(engineFormat, skFormat, warn) \
|
||||
case engine::ColorTarget::Format::engineFormat: \
|
||||
if constexpr (warn) \
|
||||
Logger::Warn("Partially supported RT format: " #engineFormat " used!"); \
|
||||
return skyline::gpu::format::skFormat
|
||||
|
||||
#define FORMAT_CASE(engineFormat, skFormat) FORMAT_CASE_BASE(engineFormat, skFormat, false)
|
||||
#define FORMAT_CASE_WARN(engineFormat, skFormat) FORMAT_CASE_BASE(engineFormat, skFormat, true)
|
||||
|
||||
switch (format) {
|
||||
FORMAT_CASE(RF32_GF32_BF32_AF32, R32G32B32A32Float);
|
||||
FORMAT_CASE(RS32_GS32_BS32_AS32, R32G32B32A32Sint);
|
||||
FORMAT_CASE(RU32_GU32_BU32_AU32, R32G32B32A32Uint);
|
||||
FORMAT_CASE_WARN(RF32_GF32_BF32_X32, R32G32B32A32Float); // TODO: ignore X32 component with blend
|
||||
FORMAT_CASE_WARN(RS32_GS32_BS32_X32, R32G32B32A32Sint); // TODO: ^
|
||||
FORMAT_CASE_WARN(RU32_GU32_BU32_X32, R32G32B32A32Uint); // TODO: ^
|
||||
FORMAT_CASE(R16_G16_B16_A16, R16G16B16A16Unorm);
|
||||
FORMAT_CASE(RN16_GN16_BN16_AN16, R16G16B16A16Snorm);
|
||||
FORMAT_CASE(RS16_GS16_BS16_AS16, R16G16B16A16Sint);
|
||||
FORMAT_CASE(RU16_GU16_BU16_AU16, R16G16B16A16Uint);
|
||||
FORMAT_CASE(RF16_GF16_BF16_AF16, R16G16B16A16Float);
|
||||
FORMAT_CASE(RF32_GF32, R32G32Float);
|
||||
FORMAT_CASE(RS32_GS32, R32G32Sint);
|
||||
FORMAT_CASE(RU32_GU32, R32G32Uint);
|
||||
FORMAT_CASE_WARN(RF16_GF16_BF16_X16, R16G16B16A16Float); // TODO: ^^
|
||||
FORMAT_CASE(A8R8G8B8, B8G8R8A8Unorm);
|
||||
FORMAT_CASE(A8RL8GL8BL8, B8G8R8A8Srgb);
|
||||
FORMAT_CASE(A2B10G10R10, A2B10G10R10Unorm);
|
||||
FORMAT_CASE(AU2BU10GU10RU10, A2B10G10R10Uint);
|
||||
FORMAT_CASE(A8B8G8R8, R8G8B8A8Unorm);
|
||||
FORMAT_CASE(A8BL8GL8RL8, R8G8B8A8Srgb);
|
||||
FORMAT_CASE(AN8BN8GN8RN8, R8G8B8A8Snorm);
|
||||
FORMAT_CASE(AS8BS8GS8RS8, R8G8B8A8Sint);
|
||||
FORMAT_CASE(AU8BU8GU8RU8, R8G8B8A8Uint);
|
||||
FORMAT_CASE(R16_G16, R16G16Unorm);
|
||||
FORMAT_CASE(RN16_GN16, R16G16Snorm);
|
||||
FORMAT_CASE(RS16_GS16, R16G16Sint);
|
||||
FORMAT_CASE(RU16_GU16, R16G16Uint);
|
||||
FORMAT_CASE(RF16_GF16, R16G16Float);
|
||||
FORMAT_CASE(A2R10G10B10, A2B10G10R10Unorm);
|
||||
FORMAT_CASE(BF10GF11RF11, B10G11R11Float);
|
||||
FORMAT_CASE(RS32, R32Sint);
|
||||
FORMAT_CASE(RU32, R32Uint);
|
||||
FORMAT_CASE(RF32, R32Float);
|
||||
FORMAT_CASE_WARN(X8R8G8B8, B8G8R8A8Unorm); // TODO: ^^
|
||||
FORMAT_CASE_WARN(X8RL8GL8BL8, B8G8R8A8Srgb); // TODO: ^^
|
||||
FORMAT_CASE(R5G6B5, R5G6B5Unorm);
|
||||
FORMAT_CASE(A1R5G5B5, A1R5G5B5Unorm);
|
||||
FORMAT_CASE(G8R8, R8G8Unorm);
|
||||
FORMAT_CASE(GN8RN8, R8G8Snorm);
|
||||
FORMAT_CASE(GS8RS8, R8G8Sint);
|
||||
FORMAT_CASE(GU8RU8, R8G8Uint);
|
||||
FORMAT_CASE(R16, R16Unorm);
|
||||
FORMAT_CASE(RN16, R16Snorm);
|
||||
FORMAT_CASE(RS16, R16Sint);
|
||||
FORMAT_CASE(RU16, R16Uint);
|
||||
FORMAT_CASE(RF16, R16Float);
|
||||
FORMAT_CASE(R8, R8Unorm);
|
||||
FORMAT_CASE(RN8, R8Snorm);
|
||||
FORMAT_CASE(RS8, R8Sint);
|
||||
FORMAT_CASE(RU8, R8Uint);
|
||||
// FORMAT_CASE(A8, A8Unorm);
|
||||
FORMAT_CASE_WARN(X1R5G5B5, A1R5G5B5Unorm); // TODO: ^^
|
||||
FORMAT_CASE_WARN(X8B8G8R8, R8G8B8A8Unorm); // TODO: ^^
|
||||
FORMAT_CASE_WARN(X8BL8GL8RL8, R8G8B8A8Srgb); // TODO: ^^
|
||||
FORMAT_CASE_WARN(Z1R5G5B5, A1R5G5B5Unorm); // TODO: ^^ but with zero blend
|
||||
FORMAT_CASE_WARN(O1R5G5B5, A1R5G5B5Unorm); // TODO: ^^ but with one blend
|
||||
FORMAT_CASE_WARN(Z8R8G8B8, B8G8R8A8Unorm); // TODO: ^^ but with zero blend
|
||||
FORMAT_CASE_WARN(O8R8G8B8, B8G8R8A8Unorm); // TODO: ^^ but with one blend
|
||||
// FORMAT_CASE(R32, R32Unorm);
|
||||
// FORMAT_CASE(A16, A16Unorm);
|
||||
// FORMAT_CASE(AF16, A16Float);
|
||||
// FORMAT_CASE(AF32, A32Float);
|
||||
// FORMAT_CASE(A8R8, R8A8Unorm);
|
||||
// FORMAT_CASE(R16_A16, R16A16Unorm);
|
||||
// FORMAT_CASE(RF16_AF16, R16A16Float);
|
||||
// FORMAT_CASE(RF32_AF32, R32A32Float);
|
||||
// FORMAT_CASE(B8G8R8A8, A8R8G8B8Unorm)
|
||||
default:
|
||||
throw exception("Unsupported colour rendertarget format: 0x{:X}", static_cast<u32>(format));
|
||||
}
|
||||
|
||||
#undef FORMAT_CASE
|
||||
#undef FORMAT_CASE_WARN
|
||||
#undef FORMAT_CASE_BASE
|
||||
}
|
||||
|
||||
void ColorRenderTargetState::Flush(InterconnectContext &ctx, PackedPipelineState &packedState) {
|
||||
auto &target{engine->colorTarget};
|
||||
packedState.SetColorRenderTargetFormat(index, target.format);
|
||||
@ -132,7 +43,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
|
||||
GuestTexture guest{};
|
||||
guest.format = ConvertColorRenderTargetFormat(target.format);
|
||||
guest.format = packedState.GetColorRenderTargetFormat(index);
|
||||
guest.aspect = vk::ImageAspectFlagBits::eColor;
|
||||
guest.baseArrayLayer = target.layerOffset;
|
||||
|
||||
@ -167,6 +78,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
view = ctx.gpu.texture.FindOrCreate(guest, ctx.executor.tag);
|
||||
} else {
|
||||
packedState.SetColorRenderTargetFormat(index, engine::ColorTarget::Format::Disabled);
|
||||
view = {};
|
||||
}
|
||||
}
|
||||
@ -178,28 +90,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
DepthRenderTargetState::DepthRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {}
|
||||
|
||||
static texture::Format ConvertDepthRenderTargetFormat(engine::ZtFormat format) {
|
||||
#define FORMAT_CASE(engineFormat, skFormat) \
|
||||
case engine::ZtFormat::engineFormat: \
|
||||
return skyline::gpu::format::skFormat
|
||||
|
||||
switch (format) {
|
||||
FORMAT_CASE(Z16, D16Unorm);
|
||||
FORMAT_CASE(Z24S8, S8UintD24Unorm);
|
||||
FORMAT_CASE(X8Z24, D24UnormX8Uint);
|
||||
FORMAT_CASE(S8Z24, D24UnormS8Uint);
|
||||
FORMAT_CASE(S8, S8Uint);
|
||||
FORMAT_CASE(ZF32, D32Float);
|
||||
FORMAT_CASE(ZF32_X24S8, D32FloatS8Uint);
|
||||
default:
|
||||
throw exception("Unsupported depth rendertarget format: 0x{:X}", static_cast<u32>(format));
|
||||
}
|
||||
|
||||
#undef FORMAT_CASE
|
||||
}
|
||||
|
||||
void DepthRenderTargetState::Flush(InterconnectContext &ctx, PackedPipelineState &packedState) {
|
||||
packedState.SetDepthRenderTargetFormat(engine->ztFormat);
|
||||
packedState.SetDepthRenderTargetFormat(engine->ztFormat, engine->ztSelect.targetCount);
|
||||
|
||||
if (!engine->ztSelect.targetCount) {
|
||||
view = {};
|
||||
@ -207,7 +99,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
|
||||
GuestTexture guest{};
|
||||
guest.format = ConvertDepthRenderTargetFormat(engine->ztFormat);
|
||||
guest.format = packedState.GetDepthRenderTargetFormat();
|
||||
guest.aspect = guest.format->vkAspect;
|
||||
guest.baseArrayLayer = engine->ztLayer.offset;
|
||||
|
||||
@ -238,6 +130,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
view = ctx.gpu.texture.FindOrCreate(guest, ctx.executor.tag);
|
||||
} else {
|
||||
packedState.SetDepthRenderTargetFormat(engine->ztFormat, false);
|
||||
view = {};
|
||||
}
|
||||
}
|
||||
@ -407,8 +300,10 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
packedState.SetLogicOp(engine->logicOp.func);
|
||||
|
||||
for (u32 i{}; i < engine::ColorTargetCount; i++) {
|
||||
bool rtEnabled{packedState.IsColorRenderTargetEnabled(packedState.ctSelect[i])};
|
||||
enabledRts.set(i, rtEnabled);
|
||||
auto ctWrite{[&]() {
|
||||
if (!packedState.activeColorTargets.test(i))
|
||||
if (!rtEnabled)
|
||||
return engine::CtWrite{};
|
||||
|
||||
if (engine->singleCtWriteControl)
|
||||
@ -417,7 +312,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
return engine->ctWrites[i];
|
||||
}()};
|
||||
|
||||
bool enable{engine->blend.enable[i] != 0 && packedState.activeColorTargets.test(i)};
|
||||
bool enable{engine->blend.enable[i] != 0 && rtEnabled};
|
||||
|
||||
if (engine->blendStatePerTargetEnable)
|
||||
packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blendPerTargets[i]);
|
||||
@ -426,6 +321,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
}
|
||||
|
||||
bool ColorBlendState::Refresh(PackedPipelineState &packedState) {
|
||||
for (u32 i{}; i < engine::ColorTargetCount; i++)
|
||||
if (enabledRts.test(i) != packedState.IsColorRenderTargetEnabled(packedState.ctSelect[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Transform Feedback State */
|
||||
void TransformFeedbackState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||
manager.Bind(handle, streamOutputEnable, streamOutControls, streamOutLayoutSelect);
|
||||
@ -491,6 +394,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
void PipelineState::Flush(InterconnectContext &ctx, Textures &textures, ConstantBufferSet &constantBuffers, StateUpdateBuilder &builder) {
|
||||
packedState.dynamicStateActive = ctx.gpu.traits.supportsExtendedDynamicState;
|
||||
packedState.ctSelect = ctSelect;
|
||||
|
||||
std::array<ShaderBinary, engine::PipelineCount> shaderBinaries;
|
||||
for (size_t i{}; i < engine::PipelineCount; i++) {
|
||||
@ -500,11 +404,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
|
||||
colorAttachments.clear();
|
||||
packedState.activeColorTargets.reset();
|
||||
for (size_t i{}; i < ctSelect.count; i++) {
|
||||
const auto &view{colorRenderTargets[ctSelect[i]].UpdateGet(ctx, packedState).view.get()};
|
||||
colorAttachments.push_back(view);
|
||||
packedState.activeColorTargets.set(i);
|
||||
|
||||
if (view)
|
||||
ctx.executor.AttachTexture(view);
|
||||
|
@ -212,7 +212,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
void Flush(PackedPipelineState &packedState);
|
||||
};
|
||||
|
||||
class ColorBlendState : dirty::ManualDirty {
|
||||
class ColorBlendState : dirty::RefreshableManualDirty {
|
||||
public:
|
||||
struct EngineRegisters {
|
||||
const engine::LogicOp &logicOp;
|
||||
@ -227,11 +227,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
private:
|
||||
dirty::BoundSubresource<EngineRegisters> engine;
|
||||
std::bitset<engine::ColorTargetCount> enabledRts{};
|
||||
|
||||
public:
|
||||
ColorBlendState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
||||
|
||||
void Flush(PackedPipelineState &packedState);
|
||||
|
||||
bool Refresh(PackedPipelineState &packedState);
|
||||
};
|
||||
|
||||
class TransformFeedbackState : dirty::ManualDirty {
|
||||
|
Loading…
Reference in New Issue
Block a user