diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 6b748f586e..790c177138 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -31,21 +31,69 @@ namespace throw EXCEPTION("Unknow depth format"); } - u32 to_gl_internal_type(rsx::vertex_base_type type, u8 size) + gl::texture::sized_internal_format to_gl_internal_type(rsx::vertex_base_type type, u8 size) { /** * The buffer texture spec only allows fetches aligned to 8, 16, 32, etc... * This rules out most 3-component formats, except for the 32-wide RGB32F, RGB32I, RGB32UI */ - const u32 vec1_types[] = { GL_R16, GL_R32F, GL_R16F, GL_R8, GL_R16I, GL_R16, GL_R8UI }; - const u32 vec2_types[] = { GL_RG16, GL_RG32F, GL_RG16F, GL_RG8, GL_RG16I, GL_RG16, GL_RG8UI }; - const u32 vec3_types[] = { GL_RGBA16, GL_RGB32F, GL_RGBA16F, GL_RGBA8, GL_RGBA16I, GL_RGBA16, GL_RGBA8UI }; //VEC3 COMPONENTS NOT SUPPORTED! - const u32 vec4_types[] = { GL_RGBA16, GL_RGBA32F, GL_RGBA16F, GL_RGBA8, GL_RGBA16I, GL_RGBA16, GL_RGBA8UI }; + static const gl::texture::sized_internal_format vec1_types[] + { + gl::texture::sized_internal_format::r16, + gl::texture::sized_internal_format::r32f, + gl::texture::sized_internal_format::r16f, + gl::texture::sized_internal_format::r8, + gl::texture::sized_internal_format::r16i, + gl::texture::sized_internal_format::r16, + gl::texture::sized_internal_format::r8ui + }; - const u32* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types }; + static const gl::texture::sized_internal_format vec2_types[] + { + gl::texture::sized_internal_format::rg16, + gl::texture::sized_internal_format::rg32f, + gl::texture::sized_internal_format::rg16f, + gl::texture::sized_internal_format::rg8, + gl::texture::sized_internal_format::rg16i, + gl::texture::sized_internal_format::rg16, + gl::texture::sized_internal_format::rg8ui + }; + + static const gl::texture::sized_internal_format vec3_types[] //VEC3 COMPONENTS NOT SUPPORTED! + { + gl::texture::sized_internal_format::rgba16, + gl::texture::sized_internal_format::rgb32f, + gl::texture::sized_internal_format::rgba16f, + gl::texture::sized_internal_format::rgba8, + gl::texture::sized_internal_format::rgba16i, + gl::texture::sized_internal_format::rgba16, + gl::texture::sized_internal_format::rgba8ui + }; + + static const gl::texture::sized_internal_format vec4_types[] + { + gl::texture::sized_internal_format::rgba16, + gl::texture::sized_internal_format::rgba32f, + gl::texture::sized_internal_format::rgba16f, + gl::texture::sized_internal_format::rgba8, + gl::texture::sized_internal_format::rgba16i, + gl::texture::sized_internal_format::rgba16, + gl::texture::sized_internal_format::rgba8ui + }; + + static const gl::texture::sized_internal_format* vec_selectors[] + { + nullptr, + vec1_types, + vec2_types, + vec3_types, + vec4_types + }; if (type > rsx::vertex_base_type::ub256) + { throw EXCEPTION("OpenGL error: unknown vertex base type 0x%X.", (u32)type); + } return vec_selectors[size][(int)type]; } @@ -189,9 +237,9 @@ void GLGSRender::begin() if (u32 blend_mrt = rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT]) { - __glcheck enable(blend_mrt & 2, GL_BLEND, GL_COLOR_ATTACHMENT1); - __glcheck enable(blend_mrt & 4, GL_BLEND, GL_COLOR_ATTACHMENT2); - __glcheck enable(blend_mrt & 8, GL_BLEND, GL_COLOR_ATTACHMENT3); + __glcheck enable(blend_mrt & 2, GL_BLEND, 1); + __glcheck enable(blend_mrt & 4, GL_BLEND, 2); + __glcheck enable(blend_mrt & 8, GL_BLEND, 3); } if (__glcheck enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP)) @@ -347,7 +395,7 @@ namespace case rsx::vertex_base_type::ub: return gl::buffer_pointer::type::u8; case rsx::vertex_base_type::s32k: return gl::buffer_pointer::type::s32; case rsx::vertex_base_type::cmp: return gl::buffer_pointer::type::s16; // Needs conversion - case rsx::vertex_base_type::ub256: gl::buffer_pointer::type::u8; + case rsx::vertex_base_type::ub256: return gl::buffer_pointer::type::u8; } throw EXCEPTION("unknow vertex type"); } @@ -389,7 +437,7 @@ void GLGSRender::end() int location; if (m_program->uniforms.has_location("tex" + std::to_string(i), &location)) { - __glcheck rsx::gl_texture::bind(m_texture_cache, i, textures[i]); + __glcheck rsx::gl_texture::bind(m_texture_cache, textures[i]); __glcheck glProgramUniform1i(m_program->id(), location, i); } } @@ -472,7 +520,7 @@ void GLGSRender::end() const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size); u32 data_size = element_size * vertex_draw_count; - u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); + gl::texture::sized_internal_format gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); auto &buffer = m_gl_attrib_buffers[index].buffer; auto &texture = m_gl_attrib_buffers[index].texture; @@ -530,7 +578,7 @@ void GLGSRender::end() if (!enabled) { glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count); - glBindTexture(GL_TEXTURE_BUFFER, NULL); + glBindTexture(GL_TEXTURE_BUFFER, 0); glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count); continue; } @@ -573,16 +621,11 @@ void GLGSRender::end() vertex_arrays_offsets[index] = gsl::narrow(position); vertex_arrays_data.resize(position + size); - u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); - u32 data_size = element_size * vertex_draw_count; + gl::texture::sized_internal_format gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); auto& attrib_pair = m_gl_attrib_buffers[index]; - __glcheck 0; - - attrib_pair.buffer.data(data_size, vertex_array.data()); - - __glcheck 0; + attrib_pair.buffer.data(vertex_array.size(), vertex_array.data()); //Attach buffer to texture attrib_pair.texture.copy_from(attrib_pair.buffer, gl_type); @@ -601,12 +644,11 @@ void GLGSRender::end() case rsx::vertex_base_type::f: { const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size); - const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); - const size_t data_size = vertex_data.size(); + gl::texture::sized_internal_format gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); auto& attrib_pair = m_gl_attrib_buffers[index]; - attrib_pair.buffer.data(data_size, vertex_data.data()); + attrib_pair.buffer.data(vertex_data.size(), vertex_data.data()); //Attach buffer to texture attrib_pair.texture.copy_from(attrib_pair.buffer, gl_type); @@ -623,7 +665,7 @@ void GLGSRender::end() else { glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count); - glBindTexture(GL_TEXTURE_BUFFER, NULL); + glBindTexture(GL_TEXTURE_BUFFER, 0); glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count); continue; } @@ -1080,7 +1122,7 @@ u32 surface_format_to_texture_format(rsx::surface_color_format format) gl::texture_info surface_info(rsx::surface_color_format format, u32 offset, u32 location, u32 width, u32 height, u32 pitch) { - gl::texture_info info; + gl::texture_info info{}; info.width = width; info.height = height; @@ -1089,6 +1131,8 @@ gl::texture_info surface_info(rsx::surface_color_format format, u32 offset, u32 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.format = gl::get_texture_format(surface_format_to_texture_format(format)); @@ -1144,7 +1188,7 @@ void GLGSRender::init_buffers(bool skip_reading) u32 location = rsx::method_registers[mr_color_dma[index]]; u32 pitch = rsx::method_registers[mr_color_pitch[index]]; - if (!location) + if (pitch <= 64) { cached_color_buffers[index] = nullptr; draw_fbo.color[index] = null_texture; @@ -1162,14 +1206,14 @@ void GLGSRender::init_buffers(bool skip_reading) u32 location = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]; u32 pitch = rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z]; - if (!location) + if (pitch <= 64) { cached_depth_buffer = nullptr; draw_fbo.depth_stencil = null_texture; } else { - gl::texture_info info; + gl::texture_info info{}; info.width = m_surface.width; info.height = m_surface.height; @@ -1179,6 +1223,8 @@ void GLGSRender::init_buffers(bool skip_reading) info.compressed_size = 0; info.start_address = rsx::get_address(offset, location); info.target = gl::texture::target::texture2D; + //TODO + info.swizzled = false; switch (m_surface.depth_format) { @@ -1203,24 +1249,24 @@ void GLGSRender::init_buffers(bool skip_reading) } info.format.remap = { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO }; - - cached_depth_buffer = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local); + __glcheck 0; + __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: - draw_fbo.depth = cached_depth_buffer->view(); + __glcheck draw_fbo.depth = cached_depth_buffer->view(); break; case rsx::surface_depth_format::z24s8: - draw_fbo.depth_stencil = cached_depth_buffer->view(); + __glcheck draw_fbo.depth_stencil = cached_depth_buffer->view(); break; } } } - draw_fbo.bind(); + __glcheck draw_fbo.bind(); { auto info = rsx::get_active_color_surfaces(); @@ -1233,7 +1279,7 @@ void GLGSRender::init_buffers(bool skip_reading) GL_COLOR_ATTACHMENT3 }; - glDrawBuffers(info.second, color_buffers + info.first); + __glcheck glDrawBuffers(info.second, color_buffers + info.first); } set_viewport(); @@ -1323,7 +1369,7 @@ bool GLGSRender::on_access_violation(u32 address, bool is_writing) { if (auto region = m_texture_cache.find_region(address)) { - std::lock_guard lock(*region); + //std::lock_guard lock(*region); if (is_writing) { diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 66fd2f3efe..ca90322c65 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -173,6 +173,10 @@ OPENGL_PROC(PFNGLTEXTUREBUFFERRANGEEXTPROC, TextureBufferRangeEXT); OPENGL_PROC(PFNGLTEXSTORAGE1DPROC, TexStorage1D); OPENGL_PROC(PFNGLTEXSTORAGE2DPROC, TexStorage2D); OPENGL_PROC(PFNGLTEXSTORAGE3DPROC, TexStorage3D); +OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, CompressedTexSubImage1D); +OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, CompressedTexSubImage2D); +OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, CompressedTexSubImage3D); +OPENGL_PROC(PFNGLCLEARTEXIMAGEPROC, ClearTexImage); //ARB_Copy_Image OPENGL_PROC(PFNGLCOPYIMAGESUBDATAPROC, CopyImageSubData); diff --git a/rpcs3/Emu/RSX/GL/gl_helpers.h b/rpcs3/Emu/RSX/GL/gl_helpers.h index 19b0c67443..2d210ee507 100644 --- a/rpcs3/Emu/RSX/GL/gl_helpers.h +++ b/rpcs3/Emu/RSX/GL/gl_helpers.h @@ -810,6 +810,7 @@ namespace gl r32f = GL_R32F, r8ui = GL_R8UI, r8i = GL_R8I, + r16 = GL_R16, r16ui = GL_R16UI, r16i = GL_R16I, r32ui = GL_R32UI, @@ -820,6 +821,7 @@ namespace gl rg32f = GL_RG32F, rg8ui = GL_RG8UI, rg8i = GL_RG8I, + rg16 = GL_RG16, rg16ui = GL_RG16UI, rg16i = GL_RG16I, rg32ui = GL_RG32UI, @@ -830,6 +832,7 @@ namespace gl rgb8_snorm = GL_RGB8_SNORM, r11f_g11f_b10f = GL_R11F_G11F_B10F, rgb9_e5 = GL_RGB9_E5, + rgb16 = GL_RGB16, rgb16f = GL_RGB16F, rgb32f = GL_RGB32F, rgb8ui = GL_RGB8UI, @@ -849,6 +852,7 @@ namespace gl rgba8ui = GL_RGBA8UI, rgba8i = GL_RGBA8I, rgb10_a2ui = GL_RGB10_A2UI, + rgba16 = GL_RGBA16, rgba16ui = GL_RGBA16UI, rgba16i = GL_RGBA16I, rgba32i = GL_RGBA32I, @@ -1203,27 +1207,27 @@ namespace gl __glcheck glTexSubImage2D((GLenum)get_target(), level(), 0, 0, width(), height(), (GLenum)format, (GLenum)type, src); } - void copy_from(buffer &buf, u32 gl_format_type, u32 offset, u32 length) + void copy_from(const buffer &buf, gl::texture::sized_internal_format format, u32 offset, u32 length) { if (get_target() != target::texture_buffer) throw EXCEPTION("OpenGL error: texture cannot copy from buffer"); if (!offset) { - copy_from(buf, gl_format_type); + copy_from(buf, format); return; } if (glTextureBufferRangeEXT == nullptr) throw EXCEPTION("OpenGL error: partial buffer access for textures is unsupported on your system"); - __glcheck glTextureBufferRangeEXT(id(), (GLenum)target::texture_buffer, gl_format_type, buf.id(), offset, length); + __glcheck glTextureBufferRangeEXT(id(), (GLenum)target::texture_buffer, (GLenum)format, buf.id(), offset, length); } - void copy_from(buffer &buf, u32 gl_format_type) + void copy_from(const buffer &buf, gl::texture::sized_internal_format format) { save_binding_state save(*this); - __glcheck glTexBuffer((GLenum)target::texture_buffer, gl_format_type, buf.id()); + __glcheck glTexBuffer((GLenum)target::texture_buffer, (GLenum)format, buf.id()); } void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings) diff --git a/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp b/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp index 5a9e82c9c9..76395d781a 100644 --- a/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp +++ b/rpcs3/Emu/RSX/GL/gl_texture_cache.cpp @@ -3,6 +3,7 @@ #include "gl_texture_cache.h" #include "GLGSRender.h" #include "../Common/TextureUtils.h" +#include "../rsx_utils.h" #include #include @@ -40,9 +41,7 @@ namespace gl if (found_texture) { //read from local - LOG_WARNING(RSX, "cached_texture at 0x%x reading from local buffer", info->start_address); - - glCopyImageSubData( + __glcheck glCopyImageSubData( found_texture->gl_name, (GLenum)found_texture->info->target, 0, 0, 0, 0, gl_name, (GLenum)info->target, 0, 0, 0, 0, info->width, info->height, info->depth); @@ -60,23 +59,92 @@ namespace gl if (info->format.format == gl::texture::format::depth || info->format.format == gl::texture::format::depth_stencil) { - LOG_ERROR(RSX, "cached_texture at 0x%x: unimplemented reading depth(stencil) from host buffer", info->start_address); + gl::buffer pbo_depth; - //TODO + __glcheck pbo_depth.create(info->pitch * info->height); + __glcheck pbo_depth.map([&](GLubyte* pixels) + { + switch (info->format.bpp) + { + case 2: + { + u16 *dst = (u16*)pixels; + const be_t* src = (const be_t*)vm::base_priv(info->start_address); + for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i) + { + dst[i] = src[i]; + } + } + break; + + case 4: + { + u32 *dst = (u32*)pixels; + const be_t* src = (const be_t*)vm::base_priv(info->start_address); + for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i) + { + dst[i] = src[i]; + } + } + break; + + default: + throw EXCEPTION(""); + } + }, gl::buffer::access::write); + + gl::pixel_unpack_settings{} + .row_length(info->pitch / info->format.bpp) + .aligment(1) + .swap_bytes((info->format.flags & gl::texture_flags::swap_bytes) != gl::texture_flags::none) + .apply(); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_depth.id()); + + __glcheck 0; + + __glcheck glTexSubImage2D((GLenum)info->target, 0, 0, 0, info->width, info->height, + (GLenum)info->format.format, (GLenum)info->format.type, nullptr); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } else if (info->compressed_size) { - LOG_WARNING(RSX, "cached_texture at 0x%x: reading compressed texture from host buffer", info->start_address); - - __glcheck glCompressedTexImage2D((GLenum)info->target, 0, + __glcheck glCompressedTexSubImage2D((GLenum)info->target, 0, + 0, 0, info->width, info->height, (GLenum)info->format.internal_format, - info->width, info->height, - 0, info->compressed_size, vm::base_priv(info->start_address)); } else { - LOG_WARNING(RSX, "cached_texture at 0x%x reading from host buffer", info->start_address); + void *pixels = vm::base_priv(info->start_address); + + std::unique_ptr linear_pixels; + + if (info->swizzled && (info->format.flags & texture_flags::allow_swizzle) != texture_flags::none) + { + linear_pixels.reset(new u8[info->size()]); + switch (info->format.bpp) + { + case 1: + rsx::convert_linear_swizzle(pixels, linear_pixels.get(), info->width, info->height, true); + break; + case 2: + rsx::convert_linear_swizzle(pixels, linear_pixels.get(), info->width, info->height, true); + break; + case 4: + rsx::convert_linear_swizzle(pixels, linear_pixels.get(), info->width, info->height, true); + break; + case 8: + rsx::convert_linear_swizzle(pixels, linear_pixels.get(), info->width, info->height, true); + break; + + default: + throw EXCEPTION(""); + } + + pixels = linear_pixels.get(); + } gl::pixel_unpack_settings{} .row_length(info->pitch / info->format.bpp) @@ -85,7 +153,7 @@ namespace gl .apply(); __glcheck glTexSubImage2D((GLenum)info->target, 0, 0, 0, info->width, info->height, - (GLenum)info->format.format, (GLenum)info->format.type, vm::base_priv(info->start_address)); + (GLenum)info->format.format, (GLenum)info->format.type, pixels); } } @@ -94,15 +162,55 @@ namespace gl void cached_texture::write() { - LOG_WARNING(RSX, "cached_texture at 0x%x writing to host buffer", info->start_address); - bind(); if (info->format.format == gl::texture::format::depth || info->format.format == gl::texture::format::depth_stencil) { - LOG_ERROR(RSX, "cached_texture at 0x%x: unimplemented writing depth(stencil) to host buffer", info->start_address); + gl::buffer pbo_depth; - //TODO + pbo_depth.create(info->pitch * info->height); + + 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) + .apply(); + + 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 pbo_depth.map([&](GLubyte* pixels) + { + switch (info->format.bpp) + { + case 2: + { + const u16 *src = (const u16*)pixels; + be_t* dst = (be_t*)vm::base_priv(info->start_address); + for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i) + { + dst[i] = src[i]; + } + } + break; + + case 4: + { + const u32 *src = (const u32*)pixels; + be_t* dst = (be_t*)vm::base_priv(info->start_address); + for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i) + { + dst[i] = src[i]; + } + } + break; + + default: + throw EXCEPTION(""); + } + + }, gl::buffer::access::read); } else if (info->compressed_size) { @@ -110,13 +218,19 @@ namespace gl } else { + if (info->swizzled && (info->format.flags & texture_flags::allow_swizzle) != texture_flags::none) + { + //TODO + LOG_ERROR(RSX, "writing swizzled texture[0x%x] to host buffer", info->start_address); + } + 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) .apply(); - glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, vm::base_priv(info->start_address)); + __glcheck glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, vm::base_priv(info->start_address)); } ignore(gl::cache_buffers::all); @@ -126,7 +240,7 @@ namespace gl { if (!created()) { - create(); + __glcheck create(); } switch (m_state) @@ -135,7 +249,7 @@ namespace gl case cache_entry_state::host_synchronized: if ((buffers & cache_buffers::local) != cache_buffers::none) { - read(); + __glcheck read(); return true; } break; @@ -254,11 +368,9 @@ namespace gl glGenTextures(1, &gl_name); - if (!info->compressed_size) - { - bind(); - __glcheck glTexStorage2D((GLenum)info->target, 1, (GLenum)info->format.internal_format, info->width, info->height); - } + bind(); + __glcheck glTexStorage2D((GLenum)info->target, 1, (GLenum)info->format.internal_format, info->width, info->height); + //__glcheck glClearTexImage(gl_name, 0, (GLenum)info->format.format, (GLenum)info->format.type, nullptr); } void cached_texture::remove() @@ -331,7 +443,7 @@ namespace gl if (m_current_protection != flags) { - LOG_WARNING(RSX, "protection region [0x%x, 0x%x)", start_address, start_address + size()); + LOG_WARNING(RSX, "protected region [0x%x, 0x%x)", start_address, start_address + size()); vm::page_protect(start_address, size(), 0, m_current_protection & ~flags, flags); m_current_protection = flags; } @@ -449,8 +561,31 @@ namespace gl cached_texture &texture_cache::entry(const texture_info &info, cache_buffers sync) { - u32 aligned_address = info.start_address & ~(vm::page_size - 1); - u32 aligned_size = align(info.size(), vm::page_size); + //u32 aligned_address = info.start_address & ~(vm::page_size - 1); + u32 aligned_address; + u32 aligned_size; + + const bool accurate_cache = false; + + if (accurate_cache) + { + aligned_address = info.start_address & ~(vm::page_size - 1); + aligned_size = align(info.start_address - aligned_address + info.size(), vm::page_size); + } + else + { + aligned_size = info.size() & ~(vm::page_size - 1); + + if (!aligned_size) + { + aligned_address = info.start_address & ~(vm::page_size - 1); + aligned_size = align(info.size() + info.start_address - aligned_address, vm::page_size); + } + else + { + aligned_address = align(info.start_address, vm::page_size); + } + } std::vector regions = find_regions(aligned_address, aligned_size); protected_region *region; diff --git a/rpcs3/Emu/RSX/GL/gl_texture_cache.h b/rpcs3/Emu/RSX/GL/gl_texture_cache.h index bebfbf4bac..bb4a3ec365 100644 --- a/rpcs3/Emu/RSX/GL/gl_texture_cache.h +++ b/rpcs3/Emu/RSX/GL/gl_texture_cache.h @@ -2,6 +2,7 @@ #include #include "Utilities/types.h" #include "gl_helpers.h" +#include namespace gl { @@ -63,6 +64,7 @@ namespace gl texture::target target; texture_format format; + bool swizzled; u32 start_address; diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index 1b6f2d8487..564322b0ab 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -136,7 +136,7 @@ int wrap(int wrap) } -void rsx::gl_texture::bind(gl::texture_cache& cache, int index, rsx::texture& tex) +void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex) { u32 full_format = tex.format(); u32 format = full_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); @@ -145,7 +145,7 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, int index, rsx::texture& te gl::texture::target target = is_normalized ? gl::texture::target::texture2D : gl::texture::target::texture_rectangle; - glActiveTexture(GL_TEXTURE0 + index); + glActiveTexture(GL_TEXTURE0 + tex.index()); gl::texture_view(target, 0).bind(); if (!tex.enabled()) @@ -166,6 +166,7 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, int index, rsx::texture& te info.dimension = tex.dimension(); info.start_address = rsx::get_address(tex.offset(), tex.location()); info.target = target; + info.swizzled = is_swizzled; if (is_compressed) { @@ -218,7 +219,7 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, int index, rsx::texture& te remap = info.format.remap.data(); } - __glcheck cache.entry(info, gl::cache_buffers::local).bind(index); + __glcheck cache.entry(info, gl::cache_buffers::local).bind(tex.index()); __glcheck glTexParameteri((GLenum)target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1); __glcheck glTexParameteri((GLenum)target, GL_GENERATE_MIPMAP, tex.mipmap() > 1); diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.h b/rpcs3/Emu/RSX/GL/rsx_gl_texture.h index 17855d1af3..7f70128134 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.h +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.h @@ -18,7 +18,7 @@ namespace rsx namespace gl_texture { - void bind(gl::texture_cache& cache, int index, rsx::texture& tex); + void bind(gl::texture_cache& cache, rsx::texture& tex); } } diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index dd4bfba429..bf6c4fbec3 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -210,6 +210,11 @@ namespace rsx return method_registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] & 0xfffff; } + u8 texture::index() const + { + return m_index; + } + void vertex_texture::init(u8 index) { m_index = index; @@ -393,4 +398,9 @@ namespace rsx { return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] & 0xfffff; } + + u8 vertex_texture::index() const + { + return m_index; + } } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 14b2843403..86359c4761 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -561,7 +561,10 @@ namespace rsx else { ++m_internal_task_waiters; - add_internal_task(callback).wait(); + while (add_internal_task(callback).wait_for(1s) == std::future_status::timeout) + { + CHECK_EMU_STATUS; + } --m_internal_task_waiters; } } @@ -737,6 +740,9 @@ namespace rsx method_registers[NV4097_SET_BLEND_COLOR2] = 0; method_registers[NV4097_SET_BLEND_EQUATION] = (CELL_GCM_FUNC_ADD << 16) | CELL_GCM_FUNC_ADD; + method_registers[NV4097_SET_STENCIL_TEST_ENABLE] = false; + method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; + method_registers[NV4097_SET_STENCIL_MASK] = 0xff; method_registers[NV4097_SET_STENCIL_FUNC] = CELL_GCM_ALWAYS; method_registers[NV4097_SET_STENCIL_FUNC_REF] = 0x00;