diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 4c1bfd1858..5396b613a7 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -1593,6 +1593,9 @@ namespace gl case GL_TEXTURE_CUBE_MAP: glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, reinterpret_cast(&old_binding)); break; + case GL_TEXTURE_2D_ARRAY: + glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, reinterpret_cast(&old_binding)); + break; case GL_TEXTURE_BUFFER: glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, reinterpret_cast(&old_binding)); break; @@ -1628,6 +1631,7 @@ namespace gl depth = 1; break; case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: glTexStorage3D(target, mipmaps, sized_format, width, height, depth); break; case GL_TEXTURE_BUFFER: @@ -1807,7 +1811,7 @@ namespace gl { pixel_settings.apply(); - switch (static_cast(m_target)) + switch (const auto target_ =static_cast(m_target)) { case GL_TEXTURE_1D: { @@ -1820,8 +1824,9 @@ namespace gl break; } case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: { - DSA_CALL(TextureSubImage3D, m_id, GL_TEXTURE_3D, 0, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast(format), static_cast(type), src); + DSA_CALL(TextureSubImage3D, m_id, target_, 0, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast(format), static_cast(type), src); break; } case GL_TEXTURE_CUBE_MAP: @@ -1920,11 +1925,19 @@ namespace gl m_image_data = data; m_aspect_flags = aspect_flags; - const auto num_levels = data->levels(); - const auto num_layers = (target != GL_TEXTURE_CUBE_MAP) ? 1 : 6; + u32 num_layers; + switch (target) + { + default: + num_layers = 1; break; + case GL_TEXTURE_CUBE_MAP: + num_layers = 6; break; + case GL_TEXTURE_2D_ARRAY: + num_layers = data->depth(); break; + } glGenTextures(1, &m_id); - glTextureView(m_id, target, data->id(), sized_format, 0, num_levels, 0, num_layers); + glTextureView(m_id, target, data->id(), sized_format, 0, data->levels(), 0, num_layers); if (argb_swizzle) { diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 16d38165cb..5c889f9956 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -400,12 +400,13 @@ namespace gl fs_src = "#version 420\n\n" "layout(binding=31) uniform sampler2D fs0;\n" + "layout(binding=30) uniform sampler2DArray fs1;\n" "layout(location=0) in vec2 tc0;\n" "layout(location=1) flat in vec4 clip_rect;\n" "layout(location=0) out vec4 ocol;\n" "uniform vec4 color;\n" "uniform float time;\n" - "uniform int read_texture;\n" + "uniform int sampler_mode;\n" "uniform int pulse_glow;\n" "uniform int clip_region;\n" "uniform int blur_strength;\n" @@ -475,10 +476,18 @@ namespace gl " if (pulse_glow != 0)\n" " diff_color.a *= (sin(time) + 1.f) * 0.5f;\n" "\n" - " if (read_texture != 0)\n" + " switch (sampler_mode)\n" + " {\n" + " case 1:\n" " ocol = sample_image(fs0, tc0) * diff_color;\n" - " else\n" + " break;\n" + " case 2:\n" + " ocol = texture(fs1, vec3(tc0.x, fract(tc0.y), trunc(tc0.y))) * diff_color;\n" + " break;\n" + " default:\n" " ocol = diff_color;\n" + " break;\n" + " }\n" "}\n"; // Smooth filtering required for inputs @@ -552,14 +561,27 @@ namespace gl gl::texture_view* find_font(rsx::overlays::font *font) { + const auto font_size = font->get_glyph_data_dimensions(); + u64 key = reinterpret_cast(font); auto found = view_cache.find(key); if (found != view_cache.end()) - return found->second.get(); + { + if (const auto this_size = found->second->image()->size3D(); + font_size.width == this_size.width && + font_size.height == this_size.height && + font_size.depth == this_size.depth) + { + return found->second.get(); + } + } - //Create font file - auto tex = std::make_unique(GL_TEXTURE_2D, font->width, font->height, 1, 1, GL_R8); - tex->copy_from(font->glyph_data.data(), gl::texture::format::r, gl::texture::type::ubyte, {}); + // Create font file + std::vector glyph_data; + font->get_glyph_data(glyph_data); + + auto tex = std::make_unique(GL_TEXTURE_2D_ARRAY, font_size.width, font_size.height, font_size.depth, 1, GL_R8); + tex->copy_from(glyph_data.data(), gl::texture::format::r, gl::texture::type::ubyte, {}); GLenum remap[] = { GL_RED, GL_RED, GL_RED, GL_RED }; auto view = std::make_unique(tex.get(), remap); @@ -644,14 +666,15 @@ namespace gl program_handle.uniforms["ui_scale"] = color4f(static_cast(ui.virtual_width), static_cast(ui.virtual_height), 1.f, 1.f); program_handle.uniforms["time"] = static_cast(get_system_time() / 1000) * 0.005f; - saved_sampler_state saved(31, m_sampler); + saved_sampler_state save_30(30, m_sampler); + saved_sampler_state save_31(31, m_sampler); for (auto &cmd : ui.get_compiled().draw_commands) { set_primitive_type(cmd.config.primitives); upload_vertex_data(reinterpret_cast(cmd.verts.data()), ::size32(cmd.verts) * 4u); num_drawable_elements = ::size32(cmd.verts); - GLint texture_exists = GL_TRUE; + GLint texture_read = GL_TRUE; switch (cmd.config.texture_ref) { @@ -660,7 +683,7 @@ namespace gl //TODO case rsx::overlays::image_resource_id::none: { - texture_exists = GL_FALSE; + texture_read = GL_FALSE; glBindTexture(GL_TEXTURE_2D, GL_NONE); break; } @@ -671,7 +694,10 @@ namespace gl } case rsx::overlays::image_resource_id::font_file: { - glBindTexture(GL_TEXTURE_2D, find_font(cmd.config.font_ref)->id()); + texture_read = (GL_TRUE + 1); + glActiveTexture(GL_TEXTURE0 + 30); + glBindTexture(GL_TEXTURE_2D_ARRAY, find_font(cmd.config.font_ref)->id()); + glActiveTexture(GL_TEXTURE0 + 31); break; } default: @@ -682,7 +708,7 @@ namespace gl } program_handle.uniforms["color"] = cmd.config.color; - program_handle.uniforms["read_texture"] = texture_exists; + program_handle.uniforms["sampler_mode"] = texture_read; program_handle.uniforms["pulse_glow"] = static_cast(cmd.config.pulse_glow); program_handle.uniforms["blur_strength"] = static_cast(cmd.config.blur_strength); program_handle.uniforms["clip_region"] = static_cast(cmd.config.clip_region);