citra-emu
/
citra
Archived
1
0
Fork 0

Merge pull request #3639 from wwylele/texture-cude-fix

gl_rasterizer_cache: exit FillTextureCube when address is invalid
This commit is contained in:
Weiyi Wang 2018-04-12 22:54:14 +03:00 committed by GitHub
commit 9772513141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 11 deletions

View File

@ -44,7 +44,6 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) {
texture_cube_sampler.Create(); texture_cube_sampler.Create();
state.texture_cube_unit.sampler = texture_cube_sampler.sampler.handle; state.texture_cube_unit.sampler = texture_cube_sampler.sampler.handle;
texture_cube.Create(); texture_cube.Create();
state.texture_cube_unit.texture_cube = texture_cube.handle;
// Generate VBO, VAO and UBO // Generate VBO, VAO and UBO
vertex_buffer = OGLStreamBuffer::MakeBuffer(GLAD_GL_ARB_buffer_storage, GL_ARRAY_BUFFER); vertex_buffer = OGLStreamBuffer::MakeBuffer(GLAD_GL_ARB_buffer_storage, GL_ARRAY_BUFFER);
@ -391,14 +390,19 @@ void RasterizerOpenGL::DrawTriangles() {
switch (texture.config.type.Value()) { switch (texture.config.type.Value()) {
case TextureType::TextureCube: case TextureType::TextureCube:
using CubeFace = Pica::TexturingRegs::CubeFace; using CubeFace = Pica::TexturingRegs::CubeFace;
res_cache.FillTextureCube( if (res_cache.FillTextureCube(
texture_cube.handle, texture, texture_cube.handle, texture,
regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveX), regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveX),
regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeX), regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeX),
regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveY), regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveY),
regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeY), regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeY),
regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ), regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ),
regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeZ)); 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); texture_cube_sampler.SyncWithConfig(texture.config);
state.texture_units[texture_index].texture_2d = 0; state.texture_units[texture_index].texture_2d = 0;
continue; // Texture unit 0 setup finished. Continue to next unit 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) { for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) {
state.texture_units[texture_index].texture_2d = 0; state.texture_units[texture_index].texture_2d = 0;
} }
state.texture_cube_unit.texture_cube = 0;
state.Apply(); state.Apply();
// Mark framebuffer surfaces as dirty // Mark framebuffer surfaces as dirty

View File

@ -1228,7 +1228,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(
return GetSurface(params, ScaleMatch::Ignore, true); return GetSurface(params, ScaleMatch::Ignore, true);
} }
void RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle, bool RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle,
const Pica::TexturingRegs::FullTextureConfig& config, const Pica::TexturingRegs::FullTextureConfig& config,
PAddr px, PAddr nx, PAddr py, PAddr ny, PAddr pz, PAddr px, PAddr nx, PAddr py, PAddr ny, PAddr pz,
PAddr nz) { PAddr nz) {
@ -1250,6 +1250,8 @@ void RasterizerCacheOpenGL::FillTextureCube(GLuint dest_handle,
u16 res_scale = 1; u16 res_scale = 1;
for (auto& face : faces) { for (auto& face : faces) {
face.surface = GetTextureSurface(config, face.address); face.surface = GetTextureSurface(config, face.address);
if (face.surface == nullptr)
return false;
res_scale = std::max(res_scale, face.surface->res_scale); 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, 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); scaled_size, scaled_size, GL_COLOR_BUFFER_BIT, GL_LINEAR);
} }
return true;
} }
SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(

View File

@ -326,7 +326,7 @@ public:
PAddr addr_override = 0); PAddr addr_override = 0);
/// Copy surfaces to a cubemap texture based on the texture configuration /// 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); PAddr px, PAddr nx, PAddr py, PAddr ny, PAddr pz, PAddr nz);
/// Get the color and depth surfaces based on the framebuffer configuration /// Get the color and depth surfaces based on the framebuffer configuration