Miscallenious fixes to gl backend and qt frontend (#6834)
* renderer_gl: Make rasterizer normal class member * It doesn't need to be heap allocated anymore * gl_rasterizer: Remove default_texture * It's unused * gl_rasterizer: General cleanup * gl_rasterizer: Lower case lambdas * Match style with review comments from vulkan backend * rasterizer_cache: Prevent memory leak * Since the switch from shared_ptr these surfaces were no longer being destroyed properly. Use our garbage collector for that purpose to destroy it safely for both backends * rasterizer_cache: Make temp copy of old surface * The custom surface would override the memory region of the old region resulting in garbage data, this ensures the custom surface is constructed correctly * citra_qt: Manually create dialog tabs * Allows for custom constructors which is very useful. While at it, global state is now eliminated from configuration * citra_qt: Eliminate global system usage * core: Remove global system usage in memory and HIO * citra_qt: Use qOverload * tests: Run clang format * gl_texture_runtime: Fix surface scaling
This commit is contained in:
@@ -503,26 +503,27 @@ SurfaceId RasterizerCache<T>::GetTextureSurface(const Pica::Texture::TextureInfo
|
||||
const u32 min_width = info.width >> max_level;
|
||||
const u32 min_height = info.height >> max_level;
|
||||
if (min_width % 8 != 0 || min_height % 8 != 0) {
|
||||
if (min_width % 4 == 0 && min_height % 4 == 0) {
|
||||
const auto [src_surface_id, rect] = GetSurfaceSubRect(params, ScaleMatch::Ignore, true);
|
||||
Surface& src_surface = slot_surfaces[src_surface_id];
|
||||
|
||||
params.res_scale = src_surface.res_scale;
|
||||
SurfaceId tmp_surface_id = CreateSurface(params);
|
||||
Surface& tmp_surface = slot_surfaces[tmp_surface_id];
|
||||
|
||||
const TextureBlit blit = {
|
||||
.src_level = src_surface.LevelOf(params.addr),
|
||||
.dst_level = 0,
|
||||
.src_rect = rect,
|
||||
.dst_rect = tmp_surface.GetScaledRect(),
|
||||
};
|
||||
runtime.BlitTextures(src_surface, tmp_surface, blit);
|
||||
return tmp_surface_id;
|
||||
if (min_width % 4 != 0 || min_height % 4 != 0) {
|
||||
LOG_CRITICAL(HW_GPU, "Texture size ({}x{}) is not multiple of 4", min_width,
|
||||
min_height);
|
||||
return NULL_SURFACE_ID;
|
||||
}
|
||||
const auto [src_surface_id, rect] = GetSurfaceSubRect(params, ScaleMatch::Ignore, true);
|
||||
Surface& src_surface = slot_surfaces[src_surface_id];
|
||||
|
||||
LOG_CRITICAL(HW_GPU, "Texture size ({}x{}) is not multiple of 4", min_width, min_height);
|
||||
return NULL_SURFACE_ID;
|
||||
params.res_scale = src_surface.res_scale;
|
||||
SurfaceId tmp_surface_id = CreateSurface(params);
|
||||
Surface& tmp_surface = slot_surfaces[tmp_surface_id];
|
||||
sentenced.emplace_back(tmp_surface_id, frame_tick);
|
||||
|
||||
const TextureBlit blit = {
|
||||
.src_level = src_surface.LevelOf(params.addr),
|
||||
.dst_level = 0,
|
||||
.src_rect = rect,
|
||||
.dst_rect = tmp_surface.GetScaledRect(),
|
||||
};
|
||||
runtime.BlitTextures(src_surface, tmp_surface, blit);
|
||||
return tmp_surface_id;
|
||||
}
|
||||
if (info.width != (min_width << max_level) || info.height != (min_height << max_level)) {
|
||||
LOG_CRITICAL(HW_GPU, "Texture size ({}x{}) does not support required mipmap level ({})",
|
||||
@@ -1054,8 +1055,9 @@ bool RasterizerCache<T>::UploadCustomSurface(SurfaceId surface_id, SurfaceInterv
|
||||
ASSERT_MSG(True(surface.flags & SurfaceFlagBits::Custom),
|
||||
"Surface is not suitable for custom upload, aborting!");
|
||||
if (!surface.IsCustom()) {
|
||||
const SurfaceBase old_surface{surface};
|
||||
const SurfaceId old_id =
|
||||
slot_surfaces.swap_and_insert(surface_id, runtime, surface, material);
|
||||
slot_surfaces.swap_and_insert(surface_id, runtime, old_surface, material);
|
||||
sentenced.emplace_back(old_id, frame_tick);
|
||||
}
|
||||
surface.UploadCustom(material, level);
|
||||
|
@@ -105,7 +105,7 @@ SurfaceInterval SurfaceBase::GetCopyableInterval(const SurfaceParams& params) co
|
||||
return result;
|
||||
}
|
||||
|
||||
Extent SurfaceBase::RealExtent(bool scaled) {
|
||||
Extent SurfaceBase::RealExtent(bool scaled) const {
|
||||
const bool is_custom = IsCustom();
|
||||
u32 real_width = width;
|
||||
u32 real_height = height;
|
||||
|
@@ -41,7 +41,7 @@ public:
|
||||
ClearValue MakeClearValue(PAddr copy_addr, PixelFormat dst_format);
|
||||
|
||||
/// Returns the internal surface extent.
|
||||
Extent RealExtent(bool scaled = true);
|
||||
Extent RealExtent(bool scaled = true) const;
|
||||
|
||||
/// Returns true if the surface contains a custom material with a normal map.
|
||||
bool HasNormalMap() const noexcept;
|
||||
|
@@ -73,12 +73,12 @@ public:
|
||||
return height * res_scale;
|
||||
}
|
||||
|
||||
[[nodiscard]] Common::Rectangle<u32> GetRect() const noexcept {
|
||||
return {0, height, width, 0};
|
||||
[[nodiscard]] Common::Rectangle<u32> GetRect(u32 level = 0) const noexcept {
|
||||
return {0, height >> level, width >> level, 0};
|
||||
}
|
||||
|
||||
[[nodiscard]] Common::Rectangle<u32> GetScaledRect() const noexcept {
|
||||
return {0, GetScaledHeight(), GetScaledWidth(), 0};
|
||||
[[nodiscard]] Common::Rectangle<u32> GetScaledRect(u32 level = 0) const noexcept {
|
||||
return {0, GetScaledHeight() >> level, GetScaledWidth() >> level, 0};
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 PixelsInBytes(u32 size) const noexcept {
|
||||
|
@@ -9,10 +9,6 @@
|
||||
#include "common/common_types.h"
|
||||
#include "core/hw/gpu.h"
|
||||
|
||||
namespace OpenGL {
|
||||
struct ScreenInfo;
|
||||
}
|
||||
|
||||
namespace Pica::Shader {
|
||||
struct OutputVertex;
|
||||
} // namespace Pica::Shader
|
||||
@@ -76,14 +72,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Attempt to use a faster method to display the framebuffer to screen
|
||||
virtual bool AccelerateDisplay([[maybe_unused]] const GPU::Regs::FramebufferConfig& config,
|
||||
[[maybe_unused]] PAddr framebuffer_addr,
|
||||
[[maybe_unused]] u32 pixel_stride,
|
||||
[[maybe_unused]] OpenGL::ScreenInfo& screen_info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Attempt to draw using hardware shaders
|
||||
virtual bool AccelerateDrawBatch([[maybe_unused]] bool is_indexed) {
|
||||
return false;
|
||||
|
@@ -42,7 +42,7 @@ public:
|
||||
virtual ~RendererBase();
|
||||
|
||||
/// Returns the rasterizer owned by the renderer
|
||||
virtual VideoCore::RasterizerInterface* Rasterizer() const = 0;
|
||||
virtual VideoCore::RasterizerInterface* Rasterizer() = 0;
|
||||
|
||||
/// Finalize rendering the guest frame and draw into the presentation texture
|
||||
virtual void SwapBuffers() = 0;
|
||||
@@ -72,9 +72,6 @@ public:
|
||||
/// Ends the current frame
|
||||
void EndFrame();
|
||||
|
||||
// Getter/setter functions:
|
||||
// ------------------------
|
||||
|
||||
f32 GetCurrentFPS() const {
|
||||
return current_fps;
|
||||
}
|
||||
|
@@ -12,9 +12,9 @@
|
||||
#include "video_core/regs_rasterizer.h"
|
||||
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
||||
#include "video_core/renderer_opengl/gl_shader_gen.h"
|
||||
#include "video_core/renderer_opengl/gl_vars.h"
|
||||
#include "video_core/renderer_opengl/pica_to_gl.h"
|
||||
#include "video_core/renderer_opengl/renderer_opengl.h"
|
||||
#include "video_core/texture/texture_decode.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
namespace OpenGL {
|
||||
@@ -76,8 +76,9 @@ GLenum MakeAttributeType(Pica::PipelineRegs::VertexAttributeFormat format) {
|
||||
RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory,
|
||||
VideoCore::CustomTexManager& custom_tex_manager,
|
||||
VideoCore::RendererBase& renderer, Driver& driver_)
|
||||
: VideoCore::RasterizerAccelerated{memory}, driver{driver_}, runtime{driver, renderer},
|
||||
res_cache{memory, custom_tex_manager, runtime, regs, renderer},
|
||||
: VideoCore::RasterizerAccelerated{memory}, driver{driver_},
|
||||
shader_manager{renderer.GetRenderWindow(), driver, !driver.IsOpenGLES()},
|
||||
runtime{driver, renderer}, res_cache{memory, custom_tex_manager, runtime, regs, renderer},
|
||||
texture_buffer_size{TextureBufferSize()}, vertex_buffer{driver, GL_ARRAY_BUFFER,
|
||||
VERTEX_BUFFER_SIZE},
|
||||
uniform_buffer{driver, GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE},
|
||||
@@ -89,14 +90,6 @@ RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory,
|
||||
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
|
||||
state.clip_distance[0] = true;
|
||||
|
||||
// Create a 1x1 clear texture to use in the NULL case,
|
||||
// instead of OpenGL's default of solid black
|
||||
glGenTextures(1, &default_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, default_texture);
|
||||
// For some reason alpha 0 wraps around to 1.0, so use 1/255 instead
|
||||
u8 framebuffer_data[4] = {0, 0, 0, 1};
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data);
|
||||
|
||||
// Generate VAO
|
||||
sw_vao.Create();
|
||||
hw_vao.Create();
|
||||
@@ -142,9 +135,6 @@ RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory,
|
||||
(GLvoid*)offsetof(HardwareVertex, view));
|
||||
glEnableVertexAttribArray(ATTRIBUTE_VIEW);
|
||||
|
||||
// Create render framebuffer
|
||||
framebuffer.Create();
|
||||
|
||||
// Allocate and bind texture buffer lut textures
|
||||
texture_buffer_lut_lf.Create();
|
||||
texture_buffer_lut_rg.Create();
|
||||
@@ -165,9 +155,6 @@ RasterizerOpenGL::RasterizerOpenGL(Memory::MemorySystem& memory,
|
||||
state.Apply();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.GetHandle());
|
||||
|
||||
shader_program_manager =
|
||||
std::make_unique<ShaderProgramManager>(renderer.GetRenderWindow(), driver, !GLES);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
SyncEntireState();
|
||||
@@ -181,7 +168,7 @@ void RasterizerOpenGL::TickFrame() {
|
||||
|
||||
void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||
shader_program_manager->LoadDiskCache(stop_loading, callback);
|
||||
shader_manager.LoadDiskCache(stop_loading, callback);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncFixedState() {
|
||||
@@ -277,7 +264,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset,
|
||||
|
||||
bool RasterizerOpenGL::SetupVertexShader() {
|
||||
MICROPROFILE_SCOPE(OpenGL_VS);
|
||||
return shader_program_manager->UseProgrammableVertexShader(regs, Pica::g_state.vs);
|
||||
return shader_manager.UseProgrammableVertexShader(regs, Pica::g_state.vs);
|
||||
}
|
||||
|
||||
bool RasterizerOpenGL::SetupGeometryShader() {
|
||||
@@ -288,7 +275,7 @@ bool RasterizerOpenGL::SetupGeometryShader() {
|
||||
return false;
|
||||
}
|
||||
|
||||
shader_program_manager->UseFixedGeometryShader(regs);
|
||||
shader_manager.UseFixedGeometryShader(regs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -302,11 +289,13 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetupVertexShader())
|
||||
if (!SetupVertexShader()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetupGeometryShader())
|
||||
if (!SetupGeometryShader()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Draw(true, is_indexed);
|
||||
}
|
||||
@@ -329,7 +318,7 @@ bool RasterizerOpenGL::AccelerateDrawBatchInternal(bool is_indexed) {
|
||||
SetupVertexArray(buffer_ptr, buffer_offset, vs_input_index_min, vs_input_index_max);
|
||||
vertex_buffer.Unmap(vs_input_size);
|
||||
|
||||
shader_program_manager->ApplyTo(state);
|
||||
shader_manager.ApplyTo(state);
|
||||
state.Apply();
|
||||
|
||||
if (is_indexed) {
|
||||
@@ -341,9 +330,9 @@ bool RasterizerOpenGL::AccelerateDrawBatchInternal(bool is_indexed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const u8* index_data = VideoCore::g_memory->GetPhysicalPointer(
|
||||
regs.pipeline.vertex_attributes.GetPhysicalBaseAddress() +
|
||||
regs.pipeline.index_array.offset);
|
||||
const u8* index_data =
|
||||
memory.GetPhysicalPointer(regs.pipeline.vertex_attributes.GetPhysicalBaseAddress() +
|
||||
regs.pipeline.index_array.offset);
|
||||
std::tie(buffer_ptr, buffer_offset, std::ignore) = index_buffer.Map(index_buffer_size, 4);
|
||||
std::memcpy(buffer_ptr, index_data, index_buffer_size);
|
||||
index_buffer.Unmap(index_buffer_size);
|
||||
@@ -434,7 +423,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
|
||||
|
||||
// Sync and bind the shader
|
||||
if (shader_dirty) {
|
||||
shader_program_manager->UseFragmentShader(regs, use_custom_normal);
|
||||
shader_manager.UseFragmentShader(regs, use_custom_normal);
|
||||
shader_dirty = false;
|
||||
}
|
||||
|
||||
@@ -452,9 +441,9 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
|
||||
} else {
|
||||
state.draw.vertex_array = sw_vao.handle;
|
||||
state.draw.vertex_buffer = vertex_buffer.GetHandle();
|
||||
shader_program_manager->UseTrivialVertexShader();
|
||||
shader_program_manager->UseTrivialGeometryShader();
|
||||
shader_program_manager->ApplyTo(state);
|
||||
shader_manager.UseTrivialVertexShader();
|
||||
shader_manager.UseTrivialGeometryShader();
|
||||
shader_manager.ApplyTo(state);
|
||||
state.Apply();
|
||||
|
||||
std::size_t max_vertices = 3 * (VERTEX_BUFFER_SIZE / (3 * sizeof(HardwareVertex)));
|
||||
@@ -820,7 +809,7 @@ void RasterizerOpenGL::SyncBlendColor() {
|
||||
void RasterizerOpenGL::SyncLogicOp() {
|
||||
state.logic_op = PicaToGL::LogicOp(regs.framebuffer.output_merger.logic_op);
|
||||
|
||||
if (GLES) {
|
||||
if (driver.IsOpenGLES()) {
|
||||
if (!regs.framebuffer.output_merger.alphablend_enable) {
|
||||
if (regs.framebuffer.output_merger.logic_op == Pica::FramebufferRegs::LogicOp::NoOp) {
|
||||
// Color output is disabled by logic operation. We use color write mask to skip
|
||||
@@ -832,7 +821,7 @@ void RasterizerOpenGL::SyncLogicOp() {
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncColorWriteMask() {
|
||||
if (GLES) {
|
||||
if (driver.IsOpenGLES()) {
|
||||
if (!regs.framebuffer.output_merger.alphablend_enable) {
|
||||
if (regs.framebuffer.output_merger.logic_op == Pica::FramebufferRegs::LogicOp::NoOp) {
|
||||
// Color output is disabled by logic operation. We use color write mask to skip
|
||||
@@ -842,17 +831,19 @@ void RasterizerOpenGL::SyncColorWriteMask() {
|
||||
}
|
||||
}
|
||||
|
||||
auto IsColorWriteEnabled = [&](u32 value) {
|
||||
auto is_color_write_enabled = [&](u32 value) {
|
||||
return (regs.framebuffer.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE
|
||||
: GL_FALSE;
|
||||
};
|
||||
|
||||
state.color_mask.red_enabled = IsColorWriteEnabled(regs.framebuffer.output_merger.red_enable);
|
||||
state.color_mask.red_enabled =
|
||||
is_color_write_enabled(regs.framebuffer.output_merger.red_enable);
|
||||
state.color_mask.green_enabled =
|
||||
IsColorWriteEnabled(regs.framebuffer.output_merger.green_enable);
|
||||
state.color_mask.blue_enabled = IsColorWriteEnabled(regs.framebuffer.output_merger.blue_enable);
|
||||
is_color_write_enabled(regs.framebuffer.output_merger.green_enable);
|
||||
state.color_mask.blue_enabled =
|
||||
is_color_write_enabled(regs.framebuffer.output_merger.blue_enable);
|
||||
state.color_mask.alpha_enabled =
|
||||
IsColorWriteEnabled(regs.framebuffer.output_merger.alpha_enable);
|
||||
is_color_write_enabled(regs.framebuffer.output_merger.alpha_enable);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncStencilWriteMask() {
|
||||
@@ -903,12 +894,10 @@ void RasterizerOpenGL::SyncAndUploadLUTsLF() {
|
||||
return;
|
||||
}
|
||||
|
||||
u8* buffer;
|
||||
GLintptr offset;
|
||||
bool invalidate;
|
||||
std::size_t bytes_used = 0;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, texture_lf_buffer.GetHandle());
|
||||
std::tie(buffer, offset, invalidate) = texture_lf_buffer.Map(max_size, sizeof(Common::Vec4f));
|
||||
const auto [buffer, offset, invalidate] =
|
||||
texture_lf_buffer.Map(max_size, sizeof(Common::Vec4f));
|
||||
|
||||
// Sync the lighting luts
|
||||
if (uniform_block_data.lighting_lut_dirty_any || invalidate) {
|
||||
@@ -973,50 +962,48 @@ void RasterizerOpenGL::SyncAndUploadLUTs() {
|
||||
return;
|
||||
}
|
||||
|
||||
u8* buffer;
|
||||
GLintptr offset;
|
||||
bool invalidate;
|
||||
std::size_t bytes_used = 0;
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, texture_buffer.GetHandle());
|
||||
std::tie(buffer, offset, invalidate) = texture_buffer.Map(max_size, sizeof(Common::Vec4f));
|
||||
const auto [buffer, offset, invalidate] = texture_buffer.Map(max_size, sizeof(Common::Vec4f));
|
||||
|
||||
// helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap
|
||||
auto SyncProcTexValueLUT = [this, buffer, offset, invalidate, &bytes_used](
|
||||
const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut,
|
||||
std::array<Common::Vec2f, 128>& lut_data, GLint& lut_offset) {
|
||||
std::array<Common::Vec2f, 128> new_data;
|
||||
std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) {
|
||||
return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
const auto sync_proc_tex_value_lut =
|
||||
[this, buffer = buffer, offset = offset, invalidate = invalidate,
|
||||
&bytes_used](const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut,
|
||||
std::array<Common::Vec2f, 128>& lut_data, GLint& lut_offset) {
|
||||
std::array<Common::Vec2f, 128> new_data;
|
||||
std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) {
|
||||
return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()};
|
||||
});
|
||||
|
||||
if (new_data != lut_data || invalidate) {
|
||||
lut_data = new_data;
|
||||
std::memcpy(buffer + bytes_used, new_data.data(),
|
||||
new_data.size() * sizeof(Common::Vec2f));
|
||||
lut_offset = static_cast<GLint>((offset + bytes_used) / sizeof(Common::Vec2f));
|
||||
uniform_block_data.dirty = true;
|
||||
bytes_used += new_data.size() * sizeof(Common::Vec2f);
|
||||
}
|
||||
};
|
||||
if (new_data != lut_data || invalidate) {
|
||||
lut_data = new_data;
|
||||
std::memcpy(buffer + bytes_used, new_data.data(),
|
||||
new_data.size() * sizeof(Common::Vec2f));
|
||||
lut_offset = static_cast<GLint>((offset + bytes_used) / sizeof(Common::Vec2f));
|
||||
uniform_block_data.dirty = true;
|
||||
bytes_used += new_data.size() * sizeof(Common::Vec2f);
|
||||
}
|
||||
};
|
||||
|
||||
// Sync the proctex noise lut
|
||||
if (uniform_block_data.proctex_noise_lut_dirty || invalidate) {
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data,
|
||||
uniform_block_data.data.proctex_noise_lut_offset);
|
||||
sync_proc_tex_value_lut(Pica::g_state.proctex.noise_table, proctex_noise_lut_data,
|
||||
uniform_block_data.data.proctex_noise_lut_offset);
|
||||
uniform_block_data.proctex_noise_lut_dirty = false;
|
||||
}
|
||||
|
||||
// Sync the proctex color map
|
||||
if (uniform_block_data.proctex_color_map_dirty || invalidate) {
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data,
|
||||
uniform_block_data.data.proctex_color_map_offset);
|
||||
sync_proc_tex_value_lut(Pica::g_state.proctex.color_map_table, proctex_color_map_data,
|
||||
uniform_block_data.data.proctex_color_map_offset);
|
||||
uniform_block_data.proctex_color_map_dirty = false;
|
||||
}
|
||||
|
||||
// Sync the proctex alpha map
|
||||
if (uniform_block_data.proctex_alpha_map_dirty || invalidate) {
|
||||
SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data,
|
||||
uniform_block_data.data.proctex_alpha_map_offset);
|
||||
sync_proc_tex_value_lut(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data,
|
||||
uniform_block_data.data.proctex_alpha_map_offset);
|
||||
uniform_block_data.proctex_alpha_map_dirty = false;
|
||||
}
|
||||
|
||||
@@ -1070,28 +1057,25 @@ void RasterizerOpenGL::SyncAndUploadLUTs() {
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::UploadUniforms(bool accelerate_draw) {
|
||||
// glBindBufferRange below also changes the generic buffer binding point, so we sync the state
|
||||
// first
|
||||
// glBindBufferRange also changes the generic buffer binding point, so we sync the state first.
|
||||
state.draw.uniform_buffer = uniform_buffer.GetHandle();
|
||||
state.Apply();
|
||||
|
||||
bool sync_vs = accelerate_draw;
|
||||
bool sync_fs = uniform_block_data.dirty;
|
||||
|
||||
if (!sync_vs && !sync_fs)
|
||||
const bool sync_vs = accelerate_draw;
|
||||
const bool sync_fs = uniform_block_data.dirty;
|
||||
if (!sync_vs && !sync_fs) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t uniform_size = uniform_size_aligned_vs + uniform_size_aligned_fs;
|
||||
std::size_t used_bytes = 0;
|
||||
u8* uniforms;
|
||||
GLintptr offset;
|
||||
bool invalidate;
|
||||
std::tie(uniforms, offset, invalidate) =
|
||||
|
||||
const auto [uniforms, offset, invalidate] =
|
||||
uniform_buffer.Map(uniform_size, uniform_buffer_alignment);
|
||||
|
||||
if (sync_vs) {
|
||||
Pica::Shader::VSUniformData vs_uniforms;
|
||||
vs_uniforms.uniforms.SetFromRegs(Pica::g_state.regs.vs, Pica::g_state.vs);
|
||||
vs_uniforms.uniforms.SetFromRegs(regs.vs, Pica::g_state.vs);
|
||||
std::memcpy(uniforms + used_bytes, &vs_uniforms, sizeof(vs_uniforms));
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, static_cast<GLuint>(Pica::Shader::UniformBindings::VS),
|
||||
uniform_buffer.GetHandle(), offset + used_bytes,
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "core/hw/gpu.h"
|
||||
#include "video_core/rasterizer_accelerated.h"
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
#include "video_core/regs_texturing.h"
|
||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||
@@ -24,6 +23,8 @@ class CustomTexManager;
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
struct ScreenInfo;
|
||||
|
||||
class Driver;
|
||||
class ShaderProgramManager;
|
||||
|
||||
@@ -48,7 +49,7 @@ public:
|
||||
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
|
||||
bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr,
|
||||
u32 pixel_stride, ScreenInfo& screen_info) override;
|
||||
u32 pixel_stride, ScreenInfo& screen_info);
|
||||
bool AccelerateDrawBatch(bool is_indexed) override;
|
||||
|
||||
private:
|
||||
@@ -132,10 +133,9 @@ private:
|
||||
private:
|
||||
Driver& driver;
|
||||
OpenGLState state;
|
||||
GLuint default_texture;
|
||||
ShaderProgramManager shader_manager;
|
||||
TextureRuntime runtime;
|
||||
RasterizerCache res_cache;
|
||||
std::unique_ptr<ShaderProgramManager> shader_program_manager;
|
||||
|
||||
OGLVertexArray sw_vao; // VAO for software shader draw
|
||||
OGLVertexArray hw_vao; // VAO for hardware shader / accelerate draw
|
||||
@@ -147,7 +147,6 @@ private:
|
||||
OGLStreamBuffer index_buffer;
|
||||
OGLStreamBuffer texture_buffer;
|
||||
OGLStreamBuffer texture_lf_buffer;
|
||||
OGLFramebuffer framebuffer;
|
||||
GLint uniform_buffer_alignment;
|
||||
std::size_t uniform_size_aligned_vs;
|
||||
std::size_t uniform_size_aligned_fs;
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include "common/scope_exit.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "video_core/renderer_opengl/gl_driver.h"
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/renderer_opengl/gl_state.h"
|
||||
#include "video_core/renderer_opengl/gl_vars.h"
|
||||
|
||||
|
@@ -528,13 +528,13 @@ void Surface::ScaleUp(u32 new_scale) {
|
||||
textures[1] = MakeHandle(GL_TEXTURE_2D, GetScaledWidth(), GetScaledHeight(), levels, tuple,
|
||||
DebugName(true));
|
||||
|
||||
VideoCore::TextureBlit blit = {
|
||||
.src_rect = GetRect(),
|
||||
.dst_rect = GetScaledRect(),
|
||||
};
|
||||
for (u32 level = 0; level < levels; level++) {
|
||||
blit.src_level = level;
|
||||
blit.dst_level = level;
|
||||
const VideoCore::TextureBlit blit = {
|
||||
.src_level = level,
|
||||
.dst_level = level,
|
||||
.src_rect = GetRect(level),
|
||||
.dst_rect = GetScaledRect(level),
|
||||
};
|
||||
BlitScale(blit, true);
|
||||
}
|
||||
}
|
||||
|
@@ -78,7 +78,8 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
|
||||
RendererOpenGL::RendererOpenGL(Core::System& system, Frontend::EmuWindow& window,
|
||||
Frontend::EmuWindow* secondary_window)
|
||||
: VideoCore::RendererBase{system, window, secondary_window}, driver{system.TelemetrySession()},
|
||||
frame_dumper{system, window} {
|
||||
rasterizer{system.Memory(), system.CustomTexManager(), *this, driver}, frame_dumper{system,
|
||||
window} {
|
||||
const bool has_debug_tool = driver.HasDebugTool();
|
||||
window.mailbox = std::make_unique<OGLTextureMailbox>(has_debug_tool);
|
||||
if (secondary_window) {
|
||||
@@ -86,8 +87,6 @@ RendererOpenGL::RendererOpenGL(Core::System& system, Frontend::EmuWindow& window
|
||||
}
|
||||
frame_dumper.mailbox = std::make_unique<OGLVideoDumpingMailbox>();
|
||||
InitOpenGLObjects();
|
||||
rasterizer = std::make_unique<RasterizerOpenGL>(system.Memory(), system.CustomTexManager(),
|
||||
*this, driver);
|
||||
}
|
||||
|
||||
RendererOpenGL::~RendererOpenGL() = default;
|
||||
@@ -121,8 +120,7 @@ void RendererOpenGL::SwapBuffers() {
|
||||
|
||||
EndFrame();
|
||||
prev_state.Apply();
|
||||
|
||||
rasterizer->TickFrame();
|
||||
rasterizer.TickFrame();
|
||||
}
|
||||
|
||||
void RendererOpenGL::RenderScreenshot() {
|
||||
@@ -273,8 +271,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
|
||||
// only allows rows to have a memory alignement of 4.
|
||||
ASSERT(pixel_stride % 4 == 0);
|
||||
|
||||
if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr,
|
||||
static_cast<u32>(pixel_stride), screen_info)) {
|
||||
if (!rasterizer.AccelerateDisplay(framebuffer, framebuffer_addr, static_cast<u32>(pixel_stride),
|
||||
screen_info)) {
|
||||
// Reset the screen info's display texture to its own permanent texture
|
||||
screen_info.display_texture = screen_info.texture.resource.handle;
|
||||
screen_info.display_texcoords = Common::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
|
||||
@@ -903,7 +901,7 @@ void RendererOpenGL::CleanupVideoDumping() {
|
||||
}
|
||||
|
||||
void RendererOpenGL::Sync() {
|
||||
rasterizer->SyncEntireState();
|
||||
rasterizer.SyncEntireState();
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
@@ -46,8 +46,8 @@ public:
|
||||
Frontend::EmuWindow* secondary_window);
|
||||
~RendererOpenGL() override;
|
||||
|
||||
[[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() const override {
|
||||
return rasterizer.get();
|
||||
[[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() override {
|
||||
return &rasterizer;
|
||||
}
|
||||
|
||||
void SwapBuffers() override;
|
||||
@@ -86,8 +86,8 @@ private:
|
||||
|
||||
private:
|
||||
Driver driver;
|
||||
RasterizerOpenGL rasterizer;
|
||||
OpenGLState state;
|
||||
std::unique_ptr<RasterizerOpenGL> rasterizer;
|
||||
|
||||
// OpenGL object IDs
|
||||
OGLVertexArray vertex_array;
|
||||
|
@@ -13,7 +13,7 @@ namespace SwRenderer {
|
||||
|
||||
RendererSoftware::RendererSoftware(Core::System& system, Frontend::EmuWindow& window)
|
||||
: VideoCore::RendererBase{system, window, nullptr}, memory{system.Memory()},
|
||||
rasterizer{std::make_unique<RasterizerSoftware>(system.Memory())} {}
|
||||
rasterizer{system.Memory()} {}
|
||||
|
||||
RendererSoftware::~RendererSoftware() = default;
|
||||
|
||||
|
@@ -24,8 +24,8 @@ public:
|
||||
explicit RendererSoftware(Core::System& system, Frontend::EmuWindow& window);
|
||||
~RendererSoftware() override;
|
||||
|
||||
[[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() const override {
|
||||
return rasterizer.get();
|
||||
[[nodiscard]] VideoCore::RasterizerInterface* Rasterizer() override {
|
||||
return &rasterizer;
|
||||
}
|
||||
|
||||
[[nodiscard]] const ScreenInfo& Screen(VideoCore::ScreenId id) const noexcept {
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
|
||||
private:
|
||||
Memory::MemorySystem& memory;
|
||||
std::unique_ptr<RasterizerSoftware> rasterizer;
|
||||
RasterizerSoftware rasterizer;
|
||||
std::array<ScreenInfo, 3> screen_infos{};
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user