GSVector2i GSRendererHW::GetInternalResolution() { GSVector2i dr(GetDisplayRect().width(), GetDisplayRect().height()); if (m_upscale_multiplier) return GSVector2i(dr.x * m_upscale_multiplier, dr.y * m_upscale_multiplier); else return GSVector2i(m_width, m_height); }
void GSTextureOGL::CommitPages(const GSVector2i& region, bool commit) { GLState::available_vram += m_mem_usage; if (commit) { if (m_committed_size.x == 0) { // Nothing allocated so far GL_INS("CommitPages initial %dx%d of %u", region.x, region.y, m_texture_id); glTexturePageCommitmentEXT(m_texture_id, GL_TEX_LEVEL_0, 0, 0, 0, region.x, region.y, 1, commit); } else { GL_INS("CommitPages extend %dx%d to %dx%d of %u", m_committed_size.x, m_committed_size.y, region.x, region.y, m_texture_id); int w = region.x - m_committed_size.x; int h = region.y - m_committed_size.y; // Extend width glTexturePageCommitmentEXT(m_texture_id, GL_TEX_LEVEL_0, m_committed_size.x, 0, 0, w, m_committed_size.y, 1, commit); // Extend height glTexturePageCommitmentEXT(m_texture_id, GL_TEX_LEVEL_0, 0, m_committed_size.y, 0, region.x, h, 1, commit); } m_committed_size = region; } else { // Release everything GL_INS("CommitPages release of %u", m_texture_id); glTexturePageCommitmentEXT(m_texture_id, GL_TEX_LEVEL_0, 0, 0, 0, m_committed_size.x, m_committed_size.y, 1, commit); m_committed_size = GSVector2i(0, 0); } m_mem_usage = (m_committed_size.x * m_committed_size.y) << m_int_shift; GLState::available_vram -= m_mem_usage; }
GSTextureSW::GSTextureSW(int type, int width, int height) { m_mapped.clear(std::memory_order_release); m_size = GSVector2i(width, height); m_type = type; m_format = 0; m_pitch = ((width << 2) + 31) & ~31; m_data = _aligned_malloc(m_pitch * height, 32); }
void Clear() { fbo = 0; viewport = GSVector2i(0, 0); scissor = GSVector4i(0, 0, 0, 0); blend = false; eq_RGB = 0; eq_A = 0; f_sRGB = 0; f_dRGB = 0; f_sA = 0; f_dA = 0; r_msk = true; g_msk = true; b_msk = true; a_msk = true; bf = 0.0; depth = false; depth_func = 0; depth_mask = false; stencil = false; stencil_func = 0; stencil_pass = 0; ubo = 0; ps_ss = 0; rt = 0; ds = 0; tex_unit[0] = 0; tex_unit[1] = 0; tex = 0; tex_handle[0] = 0; tex_handle[1] = 0; ps = 0; gs = 0; vs = 0; program = 0; dirty_prog = false; dirty_subroutine_vs = false; dirty_subroutine_ps = false; dirty_ressources = false; }
void Clear() { fbo = 0; viewport = GSVector2i(0, 0); scissor = GSVector4i(0, 0, 0, 0); blend = false; eq_RGB = 0; f_sRGB = 0; f_dRGB = 0; wrgba = 0xF; bf = 0.0; depth = false; depth_func = 0; depth_mask = false; stencil = false; stencil_func = 0; stencil_pass = 0; ubo = 0; ps_ss = 0; rt = 0; ds = 0; for (size_t i = 0; i < countof(tex_unit); i++) tex_unit[i] = 0; for (size_t i = 0; i < countof(tex_handle); i++) tex_handle[i] = 0; ps = 0; gs = 0; vs = 0; program = 0; dirty_prog = false; dirty_ressources = false; }
GSVector2i GSOsdManager::get_texture_font_size() { return GSVector2i(m_atlas_w, m_atlas_h); }
GSVector2i GSRendererHW::GetCustomResolution() { return GSVector2i(m_custom_width, m_custom_height); }
GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read, bool mipmap) : m_clean(false), m_generate_mipmap(true), m_local_buffer(nullptr), m_r_x(0), m_r_y(0), m_r_w(0), m_r_h(0), m_layer(0) { // OpenGL didn't like dimensions of size 0 m_size.x = std::max(1,w); m_size.y = std::max(1,h); m_format = format; m_type = type; m_fbo_read = fbo_read; m_texture_id = 0; m_sparse = false; m_max_layer = 1; // Bunch of constant parameter switch (m_format) { // 1 Channel integer case GL_R32UI: case GL_R32I: m_int_format = GL_RED_INTEGER; m_int_type = (m_format == GL_R32UI) ? GL_UNSIGNED_INT : GL_INT; m_int_shift = 2; break; case GL_R16UI: m_int_format = GL_RED_INTEGER; m_int_type = GL_UNSIGNED_SHORT; m_int_shift = 1; break; // 1 Channel normalized case GL_R8: m_int_format = GL_RED; m_int_type = GL_UNSIGNED_BYTE; m_int_shift = 0; break; // 4 channel normalized case GL_RGBA16: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_SHORT; m_int_shift = 3; break; case GL_RGBA8: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_BYTE; m_int_shift = 2; break; // 4 channel integer case GL_RGBA16I: case GL_RGBA16UI: m_int_format = GL_RGBA_INTEGER; m_int_type = (m_format == GL_R16UI) ? GL_UNSIGNED_SHORT : GL_SHORT; m_int_shift = 3; break; // 4 channel float case GL_RGBA32F: m_int_format = GL_RGBA; m_int_type = GL_FLOAT; m_int_shift = 4; break; case GL_RGBA16F: m_int_format = GL_RGBA; m_int_type = GL_HALF_FLOAT; m_int_shift = 3; break; // Depth buffer case GL_DEPTH32F_STENCIL8: m_int_format = GL_DEPTH_STENCIL; m_int_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; m_int_shift = 3; // 4 bytes for depth + 4 bytes for stencil by texels break; // Backbuffer case 0: m_int_format = 0; m_int_type = 0; m_int_shift = 2; // 4 bytes by texels break; default: m_int_format = 0; m_int_type = 0; m_int_shift = 0; ASSERT(0); } switch (m_type) { case GSTexture::Backbuffer: return; // backbuffer isn't a real texture case GSTexture::Offscreen: // Offscreen is only used to read color. So it only requires 4B by pixel m_local_buffer = (uint8*)_aligned_malloc(m_size.x * m_size.y * 4, 32); break; case GSTexture::Texture: // Only 32 bits input texture will be supported for mipmap m_max_layer = mipmap && m_format == GL_RGBA8 ? (int)log2(std::max(w,h)) : 1; break; case SparseRenderTarget: case SparseDepthStencil: m_sparse = true; break; default: break; } switch (m_format) { case GL_R16UI: case GL_R8: m_sparse &= GLLoader::found_compatible_GL_ARB_sparse_texture2; SetGpuPageSize(GSVector2i(255, 255)); break; case GL_R32UI: case GL_R32I: case GL_RGBA16: case GL_RGBA8: case GL_RGBA16I: case GL_RGBA16UI: case GL_RGBA16F: case 0: m_sparse &= GLLoader::found_compatible_GL_ARB_sparse_texture2; SetGpuPageSize(GSVector2i(127, 127)); break; case GL_RGBA32F: m_sparse &= GLLoader::found_compatible_GL_ARB_sparse_texture2; SetGpuPageSize(GSVector2i(63, 63)); break; case GL_DEPTH32F_STENCIL8: m_sparse &= GLLoader::found_compatible_sparse_depth; SetGpuPageSize(GSVector2i(127, 127)); break; default: ASSERT(0); } // Create a gl object (texture isn't allocated here) glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id); if (m_format == GL_R8) { // Emulate DX behavior, beside it avoid special code in shader to differentiate // palette texture from a GL_RGBA target or a GL_R texture. glTextureParameteri(m_texture_id, GL_TEXTURE_SWIZZLE_A, GL_RED); } if (m_sparse) { GSVector2i old_size = m_size; m_size = RoundUpPage(m_size); if (m_size != old_size) { fprintf(stderr, "Sparse texture size (%dx%d) isn't a multiple of gpu page size (%dx%d)\n", old_size.x, old_size.y, m_gpu_page_size.x, m_gpu_page_size.y); } glTextureParameteri(m_texture_id, GL_TEXTURE_SPARSE_ARB, true); } else { m_committed_size = m_size; } m_mem_usage = (m_committed_size.x * m_committed_size.y) << m_int_shift; static int every_512 = 0; GLState::available_vram -= m_mem_usage; if ((GLState::available_vram < 0) && (every_512 % 512 == 0)) { fprintf(stderr, "Available VRAM is very low (%lld), a crash is expected ! Disable Larger framebuffer or reduce upscaling!\n", GLState::available_vram); every_512++; // Pull emergency break throw std::bad_alloc(); } glTextureStorage2D(m_texture_id, m_max_layer + GL_TEX_LEVEL_0, m_format, m_size.x, m_size.y); }