void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { PAddr texture_addr = config.config.GetPhysicalAddress(); const auto cached_texture = texture_cache.find(texture_addr); if (cached_texture != texture_cache.end()) { state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle; state.Apply(); } else { std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>(); new_texture->texture.Create(); state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.Apply(); // TODO: Need to choose filters that correspond to PICA once register is declared glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(config.config.wrap_s)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(config.config.wrap_t)); const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); new_texture->width = info.width; new_texture->height = info.height; new_texture->size = info.width * info.height * Pica::Regs::NibblesPerPixel(info.format); u8* texture_src_data = Memory::GetPhysicalPointer(texture_addr); std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { temp_texture_buffer_rgba[x + info.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, info.height - 1 - y, info); } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_texture_buffer_rgba.get()); texture_cache.emplace(texture_addr, std::move(new_texture)); } }
void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::DebugUtils::TextureInfo& info) { const auto cached_texture = texture_cache.find(info.physical_address); if (cached_texture != texture_cache.end()) { state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle; state.Apply(); } else { MICROPROFILE_SCOPE(OpenGL_TextureUpload); std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>(); new_texture->texture.Create(); state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.Apply(); glActiveTexture(GL_TEXTURE0 + texture_unit); u8* texture_src_data = Memory::GetPhysicalPointer(info.physical_address); new_texture->width = info.width; new_texture->height = info.height; new_texture->size = info.stride * info.height; new_texture->addr = info.physical_address; new_texture->hash = Common::ComputeHash64(texture_src_data, new_texture->size); std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { temp_texture_buffer_rgba[x + info.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, info.height - 1 - y, info); } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_texture_buffer_rgba.get()); texture_cache.emplace(info.physical_address, std::move(new_texture)); } }