From 7259f7a733a3542af6381f6e145edbad491ecfb0 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 21 May 2019 19:11:06 -0300 Subject: [PATCH 1/5] rasterizer_opengl: Remove OpenGL core profile --- src/core/settings.cpp | 1 - src/core/settings.h | 1 - src/yuzu/bootmanager.cpp | 8 ++------ src/yuzu/configuration/config.cpp | 4 ---- src/yuzu/configuration/configure_graphics.cpp | 3 --- src/yuzu/configuration/configure_graphics.ui | 7 ------- src/yuzu_cmd/config.cpp | 2 -- src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | 6 +----- 8 files changed, 3 insertions(+), 29 deletions(-) diff --git a/src/core/settings.cpp b/src/core/settings.cpp index c1365879b3..6d32ebea37 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -90,7 +90,6 @@ void LogSettings() { LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); - LogSetting("Renderer_UseCompatibilityProfile", Settings::values.use_compatibility_profile); LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); LogSetting("Renderer_UseAccurateGpuEmulation", Settings::values.use_accurate_gpu_emulation); LogSetting("Renderer_UseAsynchronousGpuEmulation", diff --git a/src/core/settings.h b/src/core/settings.h index 5ff3634aa6..b843907453 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -390,7 +390,6 @@ struct Values { float resolution_factor; bool use_frame_limit; u16 frame_limit; - bool use_compatibility_profile; bool use_disk_shader_cache; bool use_accurate_gpu_emulation; bool use_asynchronous_gpu_emulation; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 9e420b3591..5243fe820e 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -379,12 +379,8 @@ void GRenderWindow::InitRenderTarget() { // WA_DontShowOnScreen, WA_DeleteOnClose QSurfaceFormat fmt; fmt.setVersion(4, 3); - if (Settings::values.use_compatibility_profile) { - fmt.setProfile(QSurfaceFormat::CompatibilityProfile); - fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions); - } else { - fmt.setProfile(QSurfaceFormat::CoreProfile); - } + fmt.setProfile(QSurfaceFormat::CompatibilityProfile); + fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions); // TODO: expose a setting for buffer value (ie default/single/double/triple) fmt.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); shared_context = std::make_unique(); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index db27da23e3..02a213e58d 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -531,8 +531,6 @@ void Config::ReadRendererValues() { Settings::values.use_frame_limit = ReadSetting(QStringLiteral("use_frame_limit"), true).toBool(); Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt(); - Settings::values.use_compatibility_profile = - ReadSetting(QStringLiteral("use_compatibility_profile"), true).toBool(); Settings::values.use_disk_shader_cache = ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool(); Settings::values.use_accurate_gpu_emulation = @@ -912,8 +910,6 @@ void Config::SaveRendererValues() { static_cast(Settings::values.resolution_factor), 1.0); WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); - WriteSetting(QStringLiteral("use_compatibility_profile"), - Settings::values.use_compatibility_profile, true); WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache, true); WriteSetting(QStringLiteral("use_accurate_gpu_emulation"), diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 08ea41b0ff..c01281ee11 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -75,8 +75,6 @@ void ConfigureGraphics::setConfiguration() { static_cast(FromResolutionFactor(Settings::values.resolution_factor))); ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); ui->frame_limit->setValue(Settings::values.frame_limit); - ui->use_compatibility_profile->setEnabled(runtime_lock); - ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile); ui->use_disk_shader_cache->setEnabled(runtime_lock); ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache); ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation); @@ -93,7 +91,6 @@ void ConfigureGraphics::applyConfiguration() { ToResolutionFactor(static_cast(ui->resolution_factor_combobox->currentIndex())); Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); Settings::values.frame_limit = ui->frame_limit->value(); - Settings::values.use_compatibility_profile = ui->use_compatibility_profile->isChecked(); Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked(); Settings::values.use_accurate_gpu_emulation = ui->use_accurate_gpu_emulation->isChecked(); Settings::values.use_asynchronous_gpu_emulation = diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 0f6f6c0033..15ab18ecd0 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui @@ -49,13 +49,6 @@ - - - - Use OpenGL compatibility profile - - - diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 7309564275..f3817bb874 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -349,8 +349,6 @@ void Config::ReadValues() { Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); Settings::values.frame_limit = static_cast(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); - Settings::values.use_compatibility_profile = - sdl2_config->GetBoolean("Renderer", "use_compatibility_profile", true); Settings::values.use_disk_shader_cache = sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); Settings::values.use_accurate_gpu_emulation = diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 904022137a..e2d3df1802 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -74,13 +74,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { } EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen) : EmuWindow_SDL2(fullscreen) { - const SDL_GLprofile profile = Settings::values.use_compatibility_profile - ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY - : SDL_GL_CONTEXT_PROFILE_CORE; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); From df509486c48dd1da9e9e69d9e94a065e0fffbd20 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 21 May 2019 19:21:57 -0300 Subject: [PATCH 2/5] gl_rasterizer: Use GL_QUADS to emulate quads rendering --- src/video_core/CMakeLists.txt | 2 - .../gl_primitive_assembler.cpp | 63 ------------------- .../renderer_opengl/gl_primitive_assembler.h | 31 --------- .../renderer_opengl/gl_rasterizer.cpp | 37 +---------- .../renderer_opengl/gl_rasterizer.h | 2 - .../renderer_opengl/maxwell_to_gl.h | 2 + 6 files changed, 5 insertions(+), 132 deletions(-) delete mode 100644 src/video_core/renderer_opengl/gl_primitive_assembler.cpp delete mode 100644 src/video_core/renderer_opengl/gl_primitive_assembler.h diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 1e010e4da6..0b9b6edee9 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -42,8 +42,6 @@ add_library(video_core STATIC renderer_opengl/gl_device.h renderer_opengl/gl_global_cache.cpp renderer_opengl/gl_global_cache.h - renderer_opengl/gl_primitive_assembler.cpp - renderer_opengl/gl_primitive_assembler.h renderer_opengl/gl_rasterizer.cpp renderer_opengl/gl_rasterizer.h renderer_opengl/gl_rasterizer_cache.cpp diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp deleted file mode 100644 index c3e94d9177..0000000000 --- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2018 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include -#include -#include "common/assert.h" -#include "common/common_types.h" -#include "core/core.h" -#include "video_core/memory_manager.h" -#include "video_core/renderer_opengl/gl_buffer_cache.h" -#include "video_core/renderer_opengl/gl_primitive_assembler.h" - -namespace OpenGL { - -constexpr u32 TRIANGLES_PER_QUAD = 6; -constexpr std::array QUAD_MAP = {0, 1, 2, 0, 2, 3}; - -PrimitiveAssembler::PrimitiveAssembler(OGLBufferCache& buffer_cache) : buffer_cache(buffer_cache) {} - -PrimitiveAssembler::~PrimitiveAssembler() = default; - -std::size_t PrimitiveAssembler::CalculateQuadSize(u32 count) const { - ASSERT_MSG(count % 4 == 0, "Quad count is expected to be a multiple of 4"); - return (count / 4) * TRIANGLES_PER_QUAD * sizeof(GLuint); -} - -GLintptr PrimitiveAssembler::MakeQuadArray(u32 first, u32 count) { - const std::size_t size{CalculateQuadSize(count)}; - auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(size); - - for (u32 primitive = 0; primitive < count / 4; ++primitive) { - for (u32 i = 0; i < TRIANGLES_PER_QUAD; ++i) { - const u32 index = first + primitive * 4 + QUAD_MAP[i]; - std::memcpy(dst_pointer, &index, sizeof(index)); - dst_pointer += sizeof(index); - } - } - - return index_offset; -} - -GLintptr PrimitiveAssembler::MakeQuadIndexed(GPUVAddr gpu_addr, std::size_t index_size, u32 count) { - const std::size_t map_size{CalculateQuadSize(count)}; - auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size); - - auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); - const u8* source{memory_manager.GetPointer(gpu_addr)}; - - for (u32 primitive = 0; primitive < count / 4; ++primitive) { - for (std::size_t i = 0; i < TRIANGLES_PER_QUAD; ++i) { - const u32 index = primitive * 4 + QUAD_MAP[i]; - const u8* src_offset = source + (index * index_size); - - std::memcpy(dst_pointer, src_offset, index_size); - dst_pointer += index_size; - } - } - - return index_offset; -} - -} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.h b/src/video_core/renderer_opengl/gl_primitive_assembler.h deleted file mode 100644 index 4e87ce4d6a..0000000000 --- a/src/video_core/renderer_opengl/gl_primitive_assembler.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include - -#include "common/common_types.h" - -namespace OpenGL { - -class OGLBufferCache; - -class PrimitiveAssembler { -public: - explicit PrimitiveAssembler(OGLBufferCache& buffer_cache); - ~PrimitiveAssembler(); - - /// Calculates the size required by MakeQuadArray and MakeQuadIndexed. - std::size_t CalculateQuadSize(u32 count) const; - - GLintptr MakeQuadArray(u32 first, u32 count); - - GLintptr MakeQuadIndexed(GPUVAddr gpu_addr, std::size_t index_size, u32 count); - -private: - OGLBufferCache& buffer_cache; -}; - -} // namespace OpenGL \ No newline at end of file diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f9b6dfeea4..5087d94063 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -246,29 +246,6 @@ DrawParameters RasterizerOpenGL::SetupDraw() { DrawParameters params{}; params.current_instance = gpu.state.current_instance; - if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) { - MICROPROFILE_SCOPE(OpenGL_PrimitiveAssembly); - - params.use_indexed = true; - params.primitive_mode = GL_TRIANGLES; - - if (is_indexed) { - params.index_format = MaxwellToGL::IndexFormat(regs.index_array.format); - params.count = (regs.index_array.count / 4) * 6; - params.index_buffer_offset = primitive_assembler.MakeQuadIndexed( - regs.index_array.IndexStart(), regs.index_array.FormatSizeInBytes(), - regs.index_array.count); - params.base_vertex = static_cast(regs.vb_element_base); - } else { - // MakeQuadArray always generates u32 indexes - params.index_format = GL_UNSIGNED_INT; - params.count = (regs.vertex_buffer.count / 4) * 6; - params.index_buffer_offset = primitive_assembler.MakeQuadArray( - regs.vertex_buffer.first, regs.vertex_buffer.count); - } - return params; - } - params.use_indexed = is_indexed; params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); @@ -699,17 +676,9 @@ void RasterizerOpenGL::DrawArrays() { std::size_t buffer_size = CalculateVertexArraysSize(); - // Add space for index buffer (keeping in mind non-core primitives) - switch (regs.draw.topology) { - case Maxwell::PrimitiveTopology::Quads: - buffer_size = Common::AlignUp(buffer_size, 4) + - primitive_assembler.CalculateQuadSize(regs.vertex_buffer.count); - break; - default: - if (is_indexed) { - buffer_size = Common::AlignUp(buffer_size, 4) + CalculateIndexBufferSize(); - } - break; + // Add space for index buffer + if (is_indexed) { + buffer_size = Common::AlignUp(buffer_size, 4) + CalculateIndexBufferSize(); } // Uniform space for the 5 shader stages diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index d78094138c..f2643f26f8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -23,7 +23,6 @@ #include "video_core/renderer_opengl/gl_buffer_cache.h" #include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_global_cache.h" -#include "video_core/renderer_opengl/gl_primitive_assembler.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_sampler_cache.h" @@ -197,7 +196,6 @@ private: static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; OGLBufferCache buffer_cache; - PrimitiveAssembler primitive_assembler{buffer_cache}; BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index ed7b5cff0f..e3cabded30 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -128,6 +128,8 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) { return GL_TRIANGLE_STRIP; case Maxwell::PrimitiveTopology::TriangleFan: return GL_TRIANGLE_FAN; + case Maxwell::PrimitiveTopology::Quads: + return GL_QUADS; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast(topology)); UNREACHABLE(); From b76df62c00c28244f2fdd657b809853907f0070f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 21 May 2019 20:28:09 -0300 Subject: [PATCH 3/5] gl_rasterizer: Move alpha testing to the OpenGL pipeline Removes the alpha testing code from each fragment shader invocation. --- .../renderer_opengl/gl_rasterizer.cpp | 14 ++++++---- .../renderer_opengl/gl_rasterizer.h | 4 +-- .../renderer_opengl/gl_shader_decompiler.cpp | 20 +------------- .../renderer_opengl/gl_shader_gen.cpp | 27 ------------------- .../renderer_opengl/gl_shader_manager.cpp | 11 -------- .../renderer_opengl/gl_shader_manager.h | 8 +----- src/video_core/renderer_opengl/gl_state.cpp | 13 +++++++++ src/video_core/renderer_opengl/gl_state.h | 7 +++++ 8 files changed, 33 insertions(+), 71 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 5087d94063..ca410287a8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -663,13 +663,10 @@ void RasterizerOpenGL::DrawArrays() { SyncCullMode(); SyncPrimitiveRestart(); SyncScissorTest(state); - // Alpha Testing is synced on shaders. SyncTransformFeedback(); SyncPointState(); - CheckAlphaTests(); SyncPolygonOffset(); - // TODO(bunnei): Sync framebuffer_scale uniform here - // TODO(bunnei): Sync scissorbox uniform(s) here + SyncAlphaTest(); // Draw the vertex batch const bool is_indexed = accelerate_draw == AccelDraw::Indexed; @@ -1121,10 +1118,17 @@ void RasterizerOpenGL::SyncPolygonOffset() { state.polygon_offset.clamp = regs.polygon_offset_clamp; } -void RasterizerOpenGL::CheckAlphaTests() { +void RasterizerOpenGL::SyncAlphaTest() { const auto& regs = system.GPU().Maxwell3D().regs; UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1, "Alpha Testing is enabled with more than one rendertarget"); + + state.alpha_test.enabled = regs.alpha_test_enabled; + if (!state.alpha_test.enabled) { + return; + } + state.alpha_test.func = MaxwellToGL::ComparisonOp(regs.alpha_test_func); + state.alpha_test.ref = regs.alpha_test_ref; } } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index f2643f26f8..2817f65c96 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -166,8 +166,8 @@ private: /// Syncs the polygon offsets void SyncPolygonOffset(); - /// Check asserts for alpha testing. - void CheckAlphaTests(); + /// Syncs the alpha test state to match the guest state + void SyncAlphaTest(); /// Check for extension that are not strictly required /// but are needed for correct emulation diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e9f8d40dbb..ab75bb795e 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1447,27 +1447,9 @@ private: UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Sample mask write is unimplemented"); - code.AddLine("if (alpha_test[0] != 0) {{"); - ++code.scope; - // We start on the register containing the alpha value in the first RT. - u32 current_reg = 3; - for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) { - // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when - // multiple render targets are used. - if (header.ps.IsColorComponentOutputEnabled(render_target, 0) || - header.ps.IsColorComponentOutputEnabled(render_target, 1) || - header.ps.IsColorComponentOutputEnabled(render_target, 2) || - header.ps.IsColorComponentOutputEnabled(render_target, 3)) { - code.AddLine("if (!AlphaFunc({})) discard;", SafeGetRegister(current_reg)); - current_reg += 4; - } - } - --code.scope; - code.AddLine("}}"); - // Write the color outputs using the data in the shader registers, disabled // rendertargets/components are skipped in the register assignment. - current_reg = 0; + u32 current_reg = 0; for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) { // TODO(Subv): Figure out how dual-source blending is configured in the Switch. for (u32 component = 0; component < 4; ++component) { diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index d2bb705a9f..269dda1222 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -28,7 +28,6 @@ layout (location = 0) out vec4 position; layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config { vec4 viewport_flip; uvec4 config_pack; // instance_id, flip_stage, y_direction, padding - uvec4 alpha_test; }; )"; @@ -91,7 +90,6 @@ layout (location = 0) out vec4 position; layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config { vec4 viewport_flip; uvec4 config_pack; // instance_id, flip_stage, y_direction, padding - uvec4 alpha_test; }; )"; @@ -129,33 +127,8 @@ layout (location = 0) in noperspective vec4 position; layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config { vec4 viewport_flip; uvec4 config_pack; // instance_id, flip_stage, y_direction, padding - uvec4 alpha_test; }; -bool AlphaFunc(in float value) { - float ref = uintBitsToFloat(alpha_test[2]); - switch (alpha_test[1]) { - case 1: - return false; - case 2: - return value < ref; - case 3: - return value == ref; - case 4: - return value <= ref; - case 5: - return value > ref; - case 6: - return value != ref; - case 7: - return value >= ref; - case 8: - return true; - default: - return false; - } -} - )"; const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); ProgramResult program = diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 05ab01dcbc..b05f90f20d 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -48,17 +48,6 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shade viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; - auto func{static_cast(regs.alpha_test_func)}; - // Normalize the gl variants of opCompare to be the same as the normal variants - const u32 op_gl_variant_base = static_cast(Maxwell3D::Regs::ComparisonOp::Never); - if (func >= op_gl_variant_base) { - func = func - op_gl_variant_base + 1U; - } - - alpha_test.enabled = regs.alpha_test_enabled; - alpha_test.func = func; - alpha_test.ref = regs.alpha_test_ref; - instance_id = state.current_instance; // Assign in which stage the position has to be flipped diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index cec18a8321..6961e702a2 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -27,14 +27,8 @@ struct MaxwellUniformData { GLuint flip_stage; GLfloat y_direction; }; - struct alignas(16) { - GLuint enabled; - GLuint func; - GLfloat ref; - GLuint padding; - } alpha_test; }; -static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); +static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect"); static_assert(sizeof(MaxwellUniformData) < 16384, "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 7425fbe5dd..d86e137ac1 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -156,6 +156,10 @@ OpenGLState::OpenGLState() { polygon_offset.factor = 0.0f; polygon_offset.units = 0.0f; polygon_offset.clamp = 0.0f; + + alpha_test.enabled = false; + alpha_test.func = GL_ALWAYS; + alpha_test.ref = 0.0f; } void OpenGLState::ApplyDefaultState() { @@ -461,6 +465,14 @@ void OpenGLState::ApplyPolygonOffset() const { } } +void OpenGLState::ApplyAlphaTest() const { + Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled); + if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref), + std::tie(alpha_test.func, alpha_test.ref))) { + glAlphaFunc(alpha_test.func, alpha_test.ref); + } +} + void OpenGLState::ApplyTextures() const { bool has_delta{}; std::size_t first{}; @@ -533,6 +545,7 @@ void OpenGLState::Apply() const { ApplyTextures(); ApplySamplers(); ApplyPolygonOffset(); + ApplyAlphaTest(); } void OpenGLState::EmulateViewportWithScissor() { diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 41418a7b84..b0140495df 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -172,6 +172,12 @@ public: GLfloat clamp; } polygon_offset; + struct { + bool enabled; // GL_ALPHA_TEST + GLenum func; // GL_ALPHA_TEST_FUNC + GLfloat ref; // GL_ALPHA_TEST_REF + } alpha_test; + std::array clip_distance; // GL_CLIP_DISTANCE OpenGLState(); @@ -215,6 +221,7 @@ public: void ApplySamplers() const; void ApplyDepthClamp() const; void ApplyPolygonOffset() const; + void ApplyAlphaTest() const; /// Set the initial OpenGL state static void ApplyDefaultState(); From a89cc0bafc2b56aa7b29d34ed460911478fd9efa Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 21 May 2019 20:29:41 -0300 Subject: [PATCH 4/5] maxwell_to_gl: Use GL_CLAMP to emulate Clamp wrap mode --- src/video_core/renderer_opengl/maxwell_to_gl.h | 7 ++----- src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 2 +- src/video_core/textures/texture.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index e3cabded30..ea77dd211f 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -175,11 +175,8 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { return GL_CLAMP_TO_EDGE; case Tegra::Texture::WrapMode::Border: return GL_CLAMP_TO_BORDER; - case Tegra::Texture::WrapMode::ClampOGL: - // TODO(Subv): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use - // GL_CLAMP_TO_BORDER to get the border color of the texture, and then sample the edge to - // manually mix them. However the shader part of this is not yet implemented. - return GL_CLAMP_TO_BORDER; + case Tegra::Texture::WrapMode::Clamp: + return GL_CLAMP; case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: return GL_MIRROR_CLAMP_TO_EDGE; case Tegra::Texture::WrapMode::MirrorOnceBorder: diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 9fe1e3280c..0bbbf68510 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -52,7 +52,7 @@ vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) { return vk::SamplerAddressMode::eClampToEdge; case Tegra::Texture::WrapMode::Border: return vk::SamplerAddressMode::eClampToBorder; - case Tegra::Texture::WrapMode::ClampOGL: + case Tegra::Texture::WrapMode::Clamp: // TODO(Rodrigo): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use // eClampToBorder to get the border color of the texture, and then sample the edge to // manually mix them. However the shader part of this is not yet implemented. diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index bea0d5bc29..219bfd5598 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -251,7 +251,7 @@ enum class WrapMode : u32 { Mirror = 1, ClampToEdge = 2, Border = 3, - ClampOGL = 4, + Clamp = 4, MirrorOnceClampToEdge = 5, MirrorOnceBorder = 6, MirrorOnceClampOGL = 7, From 6ac44907516a0fd4973a80b793b336c4cef2377a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 27 May 2019 20:51:41 -0300 Subject: [PATCH 5/5] gl_buffer_cache: Remove unused ReserveMemory method --- src/video_core/renderer_opengl/gl_buffer_cache.cpp | 10 ---------- src/video_core/renderer_opengl/gl_buffer_cache.h | 3 --- 2 files changed, 13 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index 25652e7947..48b86f3bdd 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -71,16 +71,6 @@ GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t s return uploaded_offset; } -std::tuple OGLBufferCache::ReserveMemory(std::size_t size, std::size_t alignment) { - AlignBuffer(alignment); - u8* const uploaded_ptr = buffer_ptr; - const GLintptr uploaded_offset = buffer_offset; - - buffer_ptr += size; - buffer_offset += size; - return std::make_tuple(uploaded_ptr, uploaded_offset); -} - bool OGLBufferCache::Map(std::size_t max_size) { bool invalidate; std::tie(buffer_ptr, buffer_offset_base, invalidate) = diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index f9247a40e4..f2347581b5 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -61,9 +61,6 @@ public: /// Uploads from a host memory. Returns host's buffer offset where it's been allocated. GLintptr UploadHostMemory(const void* raw_pointer, std::size_t size, std::size_t alignment = 4); - /// Reserves memory to be used by host's CPU. Returns mapped address and offset. - std::tuple ReserveMemory(std::size_t size, std::size_t alignment = 4); - bool Map(std::size_t max_size); void Unmap();