diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e4c620d96a..cacecbed27 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -44,7 +44,6 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { texture_cube_sampler.Create(); state.texture_cube_unit.sampler = texture_cube_sampler.sampler.handle; texture_cube.Create(); - state.texture_cube_unit.texture_cube = texture_cube.handle; // Generate VBO, VAO and UBO vertex_buffer = OGLStreamBuffer::MakeBuffer(GLAD_GL_ARB_buffer_storage, GL_ARRAY_BUFFER); @@ -391,14 +390,19 @@ void RasterizerOpenGL::DrawTriangles() { switch (texture.config.type.Value()) { case TextureType::TextureCube: using CubeFace = Pica::TexturingRegs::CubeFace; - res_cache.FillTextureCube( - texture_cube.handle, texture, - regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveX), - regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeX), - regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveY), - regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeY), - regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ), - regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeZ)); + if (res_cache.FillTextureCube( + texture_cube.handle, texture, + regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveX), + regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeX), + regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveY), + regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeY), + regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ), + regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeZ))) { + state.texture_cube_unit.texture_cube = texture_cube.handle; + } else { + // Can occur when texture addr is null or its memory is unmapped/invalid + state.texture_cube_unit.texture_cube = 0; + } texture_cube_sampler.SyncWithConfig(texture.config); state.texture_units[texture_index].texture_2d = 0; continue; // Texture unit 0 setup finished. Continue to next unit @@ -506,6 +510,7 @@ void RasterizerOpenGL::DrawTriangles() { for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { state.texture_units[texture_index].texture_2d = 0; } + state.texture_cube_unit.texture_cube = 0; state.Apply(); // Mark framebuffer surfaces as dirty diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 1500519fcd..31787c86c3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1228,7 +1228,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface( return GetSurface(params, ScaleMatch::Ignore, true); } -void RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle, +bool RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle, const Pica::TexturingRegs::FullTextureConfig& config, PAddr px, PAddr nx, PAddr py, PAddr ny, PAddr pz, PAddr nz) { @@ -1250,6 +1250,8 @@ void RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle, u16 res_scale = 1; for (auto& face : faces) { face.surface = GetTextureSurface(config, face.address); + if (face.surface == nullptr) + return false; res_scale = std::max(res_scale, face.surface->res_scale); } @@ -1298,6 +1300,8 @@ void RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle, glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, 0, 0, scaled_size, scaled_size, GL_COLOR_BUFFER_BIT, GL_LINEAR); } + + return true; } SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 719f713a13..1b01d3ad54 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -326,7 +326,7 @@ public: PAddr addr_override = 0); /// Copy surfaces to a cubemap texture based on the texture configuration - void FillTextureCube(GLuint dest_handle, const Pica::TexturingRegs::FullTextureConfig& config, + bool FillTextureCube(GLuint dest_handle, const Pica::TexturingRegs::FullTextureConfig& config, PAddr px, PAddr nx, PAddr py, PAddr ny, PAddr pz, PAddr nz); /// Get the color and depth surfaces based on the framebuffer configuration