Merge pull request #2514 from ReinUsesLisp/opengl-compat
video_core: Drop OpenGL core in favor of OpenGL compatibility
This commit is contained in:
		
						commit
						de33ad25f5
					
				@ -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",
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -71,16 +71,6 @@ GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t s
 | 
			
		||||
    return uploaded_offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::tuple<u8*, GLintptr> 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) =
 | 
			
		||||
 | 
			
		||||
@ -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<u8*, GLintptr> ReserveMemory(std::size_t size, std::size_t alignment = 4);
 | 
			
		||||
 | 
			
		||||
    bool Map(std::size_t max_size);
 | 
			
		||||
    void Unmap();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,63 +0,0 @@
 | 
			
		||||
// Copyright 2018 yuzu Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <array>
 | 
			
		||||
#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<u32, TRIANGLES_PER_QUAD> 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
 | 
			
		||||
@ -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 <glad/glad.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@ -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<GLint>(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);
 | 
			
		||||
 | 
			
		||||
@ -686,30 +663,19 @@ 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;
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
@ -1152,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
 | 
			
		||||
 | 
			
		||||
@ -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"
 | 
			
		||||
@ -167,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
 | 
			
		||||
@ -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};
 | 
			
		||||
 | 
			
		||||
@ -1467,27 +1467,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) {
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,6 @@ ProgramResult GenerateVertexShader(const Device& device, const ShaderSetup& setu
 | 
			
		||||
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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
)";
 | 
			
		||||
@ -78,7 +77,6 @@ ProgramResult GenerateGeometryShader(const Device& device, const ShaderSetup& se
 | 
			
		||||
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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
)";
 | 
			
		||||
@ -114,33 +112,8 @@ layout (location = 7) out vec4 FragColor7;
 | 
			
		||||
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 =
 | 
			
		||||
 | 
			
		||||
@ -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<u32>(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<u32>(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
 | 
			
		||||
 | 
			
		||||
@ -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");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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() {
 | 
			
		||||
 | 
			
		||||
@ -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<bool, 8> 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();
 | 
			
		||||
 | 
			
		||||
@ -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<u32>(topology));
 | 
			
		||||
        UNREACHABLE();
 | 
			
		||||
@ -173,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:
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -251,7 +251,7 @@ enum class WrapMode : u32 {
 | 
			
		||||
    Mirror = 1,
 | 
			
		||||
    ClampToEdge = 2,
 | 
			
		||||
    Border = 3,
 | 
			
		||||
    ClampOGL = 4,
 | 
			
		||||
    Clamp = 4,
 | 
			
		||||
    MirrorOnceClampToEdge = 5,
 | 
			
		||||
    MirrorOnceBorder = 6,
 | 
			
		||||
    MirrorOnceClampOGL = 7,
 | 
			
		||||
 | 
			
		||||
@ -381,12 +381,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<QOpenGLContext>();
 | 
			
		||||
 | 
			
		||||
@ -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 =
 | 
			
		||||
@ -914,8 +912,6 @@ void Config::SaveRendererValues() {
 | 
			
		||||
                 static_cast<double>(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"),
 | 
			
		||||
 | 
			
		||||
@ -75,8 +75,6 @@ void ConfigureGraphics::SetConfiguration() {
 | 
			
		||||
    ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
 | 
			
		||||
    ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked());
 | 
			
		||||
    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<Resolution>(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 =
 | 
			
		||||
 | 
			
		||||
@ -49,13 +49,6 @@
 | 
			
		||||
          </item>
 | 
			
		||||
         </layout>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
         <widget class="QCheckBox" name="use_compatibility_profile">
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>Use OpenGL compatibility profile</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </widget>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
         <widget class="QCheckBox" name="use_disk_shader_cache">
 | 
			
		||||
          <property name="text">
 | 
			
		||||
 | 
			
		||||
@ -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<u16>(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 =
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user