Fixed depth surface size

Improved mipmap support
Minor fixes
This commit is contained in:
DHrpcs3 2016-03-12 21:43:32 +03:00
parent 44341895ae
commit 8aeac09741
4 changed files with 95 additions and 74 deletions

View file

@ -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();

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}
}
}