예제 #1
0
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);
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
	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;
	}
예제 #6
0
GSVector2i GSOsdManager::get_texture_font_size() {
	return GSVector2i(m_atlas_w, m_atlas_h);
}
예제 #7
0
GSVector2i GSRendererHW::GetCustomResolution()
{
	return GSVector2i(m_custom_width, m_custom_height);
}
예제 #8
0
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);
}