Merge pull request #3639 from wwylele/texture-cude-fix
gl_rasterizer_cache: exit FillTextureCube when address is invalid
This commit is contained in:
commit
9772513141
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in New Issue