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
3 changed files with 20 additions and 11 deletions
|
@ -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(
|
||||
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));
|
||||
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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue