dolphin/Source/Core/VideoCommon/BoundingBox.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

67 lines
1.9 KiB
C
Raw Normal View History

// Copyright 2014 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <memory>
#include <span>
#include <vector>
#include "Common/CommonTypes.h"
class PixelShaderManager;
class PointerWrap;
using BBoxType = s32;
constexpr u32 NUM_BBOX_VALUES = 4;
class BoundingBox
{
public:
explicit BoundingBox() = default;
virtual ~BoundingBox() = default;
bool IsEnabled() const { return m_is_active; }
void Enable(PixelShaderManager& pixel_shader_manager);
void Disable(PixelShaderManager& pixel_shader_manager);
void Flush();
u16 Get(u32 index);
void Set(u32 index, u16 value);
void DoState(PointerWrap& p);
// Initialize, Read, and Write are only safe to call if the backend supports bounding box,
// otherwise unexpected exceptions can occur
virtual bool Initialize() = 0;
protected:
virtual std::vector<BBoxType> Read(u32 index, u32 length) = 0;
virtual void Write(u32 index, std::span<const BBoxType> values) = 0;
private:
void Readback();
bool m_is_active = false;
std::array<BBoxType, NUM_BBOX_VALUES> m_values = {};
std::array<bool, NUM_BBOX_VALUES> m_dirty = {};
bool m_is_valid = true;
// Nintendo's SDK seems to write "default" bounding box values before every draw (1023 0 1023 0
// are the only values encountered so far, which happen to be the extents allowed by the BP
// registers) to reset the registers for comparison in the pixel engine, and presumably to detect
// whether GX has updated the registers with real values.
//
// We can store these values when Bounding Box emulation is disabled and return them on read,
// which the game will interpret as "no pixels have been drawn"
//
// This produces much better results than just returning garbage, which can cause games like
// Ultimate Spider-Man to crash
std::array<u16, 4> m_bounding_box_fallback = {};
};
extern std::unique_ptr<BoundingBox> g_bounding_box;