rasterizer_cache: Use Common::Rectangle everywhere
* Make a nice alias for it and use it instead of having Rect2D/Region2D. Makes the new design less intrusive to the current cache
This commit is contained in:
@ -23,21 +23,27 @@ struct Rectangle {
|
|||||||
constexpr Rectangle(T left, T top, T right, T bottom)
|
constexpr Rectangle(T left, T top, T right, T bottom)
|
||||||
: left(left), top(top), right(right), bottom(bottom) {}
|
: left(left), top(top), right(right), bottom(bottom) {}
|
||||||
|
|
||||||
auto operator<=>(const Rectangle&) const = default;
|
constexpr auto operator<=>(const Rectangle&) const = default;
|
||||||
|
constexpr void operator*=(const T value) {
|
||||||
|
left *= value;
|
||||||
|
top *= value;
|
||||||
|
right *= value;
|
||||||
|
bottom *= value;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] T GetWidth() const {
|
[[nodiscard]] constexpr T GetWidth() const {
|
||||||
return std::abs(static_cast<std::make_signed_t<T>>(right - left));
|
return std::abs(static_cast<std::make_signed_t<T>>(right - left));
|
||||||
}
|
}
|
||||||
[[nodiscard]] T GetHeight() const {
|
[[nodiscard]] constexpr T GetHeight() const {
|
||||||
return std::abs(static_cast<std::make_signed_t<T>>(bottom - top));
|
return std::abs(static_cast<std::make_signed_t<T>>(bottom - top));
|
||||||
}
|
}
|
||||||
[[nodiscard]] Rectangle<T> TranslateX(const T x) const {
|
[[nodiscard]] constexpr Rectangle<T> TranslateX(const T x) const {
|
||||||
return Rectangle{left + x, top, right + x, bottom};
|
return Rectangle{left + x, top, right + x, bottom};
|
||||||
}
|
}
|
||||||
[[nodiscard]] Rectangle<T> TranslateY(const T y) const {
|
[[nodiscard]] constexpr Rectangle<T> TranslateY(const T y) const {
|
||||||
return Rectangle{left, top + y, right, bottom + y};
|
return Rectangle{left, top + y, right, bottom + y};
|
||||||
}
|
}
|
||||||
[[nodiscard]] Rectangle<T> Scale(const float s) const {
|
[[nodiscard]] constexpr Rectangle<T> Scale(const float s) const {
|
||||||
return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
|
return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
|
||||||
static_cast<T>(top + GetHeight() * s)};
|
static_cast<T>(top + GetHeight() * s)};
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,10 @@ class RasterizerCache : NonCopyable {
|
|||||||
public:
|
public:
|
||||||
using TextureRuntime = typename T::Runtime;
|
using TextureRuntime = typename T::Runtime;
|
||||||
using CachedSurface = typename T::Surface;
|
using CachedSurface = typename T::Surface;
|
||||||
using Watcher = SurfaceWatcher<CachedSurface>;
|
|
||||||
|
|
||||||
/// Declare rasterizer interval types
|
/// Declare rasterizer interval types
|
||||||
using Surface = std::shared_ptr<CachedSurface>;
|
using Surface = std::shared_ptr<CachedSurface>;
|
||||||
|
using Watcher = SurfaceWatcher<CachedSurface>;
|
||||||
using SurfaceSet = std::set<Surface>;
|
using SurfaceSet = std::set<Surface>;
|
||||||
using SurfaceMap =
|
using SurfaceMap =
|
||||||
boost::icl::interval_map<PAddr, Surface, boost::icl::partial_absorber, std::less,
|
boost::icl::interval_map<PAddr, Surface, boost::icl::partial_absorber, std::less,
|
||||||
@ -165,15 +165,15 @@ private:
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
RasterizerCache<T>::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, TextureRuntime& runtime)
|
RasterizerCache<T>::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, TextureRuntime& runtime)
|
||||||
: rasterizer(rasterizer), runtime{runtime} {
|
: rasterizer{rasterizer}, runtime{runtime} {
|
||||||
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
template <MatchFlags find_flags>
|
template <MatchFlags find_flags>
|
||||||
auto RasterizerCache<T>::FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params,
|
auto RasterizerCache<T>::FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params,
|
||||||
ScaleMatch match_scale_type,
|
ScaleMatch match_scale_type,
|
||||||
std::optional<SurfaceInterval> validate_interval) -> Surface {
|
std::optional<SurfaceInterval> validate_interval) -> Surface {
|
||||||
Surface match_surface = nullptr;
|
Surface match_surface = nullptr;
|
||||||
bool match_valid = false;
|
bool match_valid = false;
|
||||||
u32 match_scale = 0;
|
u32 match_scale = 0;
|
||||||
@ -273,14 +273,8 @@ bool RasterizerCache<T>::BlitSurfaces(const Surface& src_surface, Common::Rectan
|
|||||||
.dst_level = 0,
|
.dst_level = 0,
|
||||||
.src_layer = 0,
|
.src_layer = 0,
|
||||||
.dst_layer = 0,
|
.dst_layer = 0,
|
||||||
.src_region = Region2D{
|
.src_rect = src_rect,
|
||||||
.start = {src_rect.left, src_rect.bottom},
|
.dst_rect = dst_rect
|
||||||
.end = {src_rect.right, src_rect.top}
|
|
||||||
},
|
|
||||||
.dst_region = Region2D{
|
|
||||||
.start = {dst_rect.left, dst_rect.bottom},
|
|
||||||
.end = {dst_rect.right, dst_rect.top}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
|
return runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
|
||||||
@ -295,10 +289,9 @@ void RasterizerCache<T>::CopySurface(const Surface& src_surface, const Surface&
|
|||||||
SurfaceInterval copy_interval) {
|
SurfaceInterval copy_interval) {
|
||||||
MICROPROFILE_SCOPE(RasterizerCache_CopySurface);
|
MICROPROFILE_SCOPE(RasterizerCache_CopySurface);
|
||||||
|
|
||||||
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
|
const SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
|
||||||
ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
|
ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
|
||||||
|
|
||||||
const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params);
|
|
||||||
if (src_surface->type == SurfaceType::Fill) {
|
if (src_surface->type == SurfaceType::Fill) {
|
||||||
// FillSurface needs a 4 bytes buffer
|
// FillSurface needs a 4 bytes buffer
|
||||||
const u32 fill_offset =
|
const u32 fill_offset =
|
||||||
@ -317,10 +310,7 @@ void RasterizerCache<T>::CopySurface(const Surface& src_surface, const Surface&
|
|||||||
.surface_type = dst_surface->type,
|
.surface_type = dst_surface->type,
|
||||||
.texture_format = dst_surface->pixel_format,
|
.texture_format = dst_surface->pixel_format,
|
||||||
.texture_level = 0,
|
.texture_level = 0,
|
||||||
.rect = Rect2D{
|
.texture_rect = dst_surface->GetScaledSubRect(subrect_params)
|
||||||
.offset = {dst_rect.left, dst_rect.bottom},
|
|
||||||
.extent = {dst_rect.GetWidth(), dst_rect.GetHeight()}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
runtime.ClearTexture(dst_surface->texture, clear_rect, clear_value);
|
runtime.ClearTexture(dst_surface->texture, clear_rect, clear_value);
|
||||||
@ -328,21 +318,14 @@ void RasterizerCache<T>::CopySurface(const Surface& src_surface, const Surface&
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (src_surface->CanSubRect(subrect_params)) {
|
if (src_surface->CanSubRect(subrect_params)) {
|
||||||
const auto src_rect = src_surface->GetScaledSubRect(subrect_params);
|
|
||||||
const TextureBlit texture_blit = {
|
const TextureBlit texture_blit = {
|
||||||
.surface_type = src_surface->type,
|
.surface_type = src_surface->type,
|
||||||
.src_level = 0,
|
.src_level = 0,
|
||||||
.dst_level = 0,
|
.dst_level = 0,
|
||||||
.src_layer = 0,
|
.src_layer = 0,
|
||||||
.dst_layer = 0,
|
.dst_layer = 0,
|
||||||
.src_region = Region2D{
|
.src_rect = src_surface->GetScaledSubRect(subrect_params),
|
||||||
.start = {src_rect.left, src_rect.bottom},
|
.dst_rect = dst_surface->GetScaledSubRect(subrect_params)
|
||||||
.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, dst_surface->texture, texture_blit);
|
runtime.BlitTextures(src_surface->texture, dst_surface->texture, texture_blit);
|
||||||
@ -567,22 +550,14 @@ auto RasterizerCache<T>::GetTextureSurface(const Pica::Texture::TextureInfo& inf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (/*texture_filterer->IsNull()*/true) {
|
if (/*texture_filterer->IsNull()*/true) {
|
||||||
const auto src_rect = level_surface->GetScaledRect();
|
|
||||||
const auto dst_rect = surface_params.GetScaledRect();
|
|
||||||
const TextureBlit texture_blit = {
|
const TextureBlit texture_blit = {
|
||||||
.surface_type = surface->type,
|
.surface_type = surface->type,
|
||||||
.src_level = 0,
|
.src_level = 0,
|
||||||
.dst_level = level,
|
.dst_level = level,
|
||||||
.src_layer = 0,
|
.src_layer = 0,
|
||||||
.dst_layer = 0,
|
.dst_layer = 0,
|
||||||
.src_region = Region2D{
|
.src_rect = level_surface->GetScaledRect(),
|
||||||
.start = {src_rect.left, src_rect.bottom},
|
.dst_rect = surface_params.GetScaledRect()
|
||||||
.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(level_surface->texture, surface->texture, texture_blit);
|
runtime.BlitTextures(level_surface->texture, surface->texture, texture_blit);
|
||||||
@ -648,8 +623,7 @@ auto RasterizerCache<T>::GetTextureCube(const TextureCubeConfig& config) -> cons
|
|||||||
cube->texture = runtime.AllocateCubeMap(width, PixelFormatFromTextureFormat(config.format));
|
cube->texture = runtime.AllocateCubeMap(width, PixelFormatFromTextureFormat(config.format));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 scaled_size = cube->res_scale * config.width;
|
const u32 scaled_size = cube->res_scale * config.width;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < faces.size(); i++) {
|
for (std::size_t i = 0; i < faces.size(); i++) {
|
||||||
const Face& face = faces[i];
|
const Face& face = faces[i];
|
||||||
if (face.watcher && !face.watcher->IsValid()) {
|
if (face.watcher && !face.watcher->IsValid()) {
|
||||||
@ -658,21 +632,14 @@ auto RasterizerCache<T>::GetTextureCube(const TextureCubeConfig& config) -> cons
|
|||||||
ValidateSurface(surface, surface->addr, surface->size);
|
ValidateSurface(surface, surface->addr, surface->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto src_rect = surface->GetScaledRect();
|
|
||||||
const TextureBlit texture_blit = {
|
const TextureBlit texture_blit = {
|
||||||
.surface_type = SurfaceType::Color,
|
.surface_type = SurfaceType::Color,
|
||||||
.src_level = 0,
|
.src_level = 0,
|
||||||
.dst_level = 0,
|
.dst_level = 0,
|
||||||
.src_layer = 0,
|
.src_layer = 0,
|
||||||
.dst_layer = static_cast<u32>(i),
|
.dst_layer = static_cast<u32>(i),
|
||||||
.src_region = Region2D{
|
.src_rect = surface->GetScaledRect(),
|
||||||
.start = {src_rect.left, src_rect.bottom},
|
.dst_rect = Rect2D{0, scaled_size, scaled_size, 0}
|
||||||
.end = {src_rect.right, src_rect.top}
|
|
||||||
},
|
|
||||||
.dst_region = Region2D{
|
|
||||||
.start = {0, 0},
|
|
||||||
.end = {scaled_size, scaled_size}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
runtime.BlitTextures(surface->texture, cube->texture, texture_blit);
|
runtime.BlitTextures(surface->texture, cube->texture, texture_blit);
|
||||||
|
@ -180,8 +180,8 @@ SurfaceInterval SurfaceBase<S>::GetCopyableInterval(const SurfaceParams& params)
|
|||||||
|
|
||||||
template <class S>
|
template <class S>
|
||||||
auto SurfaceBase<S>::CreateWatcher() -> std::shared_ptr<Watcher> {
|
auto SurfaceBase<S>::CreateWatcher() -> std::shared_ptr<Watcher> {
|
||||||
S* derived = reinterpret_cast<S*>(this);
|
auto weak_ptr = reinterpret_cast<S*>(this)->weak_from_this();
|
||||||
auto watcher = std::make_shared<Watcher>(std::move(derived->weak_from_this()));
|
auto watcher = std::make_shared<Watcher>(std::move(weak_ptr));
|
||||||
watchers[watcher_count++] = watcher;
|
watchers[watcher_count++] = watcher;
|
||||||
return watcher;
|
return watcher;
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "common/common_types.h"
|
#include "common/math_util.h"
|
||||||
#include "common/vector_math.h"
|
#include "common/vector_math.h"
|
||||||
#include "video_core/rasterizer_cache/pixel_format.h"
|
#include "video_core/rasterizer_cache/pixel_format.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
|
using Rect2D = Common::Rectangle<u32>;
|
||||||
|
|
||||||
struct Offset {
|
struct Offset {
|
||||||
constexpr auto operator<=>(const Offset&) const noexcept = default;
|
constexpr auto operator<=>(const Offset&) const noexcept = default;
|
||||||
|
|
||||||
@ -23,20 +25,6 @@ struct Extent {
|
|||||||
u32 height = 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 {
|
union ClearValue {
|
||||||
Common::Vec4f color;
|
Common::Vec4f color;
|
||||||
struct {
|
struct {
|
||||||
@ -49,7 +37,7 @@ struct TextureClear {
|
|||||||
SurfaceType surface_type;
|
SurfaceType surface_type;
|
||||||
PixelFormat texture_format;
|
PixelFormat texture_format;
|
||||||
u32 texture_level;
|
u32 texture_level;
|
||||||
Rect2D rect;
|
Rect2D texture_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureCopy {
|
struct TextureCopy {
|
||||||
@ -67,8 +55,8 @@ struct TextureBlit {
|
|||||||
u32 dst_level;
|
u32 dst_level;
|
||||||
u32 src_layer;
|
u32 src_layer;
|
||||||
u32 dst_layer;
|
u32 dst_layer;
|
||||||
Region2D src_region;
|
Rect2D src_rect;
|
||||||
Region2D dst_region;
|
Rect2D dst_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferTextureCopy {
|
struct BufferTextureCopy {
|
||||||
@ -77,9 +65,8 @@ struct BufferTextureCopy {
|
|||||||
u32 buffer_row_length;
|
u32 buffer_row_length;
|
||||||
u32 buffer_height;
|
u32 buffer_height;
|
||||||
SurfaceType surface_type;
|
SurfaceType surface_type;
|
||||||
|
Rect2D texture_rect;
|
||||||
u32 texture_level;
|
u32 texture_level;
|
||||||
Offset texture_offset;
|
|
||||||
Extent texture_extent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferCopy {
|
struct BufferCopy {
|
||||||
|
@ -187,11 +187,9 @@ void TextureRuntime::ReadTexture(OGLTexture& texture, const VideoCore::BufferTex
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FormatTuple& tuple = GetFormatTuple(format);
|
const FormatTuple& tuple = GetFormatTuple(format);
|
||||||
glReadPixels(copy.texture_offset.x, copy.texture_offset.y,
|
glReadPixels(copy.texture_rect.left, copy.texture_rect.bottom,
|
||||||
copy.texture_offset.x + copy.texture_extent.width,
|
copy.texture_rect.GetWidth(), copy.texture_rect.GetHeight(),
|
||||||
copy.texture_offset.y + copy.texture_extent.height,
|
tuple.format, tuple.type, reinterpret_cast<void*>(copy.buffer_offset));
|
||||||
tuple.format, tuple.type,
|
|
||||||
reinterpret_cast<void*>(copy.buffer_offset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureRuntime::ClearTexture(OGLTexture& texture, const VideoCore::TextureClear& clear,
|
bool TextureRuntime::ClearTexture(OGLTexture& texture, const VideoCore::TextureClear& clear,
|
||||||
@ -202,10 +200,10 @@ bool TextureRuntime::ClearTexture(OGLTexture& texture, const VideoCore::TextureC
|
|||||||
// Setup scissor rectangle according to the clear rectangle
|
// Setup scissor rectangle according to the clear rectangle
|
||||||
OpenGLState state{};
|
OpenGLState state{};
|
||||||
state.scissor.enabled = true;
|
state.scissor.enabled = true;
|
||||||
state.scissor.x = clear.rect.offset.x;
|
state.scissor.x = clear.texture_rect.left;
|
||||||
state.scissor.y = clear.rect.offset.y;
|
state.scissor.y = clear.texture_rect.bottom;
|
||||||
state.scissor.width = clear.rect.extent.width;
|
state.scissor.width = clear.texture_rect.GetWidth();
|
||||||
state.scissor.height = clear.rect.extent.height;
|
state.scissor.height = clear.texture_rect.GetHeight();
|
||||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
@ -308,10 +306,8 @@ bool TextureRuntime::BlitTextures(OGLTexture& source, OGLTexture& dest, const Vi
|
|||||||
// inconsistent scale.
|
// inconsistent scale.
|
||||||
const GLbitfield buffer_mask = MakeBufferMask(blit.surface_type);
|
const GLbitfield buffer_mask = MakeBufferMask(blit.surface_type);
|
||||||
const GLenum filter = buffer_mask == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST;
|
const GLenum filter = buffer_mask == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST;
|
||||||
glBlitFramebuffer(blit.src_region.start.x, blit.src_region.start.y,
|
glBlitFramebuffer(blit.src_rect.left, blit.src_rect.bottom, blit.src_rect.right, blit.src_rect.top,
|
||||||
blit.src_region.end.x, blit.src_region.end.y,
|
blit.dst_rect.left, blit.dst_rect.bottom, blit.dst_rect.right, blit.dst_rect.top,
|
||||||
blit.dst_region.start.x, blit.dst_region.start.y,
|
|
||||||
blit.dst_region.end.x, blit.dst_region.end.y,
|
|
||||||
buffer_mask, filter);
|
buffer_mask, filter);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -354,11 +350,11 @@ void CachedSurface::UploadTexture(Common::Rectangle<u32> rect, const StagingBuff
|
|||||||
target_tex = unscaled_tex.handle;
|
target_tex = unscaled_tex.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLState cur_state = OpenGLState::GetCurState();
|
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||||
|
SCOPE_EXIT({ prev_state.Apply(); });
|
||||||
|
|
||||||
GLuint old_tex = cur_state.texture_units[0].texture_2d;
|
glActiveTexture(GL_TEXTURE0);
|
||||||
cur_state.texture_units[0].texture_2d = target_tex;
|
glBindTexture(GL_TEXTURE_2D, target_tex);
|
||||||
cur_state.Apply();
|
|
||||||
|
|
||||||
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
|
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
|
||||||
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
|
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
|
||||||
@ -366,18 +362,13 @@ void CachedSurface::UploadTexture(Common::Rectangle<u32> rect, const StagingBuff
|
|||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, staging.buffer.handle);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, staging.buffer.handle);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
|
||||||
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
|
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
|
||||||
reinterpret_cast<void*>(buffer_offset));
|
reinterpret_cast<void*>(buffer_offset));
|
||||||
|
|
||||||
|
// Lock the staging buffer until glTexSubImage completes
|
||||||
staging.Lock();
|
staging.Lock();
|
||||||
|
|
||||||
cur_state.texture_units[0].texture_2d = old_tex;
|
|
||||||
cur_state.Apply();
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
|
||||||
@ -416,6 +407,7 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
|
|||||||
MICROPROFILE_SCOPE(RasterizerCache_TextureDL);
|
MICROPROFILE_SCOPE(RasterizerCache_TextureDL);
|
||||||
|
|
||||||
const FormatTuple& tuple = runtime.GetFormatTuple(pixel_format);
|
const FormatTuple& tuple = runtime.GetFormatTuple(pixel_format);
|
||||||
|
const u32 buffer_offset = (rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format);
|
||||||
|
|
||||||
OpenGLState state = OpenGLState::GetCurState();
|
OpenGLState state = OpenGLState::GetCurState();
|
||||||
OpenGLState prev_state = state;
|
OpenGLState prev_state = state;
|
||||||
@ -425,7 +417,6 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
|
|||||||
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
|
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride));
|
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride));
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, staging.buffer.handle);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, staging.buffer.handle);
|
||||||
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 not 1x scale, blit scaled texture to a new 1x texture and use that to flush
|
||||||
if (res_scale != 1) {
|
if (res_scale != 1) {
|
||||||
@ -441,14 +432,8 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
|
|||||||
.surface_type = type,
|
.surface_type = type,
|
||||||
.src_level = 0,
|
.src_level = 0,
|
||||||
.dst_level = 0,
|
.dst_level = 0,
|
||||||
.src_region = VideoCore::Region2D{
|
.src_rect = scaled_rect,
|
||||||
.start = {scaled_rect.left, scaled_rect.bottom},
|
.dst_rect = VideoCore::Rect2D{0, rect.GetHeight(), rect.GetWidth(), 0}
|
||||||
.end = {scaled_rect.right, scaled_rect.top}
|
|
||||||
},
|
|
||||||
.dst_region = VideoCore::Region2D{
|
|
||||||
.start = {0, 0},
|
|
||||||
.end = {rect.GetWidth(), rect.GetHeight()}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Blit scaled texture to the unscaled one
|
// Blit scaled texture to the unscaled one
|
||||||
@ -475,9 +460,8 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
|
|||||||
.buffer_row_length = stride,
|
.buffer_row_length = stride,
|
||||||
.buffer_height = height,
|
.buffer_height = height,
|
||||||
.surface_type = type,
|
.surface_type = type,
|
||||||
.texture_level = 0,
|
.texture_rect = rect,
|
||||||
.texture_offset = {rect.bottom, rect.left},
|
.texture_level = 0
|
||||||
.texture_extent = {rect.GetWidth(), rect.GetHeight()}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
runtime.ReadTexture(texture, texture_download, pixel_format);
|
runtime.ReadTexture(texture, texture_download, pixel_format);
|
||||||
@ -487,4 +471,8 @@ void CachedSurface::DownloadTexture(Common::Rectangle<u32> rect, const StagingBu
|
|||||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CachedSurface::Scale() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
@ -112,6 +112,10 @@ public:
|
|||||||
/// Downloads pixel data to staging from a rectangle region of the surface texture
|
/// Downloads pixel data to staging from a rectangle region of the surface texture
|
||||||
void DownloadTexture(Common::Rectangle<u32> rect, const StagingBuffer& staging);
|
void DownloadTexture(Common::Rectangle<u32> rect, const StagingBuffer& staging);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Replaces the current texture with a scaled version according to res_scale
|
||||||
|
void Scale();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureRuntime& runtime;
|
TextureRuntime& runtime;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user