Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b55aa4f48 | ||
|
|
393cc3ef2f | ||
|
|
b8b1747704 | ||
|
|
193bfefce4 | ||
|
|
6b997c8f7f | ||
|
|
e60d281a01 | ||
|
|
78574746bd | ||
|
|
5f309b88db |
No files matched your search
+6
-10
@@ -28,18 +28,14 @@ __declspec(noinline, noreturn)
|
||||
}
|
||||
|
||||
#define ASSERT(_a_) \
|
||||
do \
|
||||
if (!(_a_)) { \
|
||||
assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
|
||||
} \
|
||||
while (0)
|
||||
if (!(_a_)) { \
|
||||
LOG_CRITICAL(Debug, "Assertion Failed!"); \
|
||||
}
|
||||
|
||||
#define ASSERT_MSG(_a_, ...) \
|
||||
do \
|
||||
if (!(_a_)) { \
|
||||
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
|
||||
} \
|
||||
while (0)
|
||||
if (!(_a_)) { \
|
||||
LOG_CRITICAL(Debug, "Assertion Failed! " __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!")
|
||||
#define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__)
|
||||
|
||||
@@ -89,6 +89,9 @@ void Maxwell3D::InitializeRegisterDefaults() {
|
||||
|
||||
// Commercial games seem to assume this value is enabled and nouveau sets this value manually.
|
||||
regs.rt_separate_frag_data = 1;
|
||||
|
||||
// Some games (like Super Mario Odyssey) assume that SRGB is enabled.
|
||||
regs.framebuffer_srgb = 1;
|
||||
}
|
||||
|
||||
#define DIRTY_REGS_POS(field_name) (offsetof(Maxwell3D::DirtyRegs, field_name))
|
||||
@@ -329,6 +332,10 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
|
||||
ProcessMacroBind(method_call.argument);
|
||||
break;
|
||||
}
|
||||
case MAXWELL3D_REG_INDEX(firmware[4]): {
|
||||
ProcessFirmwareCall4();
|
||||
break;
|
||||
}
|
||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
|
||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
|
||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
|
||||
@@ -419,6 +426,14 @@ void Maxwell3D::ProcessMacroBind(u32 data) {
|
||||
macro_positions[regs.macros.entry++] = data;
|
||||
}
|
||||
|
||||
void Maxwell3D::ProcessFirmwareCall4() {
|
||||
LOG_WARNING(HW_GPU, "(STUBBED) called");
|
||||
|
||||
// Firmware call 4 is a blob that changes some registers depending on its parameters.
|
||||
// These registers don't affect emulation and so are stubbed by setting 0xd00 to 1.
|
||||
regs.reg_array[0xd00] = 1;
|
||||
}
|
||||
|
||||
void Maxwell3D::ProcessQueryGet() {
|
||||
const GPUVAddr sequence_address{regs.query.QueryAddress()};
|
||||
// Since the sequence address is given as a GPU VAddr, we have to convert it to an application
|
||||
|
||||
@@ -1089,7 +1089,9 @@ public:
|
||||
INSERT_PADDING_WORDS(14);
|
||||
} shader_config[MaxShaderProgram];
|
||||
|
||||
INSERT_PADDING_WORDS(0x80);
|
||||
INSERT_PADDING_WORDS(0x60);
|
||||
|
||||
u32 firmware[0x20];
|
||||
|
||||
struct {
|
||||
u32 cb_size;
|
||||
@@ -1319,6 +1321,9 @@ private:
|
||||
/// Handles writes to the macro bind register.
|
||||
void ProcessMacroBind(u32 data);
|
||||
|
||||
/// Handles firmware blob 4
|
||||
void ProcessFirmwareCall4();
|
||||
|
||||
/// Handles a write to the CLEAR_BUFFERS register.
|
||||
void ProcessClearBuffers();
|
||||
|
||||
@@ -1431,6 +1436,7 @@ ASSERT_REG_POSITION(vertex_array[0], 0x700);
|
||||
ASSERT_REG_POSITION(independent_blend, 0x780);
|
||||
ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0);
|
||||
ASSERT_REG_POSITION(shader_config[0], 0x800);
|
||||
ASSERT_REG_POSITION(firmware, 0x8C0);
|
||||
ASSERT_REG_POSITION(const_buffer, 0x8E0);
|
||||
ASSERT_REG_POSITION(cb_bind[0], 0x904);
|
||||
ASSERT_REG_POSITION(tex_cb_index, 0x982);
|
||||
|
||||
@@ -131,9 +131,7 @@ bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) {
|
||||
|
||||
// An instruction with the Exit flag will not actually
|
||||
// cause an exit if it's executed inside a delay slot.
|
||||
// TODO(Blinkhawk): Reversed to always exit. The behavior explained above requires further
|
||||
// testing on the MME code.
|
||||
if (opcode.is_exit) {
|
||||
if (opcode.is_exit && !is_delay_slot) {
|
||||
// Exit has a delay slot, execute the next instruction
|
||||
Step(offset, true);
|
||||
return false;
|
||||
|
||||
@@ -489,9 +489,6 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
||||
// Assume that a surface will be written to if it is used as a framebuffer, even if
|
||||
// the shader doesn't actually write to it.
|
||||
texture_cache.MarkColorBufferInUse(*single_color_target);
|
||||
// Workaround for and issue in nvidia drivers
|
||||
// https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/
|
||||
state.framebuffer_srgb.enabled |= color_surface->GetSurfaceParams().srgb_conversion;
|
||||
}
|
||||
|
||||
fbkey.is_single_buffer = true;
|
||||
@@ -512,11 +509,6 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
||||
// Assume that a surface will be written to if it is used as a framebuffer, even
|
||||
// if the shader doesn't actually write to it.
|
||||
texture_cache.MarkColorBufferInUse(index);
|
||||
// Enable sRGB only for supported formats
|
||||
// Workaround for and issue in nvidia drivers
|
||||
// https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/
|
||||
state.framebuffer_srgb.enabled |=
|
||||
color_surface->GetSurfaceParams().srgb_conversion;
|
||||
}
|
||||
|
||||
fbkey.color_attachments[index] =
|
||||
@@ -906,6 +898,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
|
||||
}
|
||||
|
||||
screen_info.display_texture = surface->GetTexture();
|
||||
screen_info.display_srgb = surface->GetSurfaceParams().srgb_conversion;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace OpenGL {
|
||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
|
||||
OpenGLState OpenGLState::cur_state;
|
||||
bool OpenGLState::s_rgb_used;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -282,8 +281,6 @@ void OpenGLState::ApplySRgb() const {
|
||||
return;
|
||||
cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled;
|
||||
if (framebuffer_srgb.enabled) {
|
||||
// Track if sRGB is used
|
||||
s_rgb_used = true;
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
} else {
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
@@ -175,14 +175,6 @@ public:
|
||||
return cur_state;
|
||||
}
|
||||
|
||||
static bool GetsRGBUsed() {
|
||||
return s_rgb_used;
|
||||
}
|
||||
|
||||
static void ClearsRGBUsed() {
|
||||
s_rgb_used = false;
|
||||
}
|
||||
|
||||
void SetDefaultViewports();
|
||||
/// Apply this state as the current OpenGL state
|
||||
void Apply();
|
||||
@@ -253,8 +245,6 @@ public:
|
||||
private:
|
||||
static OpenGLState cur_state;
|
||||
|
||||
// Workaround for sRGB problems caused by QT not supporting srgb output
|
||||
static bool s_rgb_used;
|
||||
struct {
|
||||
bool blend_state;
|
||||
bool stencil_state;
|
||||
|
||||
@@ -264,7 +264,6 @@ void RendererOpenGL::CreateRasterizer() {
|
||||
if (rasterizer) {
|
||||
return;
|
||||
}
|
||||
OpenGLState::ClearsRGBUsed();
|
||||
rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info);
|
||||
}
|
||||
|
||||
@@ -343,9 +342,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
|
||||
}};
|
||||
|
||||
state.textures[0] = screen_info.display_texture;
|
||||
// Workaround brigthness problems in SMO by enabling sRGB in the final output
|
||||
// if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
|
||||
state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
|
||||
state.framebuffer_srgb.enabled = screen_info.display_srgb;
|
||||
state.AllDirty();
|
||||
state.Apply();
|
||||
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data());
|
||||
@@ -355,8 +352,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
|
||||
state.textures[0] = 0;
|
||||
state.AllDirty();
|
||||
state.Apply();
|
||||
// Clear sRGB state for the next frame
|
||||
OpenGLState::ClearsRGBUsed();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,8 +401,8 @@ void RendererOpenGL::CaptureScreenshot() {
|
||||
GLuint renderbuffer;
|
||||
glGenRenderbuffers(1, &renderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, state.GetsRGBUsed() ? GL_SRGB8 : GL_RGB8, layout.width,
|
||||
layout.height);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, screen_info.display_srgb ? GL_SRGB8 : GL_RGB8,
|
||||
layout.width, layout.height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
|
||||
|
||||
DrawScreen(layout);
|
||||
|
||||
@@ -38,7 +38,8 @@ struct TextureInfo {
|
||||
|
||||
/// Structure used for storing information about the display target for the Switch screen
|
||||
struct ScreenInfo {
|
||||
GLuint display_texture;
|
||||
GLuint display_texture{};
|
||||
bool display_srgb{};
|
||||
const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
|
||||
TextureInfo texture;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user