3
0
Fork 0
forked from suyu/suyu

OpenGL: Non-zero stride only makes sense for linear buffers

This commit is contained in:
Yuri Kunde Schlesner 2016-12-04 05:16:56 -08:00
parent 2600633b89
commit 8a1f96011d
3 changed files with 11 additions and 7 deletions

View file

@ -947,7 +947,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
src_params.addr = framebuffer_addr; src_params.addr = framebuffer_addr;
src_params.width = config.width; src_params.width = config.width;
src_params.height = config.height; src_params.height = config.height;
src_params.stride = pixel_stride; src_params.pixel_stride = pixel_stride;
src_params.is_tiled = false; src_params.is_tiled = false;
src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.color_format); src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.color_format);

View file

@ -288,6 +288,9 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
MICROPROFILE_SCOPE(OpenGL_SurfaceUpload); MICROPROFILE_SCOPE(OpenGL_SurfaceUpload);
// Stride only applies to linear images.
ASSERT(params.pixel_stride == 0 || !params.is_tiled);
std::shared_ptr<CachedSurface> new_surface = std::make_shared<CachedSurface>(); std::shared_ptr<CachedSurface> new_surface = std::make_shared<CachedSurface>();
new_surface->addr = params.addr; new_surface->addr = params.addr;
@ -296,7 +299,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
new_surface->texture.Create(); new_surface->texture.Create();
new_surface->width = params.width; new_surface->width = params.width;
new_surface->height = params.height; new_surface->height = params.height;
new_surface->stride = params.stride; new_surface->pixel_stride = params.pixel_stride;
new_surface->res_scale_width = params.res_scale_width; new_surface->res_scale_width = params.res_scale_width;
new_surface->res_scale_height = params.res_scale_height; new_surface->res_scale_height = params.res_scale_height;
@ -322,14 +325,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
cur_state.Apply(); cur_state.Apply();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->stride);
if (!new_surface->is_tiled) { if (!new_surface->is_tiled) {
// TODO: Ensure this will always be a color format, not a depth or other format // TODO: Ensure this will always be a color format, not a depth or other format
ASSERT((size_t)new_surface->pixel_format < fb_format_tuples.size()); ASSERT((size_t)new_surface->pixel_format < fb_format_tuples.size());
const FormatTuple& tuple = fb_format_tuples[(unsigned int)params.pixel_format]; const FormatTuple& tuple = fb_format_tuples[(unsigned int)params.pixel_format];
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->pixel_stride);
glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0,
tuple.format, tuple.type, texture_src_data); tuple.format, tuple.type, texture_src_data);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else { } else {
SurfaceType type = CachedSurface::GetFormatType(new_surface->pixel_format); SurfaceType type = CachedSurface::GetFormatType(new_surface->pixel_format);
if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) {
@ -388,7 +392,6 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
0, tuple.format, tuple.type, temp_fb_depth_buffer.data()); 0, tuple.format, tuple.type, temp_fb_depth_buffer.data());
} }
} }
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
// If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface // If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface
if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) { if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) {
@ -698,13 +701,14 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
cur_state.Apply(); cur_state.Apply();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->stride);
if (!surface->is_tiled) { if (!surface->is_tiled) {
// TODO: Ensure this will always be a color format, not a depth or other format // TODO: Ensure this will always be a color format, not a depth or other format
ASSERT((size_t)surface->pixel_format < fb_format_tuples.size()); ASSERT((size_t)surface->pixel_format < fb_format_tuples.size());
const FormatTuple& tuple = fb_format_tuples[(unsigned int)surface->pixel_format]; const FormatTuple& tuple = fb_format_tuples[(unsigned int)surface->pixel_format];
glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->pixel_stride);
glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, dst_buffer); glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, dst_buffer);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
} else { } else {
SurfaceType type = CachedSurface::GetFormatType(surface->pixel_format); SurfaceType type = CachedSurface::GetFormatType(surface->pixel_format);
if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) {
@ -747,7 +751,6 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
false); false);
} }
} }
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
surface->dirty = false; surface->dirty = false;

View file

@ -171,7 +171,8 @@ struct CachedSurface {
OGLTexture texture; OGLTexture texture;
u32 width; u32 width;
u32 height; u32 height;
u32 stride = 0; /// Stride between lines, in pixels. Only valid for images in linear format.
u32 pixel_stride = 0;
float res_scale_width = 1.f; float res_scale_width = 1.f;
float res_scale_height = 1.f; float res_scale_height = 1.f;