diff --git a/src/video_core/rasterizer_cache/cached_surface.cpp b/src/video_core/rasterizer_cache/cached_surface.cpp index a8ee5349a..d38ef0254 100644 --- a/src/video_core/rasterizer_cache/cached_surface.cpp +++ b/src/video_core/rasterizer_cache/cached_surface.cpp @@ -337,17 +337,21 @@ void CachedSurface::UploadGLTexture(Common::Rectangle rect) { const Common::Rectangle from_rect{0, height, width, 0}; if (is_custom || !owner.texture_filterer->Filter(unscaled_tex, from_rect, texture, scaled_rect, type)) { - const Subresource src_subresource = { - .type = type, - .region = from_rect + const TextureBlit texture_blit = { + .surface_type = type, + .src_level = 0, + .dst_level = 0, + .src_region = Region2D{ + .start = {0, 0}, + .end = {width, height} + }, + .dst_region = Region2D{ + .start = {rect.left, rect.bottom}, + .end = {rect.right, rect.top} + } }; - const Subresource dst_subresource = { - .type = type, - .region = scaled_rect - }; - - runtime.BlitTextures(unscaled_tex, src_subresource, texture, dst_subresource); + runtime.BlitTextures(unscaled_tex, texture, texture_blit); } } @@ -363,8 +367,10 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle& rect) { MICROPROFILE_SCOPE(RasterizerCache_TextureDL); + const u32 download_size = width * height * GetBytesPerPixel(pixel_format); + if (gl_buffer.empty()) { - gl_buffer.resize(width * height * GetBytesPerPixel(pixel_format)); + gl_buffer.resize(download_size); } OpenGLState state = OpenGLState::GetCurState(); @@ -374,10 +380,7 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle& rect) { // Ensure no bad interactions with GL_PACK_ALIGNMENT ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0); glPixelStorei(GL_PACK_ROW_LENGTH, static_cast(stride)); - const std::size_t buffer_offset = - (rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format); - - const FormatTuple& tuple = GetFormatTuple(pixel_format); + const u32 buffer_offset = (rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format); // If not 1x scale, blit scaled texture to a new 1x texture and use that to flush if (res_scale != 1) { @@ -390,23 +393,29 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle& rect) { const Common::Rectangle unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0}; auto unscaled_tex = owner.AllocateSurfaceTexture(pixel_format, rect.GetWidth(), rect.GetHeight()); - const Subresource src_subresource = { - .type = type, - .region = scaled_rect - }; - - const Subresource dst_subresource = { - .type = type, - .region = unscaled_tex_rect + const TextureBlit texture_blit = { + .surface_type = type, + .src_level = 0, + .dst_level = 0, + .src_region = Region2D{ + .start = {scaled_rect.left, scaled_rect.bottom}, + .end = {scaled_rect.right, scaled_rect.top} + }, + .dst_region = Region2D{ + .start = {unscaled_tex_rect.left, unscaled_tex_rect.bottom}, + .end = {unscaled_tex_rect.right, unscaled_tex_rect.top} + } }; // Blit scaled texture to the unscaled one - runtime.BlitTextures(texture, src_subresource, unscaled_tex, dst_subresource); + runtime.BlitTextures(texture, unscaled_tex, texture_blit); state.texture_units[0].texture_2d = unscaled_tex.handle; state.Apply(); glActiveTexture(GL_TEXTURE0); + + const FormatTuple& tuple = GetFormatTuple(pixel_format); if (GLES) { owner.texture_downloader_es->GetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, rect.GetHeight(), rect.GetWidth(), @@ -415,12 +424,18 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle& rect) { glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, &gl_buffer[buffer_offset]); } } else { - const Subresource subresource = { - .type = type, - .region = rect + const BufferTextureCopy texture_download = { + .buffer_offset = buffer_offset, + .buffer_size = download_size, + .buffer_row_length = stride, + .buffer_height = height, + .surface_type = type, + .texture_level = 0, + .texture_offset = {rect.bottom, rect.left}, + .texture_extent = {rect.GetWidth(), rect.GetHeight()} }; - runtime.ReadTexture(texture, subresource, tuple, (u8*)gl_buffer.data()); + runtime.ReadTexture(texture, texture_download, pixel_format, gl_buffer); } glPixelStorei(GL_PACK_ROW_LENGTH, 0); diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.cpp b/src/video_core/rasterizer_cache/rasterizer_cache.cpp index 70c4d899c..9cfb26620 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.cpp +++ b/src/video_core/rasterizer_cache/rasterizer_cache.cpp @@ -49,11 +49,7 @@ void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval); ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface); - const Subresource dst_subresource = { - .type = dst_surface->type, - .region = dst_surface->GetScaledSubRect(subrect_params) - }; - + const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params); if (src_surface->type == SurfaceType::Fill) { // FillSurface needs a 4 bytes buffer const u32 fill_offset = @@ -68,18 +64,36 @@ void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst const ClearValue clear_value = MakeClearValue(dst_surface->type, dst_surface->pixel_format, fill_buffer.data()); - runtime.ClearTexture(dst_surface->texture, dst_subresource, clear_value); + const ClearRect clear_rect = { + .surface_type = dst_surface->type, + .texture_level = 0, + .rect = Rect2D{ + .offset = {dst_rect.left, dst_rect.bottom}, + .extent = {dst_rect.GetWidth(), dst_rect.GetHeight()} + } + }; + + runtime.ClearTexture(dst_surface->texture, clear_rect, clear_value); return; } if (src_surface->CanSubRect(subrect_params)) { - const Subresource src_subresource = { - .type = src_surface->type, - .region = src_surface->GetScaledSubRect(subrect_params) + const auto src_rect = src_surface->GetScaledSubRect(subrect_params); + const TextureBlit texture_blit = { + .surface_type = src_surface->type, + .src_level = 0, + .dst_level = 0, + .src_region = Region2D{ + .start = {src_rect.left, src_rect.bottom}, + .end = {src_rect.right, src_rect.top} + }, + .dst_region = Region2D{ + .start = {dst_rect.left, dst_rect.bottom}, + .end = {dst_rect.right, dst_rect.top} + } }; - runtime.BlitTextures(src_surface->texture, src_subresource, dst_surface->texture, - dst_subresource); + runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit); return; } @@ -210,18 +224,21 @@ bool RasterizerCache::BlitSurfaces(const Surface& src_surface, if (CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) { dst_surface->InvalidateAllWatcher(); - const Subresource src_subresource = { - .type = src_surface->type, - .region = src_rect + const TextureBlit texture_blit = { + .surface_type = src_surface->type, + .src_level = 0, + .dst_level = 0, + .src_region = Region2D{ + .start = {src_rect.left, src_rect.bottom}, + .end = {src_rect.right, src_rect.top} + }, + .dst_region = Region2D{ + .start = {dst_rect.left, dst_rect.bottom}, + .end = {dst_rect.right, dst_rect.top} + } }; - const Subresource dst_subresource = { - .type = dst_surface->type, - .region = dst_rect - }; - - return runtime.BlitTextures(src_surface->texture, src_subresource, - dst_surface->texture, dst_subresource); + return runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit); } return false; @@ -441,19 +458,23 @@ Surface RasterizerCache::GetTextureSurface(const Pica::Texture::TextureInfo& inf } if (!surface->is_custom && texture_filterer->IsNull()) { - const Subresource src_subresource = { - .type = surface->type, - .region = level_surface->GetScaledRect() + const auto src_rect = level_surface->GetScaledRect(); + const auto dst_rect = surface_params.GetScaledRect(); + const TextureBlit texture_blit = { + .surface_type = surface->type, + .src_level = 0, + .dst_level = level, + .src_region = Region2D{ + .start = {src_rect.left, src_rect.bottom}, + .end = {src_rect.right, src_rect.top} + }, + .dst_region = Region2D{ + .start = {dst_rect.left, dst_rect.bottom}, + .end = {dst_rect.right, dst_rect.top} + } }; - const Subresource dst_subresource = { - .type = surface->type, - .region = surface_params.GetScaledRect(), - .level = level - }; - - runtime.BlitTextures(level_surface->texture, src_subresource, - surface->texture, dst_subresource); + runtime.BlitTextures(level_surface->texture, surface->texture, texture_blit); } watcher->Validate(); @@ -530,19 +551,22 @@ const CachedTextureCube& RasterizerCache::GetTextureCube(const TextureCubeConfig ValidateSurface(surface, surface->addr, surface->size); } - const Subresource src_subresource = { - .type = surface->type, - .region = surface->GetScaledRect() + const auto src_rect = surface->GetScaledRect(); + const TextureBlit texture_blit = { + .surface_type = surface->type, + .src_level = 0, + .dst_level = 0, + .src_region = Region2D{ + .start = {src_rect.left, src_rect.bottom}, + .end = {src_rect.right, src_rect.top} + }, + .dst_region = Region2D{ + .start = {0, 0}, + .end = {scaled_size, scaled_size} + } }; - const Subresource dst_subresource = { - .type = surface->type, - .region = Common::Rectangle{0, scaled_size, scaled_size, 0} - }; - - runtime.BlitTextures(surface->texture, src_subresource, - cube.texture, dst_subresource); - + runtime.BlitTextures(surface->texture, cube.texture, texture_blit); face.watcher->Validate(); } } @@ -857,22 +881,24 @@ bool RasterizerCache::ValidateByReinterpretation(const Surface& surface, reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, tmp_tex, tmp_rect); - if (!texture_filterer->Filter(tmp_tex, tmp_rect, surface->texture, dest_rect, - type)) { - - const Subresource src_subresource = { - .type = type, - .region = tmp_rect + if (!texture_filterer->Filter(tmp_tex, tmp_rect, surface->texture, dest_rect, type)) { + const TextureBlit texture_blit = { + .surface_type = type, + .src_level = 0, + .dst_level = 0, + .src_region = Region2D{ + .start = {0, 0}, + .end = {width, height} + }, + .dst_region = Region2D{ + .start = {dest_rect.left, dest_rect.bottom}, + .end = {dest_rect.right, dest_rect.top} + } }; - const Subresource dst_subresource = { - .type = type, - .region = dest_rect - }; - - runtime.BlitTextures(tmp_tex, src_subresource, - surface->texture, dst_subresource); + runtime.BlitTextures(tmp_tex, surface->texture, texture_blit); } + } else { reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, surface->texture, dest_rect); diff --git a/src/video_core/rasterizer_cache/texture_runtime.cpp b/src/video_core/rasterizer_cache/texture_runtime.cpp index c73f28ef0..5f5b3d1c4 100644 --- a/src/video_core/rasterizer_cache/texture_runtime.cpp +++ b/src/video_core/rasterizer_cache/texture_runtime.cpp @@ -31,70 +31,69 @@ TextureRuntime::TextureRuntime() { draw_fbo.Create(); } -void TextureRuntime::ReadTexture(const OGLTexture& tex, Subresource subresource, - const FormatTuple& tuple, u8* pixels) { +void TextureRuntime::ReadTexture(OGLTexture& texture, const BufferTextureCopy& copy, + PixelFormat format, std::span pixels) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); - OpenGLState state; - state.ResetTexture(tex.handle); + OpenGLState state{}; + state.ResetTexture(texture.handle); state.draw.read_framebuffer = read_fbo.handle; state.Apply(); - const u32 level = subresource.level; - switch (subresource.type) { + switch (copy.surface_type) { case SurfaceType::Color: case SurfaceType::Texture: case SurfaceType::Fill: - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.handle, - level); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.handle, + copy.texture_level); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); break; case SurfaceType::Depth: glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex.handle, - level); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture.handle, + copy.texture_level); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); break; case SurfaceType::DepthStencil: glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - tex.handle, level); + texture.handle, copy.texture_level); break; default: UNREACHABLE_MSG("Invalid surface type!"); } - const auto& rect = subresource.region; - glReadPixels(rect.left, rect.bottom, rect.GetWidth(), rect.GetHeight(), tuple.format, - tuple.type, pixels); + // TODO: Use PBO here + const FormatTuple& tuple = GetFormatTuple(format); + glReadPixels(copy.texture_offset.x, copy.texture_offset.y, + copy.texture_offset.x + copy.texture_extent.width, + copy.texture_offset.y + copy.texture_extent.height, + tuple.format, tuple.type, pixels.data() + copy.buffer_offset); } -bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource, - ClearValue value) { +bool TextureRuntime::ClearTexture(OGLTexture& texture, const ClearRect& rect, ClearValue value) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); // Setup scissor rectangle according to the clear rectangle - const auto& clear_rect = subresource.region; - OpenGLState state; + OpenGLState state{}; state.scissor.enabled = true; - state.scissor.x = clear_rect.left; - state.scissor.y = clear_rect.bottom; - state.scissor.width = clear_rect.GetWidth(); - state.scissor.height = clear_rect.GetHeight(); + state.scissor.x = rect.rect.offset.x; + state.scissor.y = rect.rect.offset.y; + state.scissor.width = rect.rect.extent.width; + state.scissor.height = rect.rect.extent.height; state.draw.draw_framebuffer = draw_fbo.handle; state.Apply(); - const u32 level = subresource.level; - switch (subresource.type) { + switch (rect.surface_type) { case SurfaceType::Color: case SurfaceType::Texture: case SurfaceType::Fill: - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.handle, - level); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.handle, + rect.texture_level); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); @@ -108,8 +107,8 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource break; case SurfaceType::Depth: glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex.handle, - level); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture.handle, + rect.texture_level); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); state.depth.write_mask = GL_TRUE; @@ -120,7 +119,7 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource case SurfaceType::DepthStencil: glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - tex.handle, level); + texture.handle, rect.texture_level); state.depth.write_mask = GL_TRUE; state.stencil.write_mask = -1; @@ -135,50 +134,42 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource return true; } -bool TextureRuntime::CopyTextures(const OGLTexture& src_tex, Subresource src_subresource, - const OGLTexture& dst_tex, Subresource dst_subresource) { +bool TextureRuntime::CopyTextures(OGLTexture& source, OGLTexture& dest, const TextureCopy& copy) { return true; } -bool TextureRuntime::BlitTextures(const OGLTexture& src_tex, Subresource src_subresource, - const OGLTexture& dst_tex, Subresource dst_subresource, - bool dst_cube) { +bool TextureRuntime::BlitTextures(OGLTexture& source, OGLTexture& dest, const TextureBlit& blit) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); - OpenGLState state; + OpenGLState state{}; state.draw.read_framebuffer = read_fbo.handle; state.draw.draw_framebuffer = draw_fbo.handle; state.Apply(); - auto BindAttachment = - [dst_cube, src_level = src_subresource.level, dst_level = dst_subresource.level, - dst_layer = dst_subresource.layer](GLenum target, u32 src_tex, u32 dst_tex) -> void { - GLenum dst_target = dst_cube ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + dst_layer : GL_TEXTURE_2D; - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, target, GL_TEXTURE_2D, src_tex, src_level); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, target, dst_target, dst_tex, dst_level); + auto BindAttachment = [&blit](GLenum target, u32 src_tex, u32 dst_tex) -> void { + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, target, GL_TEXTURE_2D, src_tex, blit.src_level); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, target, GL_TEXTURE_2D, dst_tex, blit.dst_level); }; - // Sanity check; Can't blit a color texture to a depth buffer - ASSERT(src_subresource.type == dst_subresource.type); - switch (src_subresource.type) { + switch (blit.surface_type) { case SurfaceType::Color: case SurfaceType::Texture: case SurfaceType::Fill: // Bind only color - BindAttachment(GL_COLOR_ATTACHMENT0, src_tex.handle, dst_tex.handle); + BindAttachment(GL_COLOR_ATTACHMENT0, source.handle, dest.handle); BindAttachment(GL_DEPTH_STENCIL_ATTACHMENT, 0, 0); break; case SurfaceType::Depth: // Bind only depth BindAttachment(GL_COLOR_ATTACHMENT0, 0, 0); - BindAttachment(GL_DEPTH_ATTACHMENT, src_tex.handle, dst_tex.handle); + BindAttachment(GL_DEPTH_ATTACHMENT, source.handle, dest.handle); BindAttachment(GL_STENCIL_ATTACHMENT, 0, 0); break; case SurfaceType::DepthStencil: // Bind to combined depth + stencil BindAttachment(GL_COLOR_ATTACHMENT0, 0, 0); - BindAttachment(GL_DEPTH_STENCIL_ATTACHMENT, src_tex.handle, dst_tex.handle); + BindAttachment(GL_DEPTH_STENCIL_ATTACHMENT, source.handle, dest.handle); break; default: UNREACHABLE_MSG("Invalid surface type!"); @@ -189,23 +180,23 @@ bool TextureRuntime::BlitTextures(const OGLTexture& src_tex, Subresource src_sub // doing linear intepolation componentwise would cause incorrect value. However, for a // well-programmed game this code path should be rarely executed for shadow map with // inconsistent scale. - const GLbitfield buffer_mask = MakeBufferMask(src_subresource.type); + const GLbitfield buffer_mask = MakeBufferMask(blit.surface_type); const GLenum filter = buffer_mask == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST; - const auto& src_rect = src_subresource.region; - const auto& dst_rect = dst_subresource.region; - glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, dst_rect.left, - dst_rect.bottom, dst_rect.right, dst_rect.top, + glBlitFramebuffer(blit.src_region.start.x, blit.src_region.start.y, + blit.src_region.end.x, blit.src_region.end.y, + blit.dst_region.start.x, blit.dst_region.start.y, + blit.dst_region.end.x, blit.dst_region.end.y, buffer_mask, filter); return true; } -void TextureRuntime::GenerateMipmaps(const OGLTexture& tex, u32 max_level) { +void TextureRuntime::GenerateMipmaps(OGLTexture& texture, u32 max_level) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); - OpenGLState state; - state.texture_units[0].texture_2d = tex.handle; + OpenGLState state{}; + state.texture_units[0].texture_2d = texture.handle; state.Apply(); glActiveTexture(GL_TEXTURE0); diff --git a/src/video_core/rasterizer_cache/texture_runtime.h b/src/video_core/rasterizer_cache/texture_runtime.h index 57822fa3d..801436e59 100644 --- a/src/video_core/rasterizer_cache/texture_runtime.h +++ b/src/video_core/rasterizer_cache/texture_runtime.h @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #pragma once +#include #include "video_core/rasterizer_cache/types.h" #include "video_core/renderer_opengl/gl_resource_manager.h" @@ -19,26 +20,21 @@ public: TextureRuntime(); ~TextureRuntime() = default; - // Copies the GPU pixel data to the provided pixels buffer - void ReadTexture(const OGLTexture& tex, Subresource subresource, const FormatTuple& tuple, - u8* pixels); + /// Copies the GPU pixel data to the provided pixels buffer + void ReadTexture(OGLTexture& texture, const BufferTextureCopy& copy, + PixelFormat format, std::span pixels); - // Fills the rectangle of the texture with the clear value provided - bool ClearTexture(const OGLTexture& texture, Subresource subresource, ClearValue value); + /// Fills the rectangle of the texture with the clear value provided + bool ClearTexture(OGLTexture& texture, const ClearRect& rect, ClearValue value); - // Copies a rectangle of src_tex to another rectange of dst_rect - // NOTE: The width and height of the rectangles must be equal - bool CopyTextures(const OGLTexture& src_tex, Subresource src_subresource, - const OGLTexture& dst_tex, Subresource dst_subresource); + /// Copies a rectangle of src_tex to another rectange of dst_rect + bool CopyTextures(OGLTexture& source, OGLTexture& dest, const TextureCopy& copy); - // Copies a rectangle of src_tex to another rectange of dst_rect performing - // scaling and format conversions - bool BlitTextures(const OGLTexture& src_tex, Subresource src_subresource, - const OGLTexture& dst_tex, Subresource dst_subresource, - bool dst_cube = false); + /// Blits a rectangle of src_tex to another rectange of dst_rect + bool BlitTextures(OGLTexture& source, OGLTexture& dest, const TextureBlit& blit); - // Generates mipmaps for all the available levels of the texture - void GenerateMipmaps(const OGLTexture& tex, u32 max_level); + /// Generates mipmaps for all the available levels of the texture + void GenerateMipmaps(OGLTexture& texture, u32 max_level); private: OGLFramebuffer read_fbo, draw_fbo; diff --git a/src/video_core/rasterizer_cache/types.h b/src/video_core/rasterizer_cache/types.h index 39610f3d3..64159e856 100644 --- a/src/video_core/rasterizer_cache/types.h +++ b/src/video_core/rasterizer_cache/types.h @@ -3,13 +3,40 @@ // Refer to the license.txt file included. #pragma once -#include "common/math_util.h" +#include "common/common_types.h" #include "common/vector_math.h" #include "video_core/rasterizer_cache/pixel_format.h" namespace OpenGL { -// A union for both color and depth/stencil clear values +struct Offset { + constexpr auto operator<=>(const Offset&) const noexcept = default; + + u32 x = 0; + u32 y = 0; +}; + +struct Extent { + constexpr auto operator<=>(const Extent&) const noexcept = default; + + u32 width = 1; + u32 height = 1; +}; + +struct Rect2D { + constexpr auto operator<=>(const Rect2D&) const noexcept = default; + + Offset offset; + Extent extent; +}; + +struct Region2D { + constexpr auto operator<=>(const Region2D&) const noexcept = default; + + Offset start; + Offset end; +}; + union ClearValue { Common::Vec4f color; struct { @@ -18,13 +45,44 @@ union ClearValue { }; }; -struct Subresource { - auto operator<=>(const Subresource&) const = default; +struct ClearRect { + SurfaceType surface_type; + u32 texture_level; + Rect2D rect; +}; - SurfaceType type; - Common::Rectangle region; - u32 level = 0; - u32 layer = 0; +struct TextureCopy { + SurfaceType surface_type; + u32 src_level; + u32 dst_level; + Offset src_offset; + Offset dst_offset; + Extent extent; +}; + +struct TextureBlit { + SurfaceType surface_type; + u32 src_level; + u32 dst_level; + Region2D src_region; + Region2D dst_region; +}; + +struct BufferTextureCopy { + u32 buffer_offset; + u32 buffer_size; + u32 buffer_row_length; + u32 buffer_height; + SurfaceType surface_type; + u32 texture_level; + Offset texture_offset; + Extent texture_extent; +}; + +struct BufferCopy { + u32 src_offset; + u32 dst_offset; + u32 size; }; } // namespace OpenGL