diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 685cb89fc1..4073a86080 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -909,7 +909,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) glColorMask(((arg & 0x20) ? 1 : 0), ((arg & 0x40) ? 1 : 0), ((arg & 0x80) ? 1 : 0), ((arg & 0x10) ? 1 : 0)); glClearColor(clear_r / 255.f, clear_g / 255.f, clear_b / 255.f, clear_a / 255.f); - mask |= GLenum(gl::buffers::color); + bool exists_active_color_surface = false; rsx::for_each_active_color_surface([&](int index) { @@ -917,6 +917,8 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) if (texture) { + exists_active_color_surface = true; + if ((arg & color_mask) == color_mask) { texture->ignore(gl::cache_buffers::local); @@ -928,6 +930,11 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) } } }); + + if (exists_active_color_surface) + { + mask |= GLenum(gl::buffers::color); + } } if (mask) @@ -1135,12 +1142,10 @@ gl::texture_info surface_info(rsx::surface_color_format format, u32 offset, u32 info.height = height; info.depth = 1; info.pitch = pitch; - info.compressed_size = 0; info.target = gl::texture::target::texture2D; info.dimension = 2; - //TODO - info.swizzled = false; info.start_address = rsx::get_address(offset, location); + info.mipmap = 1; info.format = gl::get_texture_format(surface_format_to_texture_format(format)); @@ -1194,74 +1199,90 @@ void GLGSRender::init_buffers(bool skip_reading) u32 offset = rsx::method_registers[mr_color_offset[index]]; u32 location = rsx::method_registers[mr_color_dma[index]]; u32 pitch = rsx::method_registers[mr_color_pitch[index]]; + bool swizzled = m_surface.type == CELL_GCM_SURFACE_SWIZZLE; gl::texture_info info = surface_info(m_surface.color_format, offset, location, m_surface.width, m_surface.height, pitch); - info.antialiasing = m_surface.antialias; - info.swizzled = m_surface.type == CELL_GCM_SURFACE_SWIZZLE; + + info.swizzled = swizzled; + cached_color_buffers[index] = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local); draw_fbo.color[index] = cached_color_buffers[index]->view(); }); - if (rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE]) { u32 offset = rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET]; u32 location = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]; - u32 pitch = rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z]; - - gl::texture_info info{}; - - info.width = m_surface.width * m_surface.width_mult; - info.height = m_surface.height * m_surface.height_mult; - info.depth = 1; - info.pitch = pitch; - info.dimension = 2; - info.compressed_size = 0; - info.start_address = rsx::get_address(offset, location); - info.target = gl::texture::target::texture2D; - info.swizzled = false; + u32 pitch = rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z] & ~63; + int bpp; switch (m_surface.depth_format) { case rsx::surface_depth_format::z16: - info.format.bpp = 2; - info.format.flags = gl::texture_flags::swap_bytes; - info.format.type = gl::texture::type::ushort; - info.format.internal_format = gl::texture::sized_internal_format::depth16; - info.format.format = gl::texture::format::depth; + bpp = 2; break; case rsx::surface_depth_format::z24s8: - info.format.bpp = 4; - info.format.flags = gl::texture_flags::swap_bytes; - info.format.type = gl::texture::type::uint_24_8; - info.format.internal_format = gl::texture::sized_internal_format::depth24_stencil8; - info.format.format = gl::texture::format::depth_stencil; + bpp = 4; break; - - default: - throw EXCEPTION(""); } - info.format.remap = { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO }; - - __glcheck cached_depth_buffer = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local); - - switch (m_surface.depth_format) + if (pitch && pitch < bpp * m_surface.width) { - case rsx::surface_depth_format::z16: - __glcheck draw_fbo.depth = cached_depth_buffer->view(); - __glcheck draw_fbo.stencil = null_texture; - break; - - case rsx::surface_depth_format::z24s8: - __glcheck draw_fbo.depth_stencil = cached_depth_buffer->view(); - break; + __glcheck draw_fbo.depth_stencil = null_texture; + cached_depth_buffer = nullptr; + } + else + { + if (!pitch) + { + pitch = m_surface.width * bpp; + } + + gl::texture_info info{}; + + info.width = m_surface.width; + info.height = m_surface.height; + info.depth = 1; + info.pitch = pitch; + info.dimension = 2; + info.start_address = rsx::get_address(offset, location); + info.target = gl::texture::target::texture2D; + info.format.bpp = bpp; + info.mipmap = 1; + + switch (m_surface.depth_format) + { + case rsx::surface_depth_format::z16: + info.format.flags = gl::texture_flags::swap_bytes; + info.format.type = gl::texture::type::ushort; + info.format.internal_format = gl::texture::sized_internal_format::depth16; + info.format.format = gl::texture::format::depth; + break; + + case rsx::surface_depth_format::z24s8: + info.format.flags = gl::texture_flags::swap_bytes; + info.format.type = gl::texture::type::uint_24_8; + info.format.internal_format = gl::texture::sized_internal_format::depth24_stencil8; + info.format.format = gl::texture::format::depth_stencil; + break; + } + + info.format.remap = { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO }; + + __glcheck cached_depth_buffer = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local); + + switch (m_surface.depth_format) + { + case rsx::surface_depth_format::z16: + __glcheck draw_fbo.depth = cached_depth_buffer->view(); + __glcheck draw_fbo.stencil = null_texture; + break; + + case rsx::surface_depth_format::z24s8: + __glcheck draw_fbo.depth_stencil = cached_depth_buffer->view(); + break; + } } - } - else - { - __glcheck draw_fbo.depth_stencil = null_texture; - cached_depth_buffer = nullptr; } __glcheck draw_fbo.bind(); diff --git a/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp b/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp index ba77d1fe34..8db95f5f27 100644 --- a/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp +++ b/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp @@ -61,7 +61,7 @@ namespace gl { gl::buffer pbo_depth; - __glcheck pbo_depth.create(info->pitch * info->height); + __glcheck pbo_depth.create(info->size()); __glcheck pbo_depth.map([&](GLubyte* pixels) { switch (info->format.bpp) @@ -153,6 +153,15 @@ namespace gl __glcheck glTexSubImage2D((GLenum)info->target, 0, 0, 0, info->width, info->height, (GLenum)info->format.format, (GLenum)info->format.type, pixels); } + + if (info->mipmap > 1) + { + __glcheck glTexParameteri((GLenum)info->target, GL_TEXTURE_MIN_LOD, info->min_lod); + __glcheck glTexParameteri((GLenum)info->target, GL_TEXTURE_MAX_LOD, info->max_lod); + __glcheck glTexParameterf((GLenum)info->target, GL_TEXTURE_LOD_BIAS, info->lod_bias); + + __glcheck glGenerateMipmap((GLenum)info->target); + } } ignore(gl::cache_buffers::all); @@ -168,17 +177,17 @@ namespace gl gl::buffer pbo_depth; - pbo_depth.create(info->pitch * info->height); + pbo_depth.create(info->size()); gl::pixel_pack_settings{} .row_length(info->pitch / info->format.bpp) .aligment(1) - .swap_bytes((info->format.flags & gl::texture_flags::swap_bytes) != gl::texture_flags::none) + //.swap_bytes((info->format.flags & gl::texture_flags::swap_bytes) != gl::texture_flags::none) .apply(); - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_depth.id()); + __glcheck glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_depth.id()); __glcheck glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, nullptr); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + __glcheck glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); __glcheck pbo_depth.map([&](GLubyte* pixels) { @@ -369,7 +378,7 @@ namespace gl glGenTextures(1, &gl_name); bind(); - __glcheck glTexStorage2D((GLenum)info->target, 1, (GLenum)info->format.internal_format, info->width, info->height); + __glcheck glTexStorage2D((GLenum)info->target, info->mipmap, (GLenum)info->format.internal_format, info->width, info->height); //__glcheck glClearTexImage(gl_name, 0, (GLenum)info->format.format, (GLenum)info->format.type, nullptr); } diff --git a/rpcs3/Emu/RSX/GL/gl_texture_cache.h b/rpcs3/Emu/RSX/GL/gl_texture_cache.h index 0116b1ae84..3932ba1a63 100644 --- a/rpcs3/Emu/RSX/GL/gl_texture_cache.h +++ b/rpcs3/Emu/RSX/GL/gl_texture_cache.h @@ -63,9 +63,11 @@ namespace gl texture::target target; texture_format format; - rsx::surface_antialiasing antialiasing; + u8 mipmap; + u8 min_lod; + u8 max_lod; bool swizzled; - + float lod_bias; u32 start_address; u32 size() const diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index 9ac54f79df..8c48d94568 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -177,6 +177,10 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex) info.start_address = rsx::get_address(tex.offset(), tex.location()); info.swizzled = is_swizzled; info.target = target; + info.mipmap = target != gl::texture::target::texture_rectangle ? tex.mipmap() : 1; + info.min_lod = tex.min_lod() >> 8; + info.max_lod = tex.max_lod() >> 8; + info.lod_bias = tex.bias(); if (is_compressed) { @@ -226,8 +230,6 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex) __glcheck cache.entry(info, gl::cache_buffers::local).bind(tex.index()); - __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1); - if ((info.format.flags & gl::texture_flags::allow_remap) != gl::texture_flags::none) { u8 remap_a = tex.remap() & 0x3; @@ -254,21 +256,8 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex) __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]); - __glcheck glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (GLint)tex.bias()); - __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]); __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]); __glcheck glTexParameterf((GLenum)target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso())); - - if (target != gl::texture::target::texture_rectangle) - { - __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); - __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); - - if (tex.mipmap() > 1) - { - __glcheck glGenerateMipmap((GLenum)target); - } - } }