mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
implemented nv3089_image_in using opengl
implemented support 1D & 3D textures fixed regions relocation use liner filter on buffers blit minor fixes
This commit is contained in:
parent
10ec26ace8
commit
0f29b5ddb2
@ -945,10 +945,308 @@ bool nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scale_texture(gl::texture& dst, gl::texture::sized_internal_format dst_format, size2i dst_size, const gl::texture& src, position2i point, size2i src_size)
|
||||||
|
{
|
||||||
|
dst.bind();
|
||||||
|
|
||||||
|
if (dst.get_target() == gl::texture::target::texture1D)
|
||||||
|
{
|
||||||
|
glTexStorage1D((GLenum)dst.get_target(), 1, (GLenum)dst_format, dst_size.width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glTexStorage2D((GLenum)dst.get_target(), 1, (GLenum)dst_format, dst_size.width, dst_size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl::fbo src_fbo, dst_fbo;
|
||||||
|
src_fbo.create();
|
||||||
|
dst_fbo.create();
|
||||||
|
|
||||||
|
dst_fbo.color = dst;
|
||||||
|
src_fbo.color = src;
|
||||||
|
|
||||||
|
src_fbo.blit(dst_fbo, areai{ point.x, point.y, src_size.width, src_size.height }, coordi{ {}, dst_size }, gl::buffers::color, gl::filter::linear);
|
||||||
|
}
|
||||||
|
|
||||||
bool nv3089_image_in(u32 arg, GLGSRender* renderer)
|
bool nv3089_image_in(u32 arg, GLGSRender* renderer)
|
||||||
{
|
{
|
||||||
//TODO
|
u32 operation = rsx::method_registers[NV3089_SET_OPERATION];
|
||||||
return false;
|
|
||||||
|
u32 clip_x = rsx::method_registers[NV3089_CLIP_POINT] & 0xffff;
|
||||||
|
u32 clip_y = rsx::method_registers[NV3089_CLIP_POINT] >> 16;
|
||||||
|
u32 clip_w = rsx::method_registers[NV3089_CLIP_SIZE] & 0xffff;
|
||||||
|
u32 clip_h = rsx::method_registers[NV3089_CLIP_SIZE] >> 16;
|
||||||
|
|
||||||
|
u32 out_x = rsx::method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff;
|
||||||
|
u32 out_y = rsx::method_registers[NV3089_IMAGE_OUT_POINT] >> 16;
|
||||||
|
u32 out_w = rsx::method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff;
|
||||||
|
u32 out_h = rsx::method_registers[NV3089_IMAGE_OUT_SIZE] >> 16;
|
||||||
|
|
||||||
|
u16 in_w = rsx::method_registers[NV3089_IMAGE_IN_SIZE];
|
||||||
|
u16 in_h = rsx::method_registers[NV3089_IMAGE_IN_SIZE] >> 16;
|
||||||
|
u16 in_pitch = rsx::method_registers[NV3089_IMAGE_IN_FORMAT];
|
||||||
|
u8 in_origin = rsx::method_registers[NV3089_IMAGE_IN_FORMAT] >> 16;
|
||||||
|
u8 in_inter = rsx::method_registers[NV3089_IMAGE_IN_FORMAT] >> 24;
|
||||||
|
u32 src_color_format = rsx::method_registers[NV3089_SET_COLOR_FORMAT];
|
||||||
|
|
||||||
|
u32 context_surface = rsx::method_registers[NV3089_SET_CONTEXT_SURFACE];
|
||||||
|
|
||||||
|
f32 scale_x = 1048576.f / rsx::method_registers[NV3089_DS_DX];
|
||||||
|
f32 scale_y = 1048576.f / rsx::method_registers[NV3089_DT_DY];
|
||||||
|
|
||||||
|
f32 in_x = (arg & 0xffff) / 16.f;
|
||||||
|
f32 in_y = (arg >> 16) / 16.f;
|
||||||
|
|
||||||
|
if (in_w <= 64 || in_h <= 64)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(in_origin != CELL_GCM_TRANSFER_ORIGIN_CORNER)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", in_origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_inter != CELL_GCM_TRANSFER_INTERPOLATOR_ZOH && in_inter != CELL_GCM_TRANSFER_INTERPOLATOR_FOH)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", in_inter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operation != CELL_GCM_TRANSFER_OPERATION_SRCCOPY)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unimplemented operation (%d)", operation);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 src_offset = rsx::method_registers[NV3089_IMAGE_IN_OFFSET];
|
||||||
|
const u32 src_dma = rsx::method_registers[NV3089_SET_CONTEXT_DMA_IMAGE];
|
||||||
|
|
||||||
|
u32 dst_offset;
|
||||||
|
u32 dst_dma = 0;
|
||||||
|
u16 dst_color_format;
|
||||||
|
u32 out_pitch = 0;
|
||||||
|
u32 out_aligment = 64;
|
||||||
|
|
||||||
|
switch (context_surface)
|
||||||
|
{
|
||||||
|
case CELL_GCM_CONTEXT_SURFACE2D:
|
||||||
|
dst_dma = rsx::method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN];
|
||||||
|
dst_offset = rsx::method_registers[NV3062_SET_OFFSET_DESTIN];
|
||||||
|
dst_color_format = rsx::method_registers[NV3062_SET_COLOR_FORMAT];
|
||||||
|
out_pitch = rsx::method_registers[NV3062_SET_PITCH] >> 16;
|
||||||
|
out_aligment = rsx::method_registers[NV3062_SET_PITCH] & 0xffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GCM_CONTEXT_SWIZZLE2D:
|
||||||
|
dst_dma = rsx::method_registers[NV309E_SET_CONTEXT_DMA_IMAGE];
|
||||||
|
dst_offset = rsx::method_registers[NV309E_SET_OFFSET];
|
||||||
|
dst_color_format = rsx::method_registers[NV309E_SET_FORMAT];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", rsx::method_registers[NV3089_SET_CONTEXT_SURFACE]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_color_format != CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 &&
|
||||||
|
dst_color_format != CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_color_format != CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 &&
|
||||||
|
src_color_format != CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u32 in_bpp = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? 2 : 4; // bytes per pixel
|
||||||
|
u32 out_bpp = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? 2 : 4;
|
||||||
|
|
||||||
|
if (out_pitch == 0)
|
||||||
|
{
|
||||||
|
out_pitch = out_bpp * out_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_pitch == 0)
|
||||||
|
{
|
||||||
|
in_pitch = in_bpp * in_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clip_w > out_w)
|
||||||
|
{
|
||||||
|
clip_w = out_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clip_h > out_h)
|
||||||
|
{
|
||||||
|
clip_h = out_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 convert_w = u32(scale_x * in_w);
|
||||||
|
u32 convert_h = u32(scale_y * in_h);
|
||||||
|
|
||||||
|
//LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: src = 0x%x, dst = 0x%x", src_address, dst_address);
|
||||||
|
|
||||||
|
rsx::tiled_region src_region = renderer->get_tiled_address(src_offset, src_dma & 0xf);//get_address(src_offset, src_dma);
|
||||||
|
rsx::tiled_region dst_region = renderer->get_tiled_address(dst_offset, dst_dma & 0xf);
|
||||||
|
|
||||||
|
u32 src_x = 0;
|
||||||
|
u32 src_y = 0;
|
||||||
|
|
||||||
|
gl::texture_info src_info{};
|
||||||
|
src_info.start_address = src_region.address;
|
||||||
|
|
||||||
|
if (src_region.tile)
|
||||||
|
{
|
||||||
|
src_x = (src_region.base % src_region.tile->pitch) / in_bpp;
|
||||||
|
src_y = src_region.base / src_region.tile->pitch;
|
||||||
|
|
||||||
|
src_info.width = src_region.tile->pitch / in_bpp;
|
||||||
|
src_info.height = src_region.tile->size / src_region.tile->pitch;
|
||||||
|
src_info.pitch = src_region.tile->pitch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_info.width = in_w;
|
||||||
|
src_info.height = in_h;
|
||||||
|
src_info.pitch = in_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_info.depth = 1;
|
||||||
|
src_info.mipmap = 1;
|
||||||
|
src_info.dimension = src_info.height == 1 ? 1 : 2;
|
||||||
|
|
||||||
|
switch (src_info.dimension)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (src_info.width & 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_info.target = gl::texture::target::texture1D;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if ((src_info.width | src_info.height) & 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_info.target = gl::texture::target::texture2D;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (src_color_format)
|
||||||
|
{
|
||||||
|
case CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5:
|
||||||
|
src_info.format = gl::get_texture_format(CELL_GCM_TEXTURE_R5G6B5);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8:
|
||||||
|
src_info.format = gl::get_texture_format(CELL_GCM_TEXTURE_A8R8G8B8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 dst_x = 0;
|
||||||
|
u32 dst_y = 0;
|
||||||
|
|
||||||
|
gl::texture_info dst_info{};
|
||||||
|
dst_info.start_address = dst_region.address;
|
||||||
|
|
||||||
|
if (dst_region.tile)
|
||||||
|
{
|
||||||
|
dst_x = (dst_region.base % dst_region.tile->pitch) / out_bpp;
|
||||||
|
dst_y = dst_region.base / dst_region.tile->pitch;
|
||||||
|
|
||||||
|
dst_info.width = dst_region.tile->pitch / out_bpp;
|
||||||
|
dst_info.height = dst_region.tile->size / dst_region.tile->pitch;
|
||||||
|
dst_info.pitch = dst_region.tile->pitch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst_info.start_address += out_x * out_bpp + out_y * out_pitch;
|
||||||
|
out_x = 0;
|
||||||
|
out_y = 0;
|
||||||
|
dst_info.width = out_w;
|
||||||
|
dst_info.height = out_h;
|
||||||
|
dst_info.pitch = out_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_info.depth = 1;
|
||||||
|
dst_info.mipmap = 1;
|
||||||
|
dst_info.dimension = dst_info.height == 1 ? 1 : 2;
|
||||||
|
|
||||||
|
switch (dst_info.dimension)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (dst_info.width & 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_info.target = gl::texture::target::texture1D;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if ((dst_info.width | dst_info.height) & 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_info.target = gl::texture::target::texture2D;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_info.swizzled = context_surface == CELL_GCM_CONTEXT_SWIZZLE2D;
|
||||||
|
|
||||||
|
switch (dst_color_format)
|
||||||
|
{
|
||||||
|
case CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5:
|
||||||
|
dst_info.format = gl::get_texture_format(CELL_GCM_TEXTURE_R5G6B5);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8:
|
||||||
|
dst_info.format = gl::get_texture_format(CELL_GCM_TEXTURE_A8R8G8B8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &src_texture = renderer->texture_cache.entry(src_info, gl::cache_buffers::local);
|
||||||
|
auto &dst_texture = renderer->texture_cache.entry(dst_info);
|
||||||
|
|
||||||
|
dst_texture.ignore(gl::cache_buffers::local);
|
||||||
|
|
||||||
|
u32 src_id = src_texture.view().id();
|
||||||
|
gl::texture tmp;
|
||||||
|
|
||||||
|
if (convert_w != src_info.width || convert_h != src_info.height)
|
||||||
|
{
|
||||||
|
tmp.create(src_info.target);
|
||||||
|
|
||||||
|
__glcheck scale_texture(tmp, src_info.format.internal_format, { (int)convert_w, (int)convert_h },
|
||||||
|
src_texture.view(), { (int)src_x + int(in_x), (int)src_y + int(in_y) }, { int(src_x + in_w), int(src_y + in_h) });
|
||||||
|
|
||||||
|
src_id = tmp.id();
|
||||||
|
|
||||||
|
src_x = 0;
|
||||||
|
src_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__glcheck glCopyImageSubData(
|
||||||
|
src_id, (GLenum)src_info.target, 0, src_x, src_y, 0,
|
||||||
|
dst_texture.view().id(), (GLenum)dst_info.target, 0, dst_x + out_x, dst_y + out_y, 0,
|
||||||
|
clip_w, clip_h, 1);
|
||||||
|
dst_texture.invalidate(gl::cache_buffers::host);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
using rsx_method_impl_t = bool(*)(u32, GLGSRender*);
|
using rsx_method_impl_t = bool(*)(u32, GLGSRender*);
|
||||||
@ -956,7 +1254,7 @@ using rsx_method_impl_t = bool(*)(u32, GLGSRender*);
|
|||||||
static const std::unordered_map<u32, rsx_method_impl_t> g_gl_method_tbl =
|
static const std::unordered_map<u32, rsx_method_impl_t> g_gl_method_tbl =
|
||||||
{
|
{
|
||||||
{ NV4097_CLEAR_SURFACE, nv4097_clear_surface },
|
{ NV4097_CLEAR_SURFACE, nv4097_clear_surface },
|
||||||
//{ NV3089_IMAGE_IN, nv3089_image_in },
|
{ NV3089_IMAGE_IN, nv3089_image_in },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GLGSRender::do_method(u32 cmd, u32 arg)
|
bool GLGSRender::do_method(u32 cmd, u32 arg)
|
||||||
@ -1142,21 +1440,32 @@ u32 surface_format_to_texture_format(rsx::surface_color_format format)
|
|||||||
return CELL_GCM_TEXTURE_A8R8G8B8;
|
return CELL_GCM_TEXTURE_A8R8G8B8;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::texture_info surface_info(rsx::surface_color_format format, u32 offset, u32 location, u32 width, u32 height, u32 pitch)
|
gl::texture_info surface_info(rsx::thread &rsx, rsx::surface_color_format format, u32 offset, u32 location, u32 width, u32 height, u32 pitch)
|
||||||
{
|
{
|
||||||
gl::texture_info info{};
|
gl::texture_info info{};
|
||||||
|
info.format = gl::get_texture_format(surface_format_to_texture_format(format));
|
||||||
|
|
||||||
|
rsx::tiled_region region = rsx.get_tiled_address(offset, location);
|
||||||
|
|
||||||
|
if (region.tile && region.base == 0)
|
||||||
|
{
|
||||||
|
info.width = region.tile->pitch / info.format.bpp;
|
||||||
|
info.height = region.tile->size / region.tile->pitch;
|
||||||
|
info.pitch = region.tile->pitch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.width = width;
|
||||||
|
info.height = height;
|
||||||
|
info.pitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
info.width = width;
|
|
||||||
info.height = height;
|
|
||||||
info.depth = 1;
|
info.depth = 1;
|
||||||
info.pitch = pitch;
|
|
||||||
info.target = gl::texture::target::texture2D;
|
info.target = gl::texture::target::texture2D;
|
||||||
info.dimension = 2;
|
info.dimension = 2;
|
||||||
info.start_address = rsx::get_address(offset, location);
|
info.start_address = region.address;
|
||||||
info.mipmap = 1;
|
info.mipmap = 1;
|
||||||
|
|
||||||
info.format = gl::get_texture_format(surface_format_to_texture_format(format));
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,7 +1518,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
|||||||
u32 pitch = rsx::method_registers[mr_color_pitch[index]];
|
u32 pitch = rsx::method_registers[mr_color_pitch[index]];
|
||||||
bool swizzled = m_surface.type == CELL_GCM_SURFACE_SWIZZLE;
|
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);
|
gl::texture_info info = surface_info(*this, m_surface.color_format, offset, location, m_surface.width, m_surface.height, pitch);
|
||||||
|
|
||||||
info.swizzled = swizzled;
|
info.swizzled = swizzled;
|
||||||
|
|
||||||
@ -1248,12 +1557,24 @@ void GLGSRender::init_buffers(bool skip_reading)
|
|||||||
|
|
||||||
gl::texture_info info{};
|
gl::texture_info info{};
|
||||||
|
|
||||||
info.width = m_surface.width;
|
rsx::tiled_region region = get_tiled_address(offset, location);
|
||||||
info.height = m_surface.height;
|
|
||||||
|
if (region.tile && region.base == 0)
|
||||||
|
{
|
||||||
|
info.width = region.tile->pitch / info.format.bpp;
|
||||||
|
info.height = region.tile->size / region.tile->pitch;
|
||||||
|
info.pitch = region.tile->pitch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.width = m_surface.width;
|
||||||
|
info.height = m_surface.height;
|
||||||
|
info.pitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
info.depth = 1;
|
info.depth = 1;
|
||||||
info.pitch = pitch;
|
|
||||||
info.dimension = 2;
|
info.dimension = 2;
|
||||||
info.start_address = rsx::get_address(offset, location);
|
info.start_address = region.address;
|
||||||
info.target = gl::texture::target::texture2D;
|
info.target = gl::texture::target::texture2D;
|
||||||
info.format.bpp = bpp;
|
info.format.bpp = bpp;
|
||||||
info.mipmap = 1;
|
info.mipmap = 1;
|
||||||
@ -1341,7 +1662,7 @@ void GLGSRender::flip(int buffer)
|
|||||||
glDisable(GL_LOGIC_OP);
|
glDisable(GL_LOGIC_OP);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
gl::cached_texture& texture = texture_cache.entry(surface_info(rsx::surface_color_format::a8r8g8b8, gcm_buffers[buffer].offset,
|
gl::cached_texture& texture = texture_cache.entry(surface_info(*this, rsx::surface_color_format::a8r8g8b8, gcm_buffers[buffer].offset,
|
||||||
CELL_GCM_LOCATION_LOCAL, buffer_width, buffer_height, buffer_pitch), gl::cache_buffers::local);
|
CELL_GCM_LOCATION_LOCAL, buffer_width, buffer_height, buffer_pitch), gl::cache_buffers::local);
|
||||||
|
|
||||||
//std::lock_guard<gl::cached_texture> lock(texture);
|
//std::lock_guard<gl::cached_texture> lock(texture);
|
||||||
@ -1382,9 +1703,11 @@ void GLGSRender::flip(int buffer)
|
|||||||
|
|
||||||
gl::screen.clear(gl::buffers::color_depth_stencil);
|
gl::screen.clear(gl::buffers::color_depth_stencil);
|
||||||
|
|
||||||
__glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical());
|
__glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical(), gl::buffers::color, gl::filter::linear);
|
||||||
|
|
||||||
m_frame->flip(m_context);
|
m_frame->flip(m_context);
|
||||||
|
|
||||||
|
texture_cache.update_protection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,6 +177,7 @@ OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, CompressedTexSubImage1D);
|
|||||||
OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, CompressedTexSubImage2D);
|
OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, CompressedTexSubImage2D);
|
||||||
OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, CompressedTexSubImage3D);
|
OPENGL_PROC(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, CompressedTexSubImage3D);
|
||||||
OPENGL_PROC(PFNGLCLEARTEXIMAGEPROC, ClearTexImage);
|
OPENGL_PROC(PFNGLCLEARTEXIMAGEPROC, ClearTexImage);
|
||||||
|
OPENGL_PROC(PFNGLTEXSUBIMAGE3DPROC, TexSubImage3D);
|
||||||
|
|
||||||
//ARB_Copy_Image
|
//ARB_Copy_Image
|
||||||
OPENGL_PROC(PFNGLCOPYIMAGESUBDATAPROC, CopyImageSubData);
|
OPENGL_PROC(PFNGLCOPYIMAGESUBDATAPROC, CopyImageSubData);
|
||||||
|
@ -17,7 +17,14 @@ namespace gl
|
|||||||
{
|
{
|
||||||
void cached_texture::read()
|
void cached_texture::read()
|
||||||
{
|
{
|
||||||
cached_texture* found_texture = nullptr;
|
struct capability_texture
|
||||||
|
{
|
||||||
|
positioni src_pos;
|
||||||
|
positioni dst_pos;
|
||||||
|
cached_texture* texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<capability_texture> found_textures;
|
||||||
u32 texture_size = info.size();
|
u32 texture_size = info.size();
|
||||||
|
|
||||||
m_parent_region->for_each(info.start_address, texture_size, [&](cached_texture& texture)
|
m_parent_region->for_each(info.start_address, texture_size, [&](cached_texture& texture)
|
||||||
@ -27,24 +34,91 @@ namespace gl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture.info.start_address != info.start_address ||
|
if (texture.info.pitch != info.pitch || texture.info.format.bpp != info.format.bpp)
|
||||||
texture.info.pitch != info.pitch ||
|
|
||||||
texture.info.height < info.height ||
|
|
||||||
texture.info.width < info.width)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
found_texture = &texture;
|
capability_texture texture_info{};
|
||||||
|
|
||||||
|
if (texture.info.start_address < info.start_address)
|
||||||
|
{
|
||||||
|
if (texture.info.dimension > 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 diff = info.start_address - texture.info.start_address;
|
||||||
|
|
||||||
|
texture_info.src_pos.y = diff / info.pitch;
|
||||||
|
texture_info.src_pos.x = (diff % info.pitch) / info.format.bpp;
|
||||||
|
|
||||||
|
//texture.sync(cache_buffers::host);
|
||||||
|
}
|
||||||
|
else if (texture.info.start_address > info.start_address)
|
||||||
|
{
|
||||||
|
if (info.dimension > 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 diff = texture.info.start_address - info.start_address;
|
||||||
|
|
||||||
|
texture_info.dst_pos.y = diff / info.pitch;
|
||||||
|
texture_info.dst_pos.x = (diff % info.pitch) / info.format.bpp;
|
||||||
|
|
||||||
|
//texture.sync(gl::cache_buffers::host);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_info.texture = &texture;
|
||||||
|
found_textures.push_back(texture_info);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (found_texture)
|
u32 covered_width = 0, covered_height = 0, covered_depth = 0;
|
||||||
|
|
||||||
|
while (found_textures.size() > 1)
|
||||||
{
|
{
|
||||||
//read from local
|
bool found = false;
|
||||||
__glcheck glCopyImageSubData(
|
|
||||||
found_texture->gl_name, (GLenum)found_texture->info.target, 0, 0, 0, 0,
|
for (auto& tex : found_textures)
|
||||||
gl_name, (GLenum)info.target, 0, 0, 0, 0,
|
{
|
||||||
info.width, info.height, info.depth);
|
if (tex.dst_pos.x == covered_width)
|
||||||
|
{
|
||||||
|
covered_width += tex.texture->info.width;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex.dst_pos.y == covered_height)
|
||||||
|
{
|
||||||
|
covered_height += tex.texture->info.height;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == covered_depth)
|
||||||
|
{
|
||||||
|
covered_depth += tex.texture->info.depth;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
if (covered_width < info.width || covered_height < info.height || covered_depth < info.depth)
|
||||||
|
{
|
||||||
|
found_textures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_textures.empty())
|
||||||
|
{
|
||||||
|
//read from locals
|
||||||
|
|
||||||
|
for (auto &tex : found_textures)
|
||||||
|
{
|
||||||
|
__glcheck glCopyImageSubData(
|
||||||
|
tex.texture->gl_name, (GLenum)tex.texture->info.target, 0, tex.src_pos.x, tex.src_pos.y, 0,
|
||||||
|
gl_name, (GLenum)info.target, 0, tex.dst_pos.x, tex.dst_pos.y, 0,
|
||||||
|
std::min(tex.texture->info.width, info.width), std::min(tex.texture->info.height, info.height), std::min(tex.texture->info.depth, tex.texture->info.depth));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -53,6 +127,7 @@ namespace gl
|
|||||||
m_parent_region->for_each(info.start_address, texture_size, [](cached_texture& texture)
|
m_parent_region->for_each(info.start_address, texture_size, [](cached_texture& texture)
|
||||||
{
|
{
|
||||||
texture.sync(gl::cache_buffers::host);
|
texture.sync(gl::cache_buffers::host);
|
||||||
|
//texture.invalidate(gl::cache_buffers::local);
|
||||||
});
|
});
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
@ -101,20 +176,48 @@ namespace gl
|
|||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_depth.id());
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_depth.id());
|
||||||
|
|
||||||
__glcheck glTexSubImage2D((GLenum)info.target, 0, 0, 0, info.width, info.height,
|
switch (info.dimension)
|
||||||
(GLenum)info.format.format, (GLenum)info.format.type, nullptr);
|
{
|
||||||
|
case 1: __glcheck glTexSubImage1D((GLenum)info.target, 0, 0, info.width, (GLenum)info.format.format, (GLenum)info.format.type, nullptr); break;
|
||||||
|
case 2: __glcheck glTexSubImage2D((GLenum)info.target, 0, 0, 0, info.width, info.height, (GLenum)info.format.format, (GLenum)info.format.type, nullptr); break;
|
||||||
|
case 3: __glcheck glTexSubImage3D((GLenum)info.target, 0, 0, 0, 0, info.width, info.height, info.depth, (GLenum)info.format.format, (GLenum)info.format.type, nullptr); break;
|
||||||
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
}
|
}
|
||||||
else if (info.compressed_size)
|
else if (info.compressed_size)
|
||||||
{
|
{
|
||||||
__glcheck glCompressedTexSubImage2D((GLenum)info.target, 0,
|
switch (info.dimension)
|
||||||
0, 0, info.width, info.height,
|
{
|
||||||
(GLenum)info.format.internal_format,
|
case 1:
|
||||||
info.compressed_size, vm::base_priv(info.start_address));
|
__glcheck glCompressedTexSubImage1D((GLenum)info.target, 0,
|
||||||
|
0, info.width,
|
||||||
|
(GLenum)info.format.internal_format,
|
||||||
|
info.compressed_size, vm::base_priv(info.start_address));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
__glcheck glCompressedTexSubImage2D((GLenum)info.target, 0,
|
||||||
|
0, 0, info.width, info.height,
|
||||||
|
(GLenum)info.format.internal_format,
|
||||||
|
info.compressed_size, vm::base_priv(info.start_address));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
__glcheck glCompressedTexSubImage3D((GLenum)info.target, 0,
|
||||||
|
0, 0, 0, info.width, info.height, info.depth,
|
||||||
|
(GLenum)info.format.internal_format,
|
||||||
|
info.compressed_size, vm::base_priv(info.start_address));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (info.dimension > 2)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "unimplemented reading swizzled %uD texture", info.dimension);
|
||||||
|
}
|
||||||
|
|
||||||
void *pixels = vm::base_priv(info.start_address);
|
void *pixels = vm::base_priv(info.start_address);
|
||||||
|
|
||||||
std::unique_ptr<u8[]> linear_pixels;
|
std::unique_ptr<u8[]> linear_pixels;
|
||||||
@ -150,8 +253,12 @@ namespace gl
|
|||||||
.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();
|
.apply();
|
||||||
|
|
||||||
__glcheck glTexSubImage2D((GLenum)info.target, 0, 0, 0, info.width, info.height,
|
switch (info.dimension)
|
||||||
(GLenum)info.format.format, (GLenum)info.format.type, pixels);
|
{
|
||||||
|
case 1: __glcheck glTexSubImage1D((GLenum)info.target, 0, 0, info.width, (GLenum)info.format.format, (GLenum)info.format.type, pixels); break;
|
||||||
|
case 2: __glcheck glTexSubImage2D((GLenum)info.target, 0, 0, 0, info.width, info.height, (GLenum)info.format.format, (GLenum)info.format.type, pixels); break;
|
||||||
|
case 3: __glcheck glTexSubImage3D((GLenum)info.target, 0, 0, 0, 0, info.width, info.height, info.depth, (GLenum)info.format.format, (GLenum)info.format.type, pixels); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.mipmap > 1)
|
if (info.mipmap > 1)
|
||||||
@ -351,16 +458,6 @@ namespace gl
|
|||||||
return cache_access::none;
|
return cache_access::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cached_texture::lock()
|
|
||||||
{
|
|
||||||
m_parent_region->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cached_texture::unlock()
|
|
||||||
{
|
|
||||||
m_parent_region->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cached_texture::bind(uint index) const
|
void cached_texture::bind(uint index) const
|
||||||
{
|
{
|
||||||
if (index != ~0u)
|
if (index != ~0u)
|
||||||
@ -378,7 +475,15 @@ namespace gl
|
|||||||
glGenTextures(1, &gl_name);
|
glGenTextures(1, &gl_name);
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
__glcheck glTexStorage2D((GLenum)info.target, info.mipmap, (GLenum)info.format.internal_format, info.width, info.height);
|
|
||||||
|
switch (info.dimension)
|
||||||
|
{
|
||||||
|
case 1: __glcheck glTexStorage1D((GLenum)info.target, info.mipmap, (GLenum)info.format.internal_format, info.width); break;
|
||||||
|
case 2: __glcheck glTexStorage2D((GLenum)info.target, info.mipmap, (GLenum)info.format.internal_format, info.width, info.height); break;
|
||||||
|
case 3: __glcheck glTexStorage3D((GLenum)info.target, info.mipmap, (GLenum)info.format.internal_format, info.width, info.height, info.depth); break;
|
||||||
|
default:
|
||||||
|
throw EXCEPTION("bad dimension %d", info.dimension);
|
||||||
|
}
|
||||||
//__glcheck glClearTexImage(gl_name, 0, (GLenum)info.format.format, (GLenum)info.format.type, nullptr);
|
//__glcheck glClearTexImage(gl_name, 0, (GLenum)info.format.format, (GLenum)info.format.type, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,10 +606,12 @@ namespace gl
|
|||||||
for (auto &texture : region.m_textures)
|
for (auto &texture : region.m_textures)
|
||||||
{
|
{
|
||||||
texture.second.parent(this);
|
texture.second.parent(this);
|
||||||
|
if (!m_textures.emplace(texture).second)
|
||||||
|
{
|
||||||
|
throw EXCEPTION("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_textures.insert(region.m_textures.begin(), region.m_textures.end());
|
|
||||||
|
|
||||||
if (region.start_address < start_address)
|
if (region.start_address < start_address)
|
||||||
{
|
{
|
||||||
pages_count += (start_address - region.start_address) / vm::page_size;
|
pages_count += (start_address - region.start_address) / vm::page_size;
|
||||||
@ -512,7 +619,9 @@ namespace gl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pages_count = (region.start_address + region.pages_count - start_address) / vm::page_size;
|
//[start_address, region.start_address + region.pages_count * vm::page_size)
|
||||||
|
|
||||||
|
pages_count = (region.start_address + region.pages_count * vm::page_size - start_address) / vm::page_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,16 +667,6 @@ namespace gl
|
|||||||
m_textures.clear();
|
m_textures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void protected_region::lock()
|
|
||||||
{
|
|
||||||
m_mtx.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void protected_region::unlock()
|
|
||||||
{
|
|
||||||
m_mtx.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
cached_texture &texture_cache::entry(const texture_info &info, cache_buffers sync)
|
cached_texture &texture_cache::entry(const texture_info &info, cache_buffers sync)
|
||||||
{
|
{
|
||||||
u32 aligned_address;
|
u32 aligned_address;
|
||||||
@ -595,30 +694,24 @@ namespace gl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<protected_region*> regions = find_regions(aligned_address, aligned_size);
|
std::vector<std::list<protected_region>::iterator> regions = find_regions(aligned_address, aligned_size);
|
||||||
protected_region *region;
|
protected_region *region;
|
||||||
|
|
||||||
if (regions.empty())
|
if (regions.empty())
|
||||||
{
|
{
|
||||||
region = &m_protected_regions[aligned_address];
|
m_protected_regions.emplace_back();
|
||||||
|
region = &m_protected_regions.back();
|
||||||
region->pages_count = aligned_size / vm::page_size;
|
region->pages_count = aligned_size / vm::page_size;
|
||||||
region->start_address = aligned_address;
|
region->start_address = aligned_address;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
region = regions[0];
|
region = &*regions[0];
|
||||||
|
|
||||||
std::vector<u32> remove_addresses;
|
|
||||||
|
|
||||||
for (std::size_t index = 1; index < regions.size(); ++index)
|
for (std::size_t index = 1; index < regions.size(); ++index)
|
||||||
{
|
{
|
||||||
region->combine(*regions[index]);
|
region->combine(*regions[index]);
|
||||||
remove_addresses.push_back(regions[index]->start_address);
|
m_protected_regions.erase(regions[index]);
|
||||||
}
|
|
||||||
|
|
||||||
for (u32 address : remove_addresses)
|
|
||||||
{
|
|
||||||
m_protected_regions.erase(address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->start_address > aligned_address)
|
if (region->start_address > aligned_address)
|
||||||
@ -647,37 +740,37 @@ namespace gl
|
|||||||
{
|
{
|
||||||
for (auto& entry : m_protected_regions)
|
for (auto& entry : m_protected_regions)
|
||||||
{
|
{
|
||||||
if (entry.first > address)
|
if (entry.start_address > address)
|
||||||
{
|
{
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address >= entry.first && address < entry.first + entry.second.size())
|
if (address >= entry.start_address && address < entry.start_address + entry.size())
|
||||||
{
|
{
|
||||||
return &entry.second;
|
return &entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<protected_region*> texture_cache::find_regions(u32 address, u32 size)
|
std::vector<std::list<protected_region>::iterator> texture_cache::find_regions(u32 address, u32 size)
|
||||||
{
|
{
|
||||||
std::vector<protected_region *> result;
|
std::vector<std::list<protected_region>::iterator> result;
|
||||||
|
|
||||||
for (auto& entry : m_protected_regions)
|
for (auto it = m_protected_regions.begin(); it != m_protected_regions.end(); ++it)
|
||||||
{
|
{
|
||||||
if (entry.first >= address + size)
|
if (it->start_address >= address + size)
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.first + entry.second.size() <= address)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push_back(&entry.second);
|
if (it->start_address + it->size() <= address)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -687,7 +780,7 @@ namespace gl
|
|||||||
{
|
{
|
||||||
for (auto& entry : m_protected_regions)
|
for (auto& entry : m_protected_regions)
|
||||||
{
|
{
|
||||||
entry.second.protect();
|
entry.protect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +788,7 @@ namespace gl
|
|||||||
{
|
{
|
||||||
for (auto& entry : m_protected_regions)
|
for (auto& entry : m_protected_regions)
|
||||||
{
|
{
|
||||||
entry.second.clear();
|
entry.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_protected_regions.clear();
|
m_protected_regions.clear();
|
||||||
|
@ -108,9 +108,6 @@ namespace gl
|
|||||||
|
|
||||||
cache_access requires_protection() const;
|
cache_access requires_protection() const;
|
||||||
|
|
||||||
void lock();
|
|
||||||
void unlock();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void create();
|
void create();
|
||||||
void remove();
|
void remove();
|
||||||
@ -126,9 +123,7 @@ namespace gl
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<texture_info, cached_texture, fnv_1a_hasher, bitwise_equals> m_textures;
|
std::unordered_map<texture_info, cached_texture, fnv_1a_hasher, bitwise_equals> m_textures;
|
||||||
|
|
||||||
u32 m_current_protection = 0;
|
u32 m_current_protection = 0;
|
||||||
std::mutex m_mtx;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
u32 size() const
|
u32 size() const
|
||||||
@ -150,19 +145,16 @@ namespace gl
|
|||||||
cached_texture& add(const texture_info& info);
|
cached_texture& add(const texture_info& info);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void lock();
|
|
||||||
void unlock();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class texture_cache
|
class texture_cache
|
||||||
{
|
{
|
||||||
std::map<u32, protected_region> m_protected_regions;
|
std::list<protected_region> m_protected_regions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cached_texture &entry(const texture_info &info, cache_buffers sync = cache_buffers::none);
|
cached_texture &entry(const texture_info &info, cache_buffers sync = cache_buffers::none);
|
||||||
protected_region *find_region(u32 address);
|
protected_region *find_region(u32 address);
|
||||||
std::vector<protected_region*> find_regions(u32 address, u32 size);
|
std::vector<std::list<protected_region>::iterator> find_regions(u32 address, u32 size);
|
||||||
void update_protection();
|
void update_protection();
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
@ -178,9 +178,13 @@ void rsx::gl_texture::bind(gl::texture_cache& cache, rsx::texture& tex)
|
|||||||
info.swizzled = is_swizzled;
|
info.swizzled = is_swizzled;
|
||||||
info.target = target;
|
info.target = target;
|
||||||
info.mipmap = target != gl::texture::target::texture_rectangle ? tex.mipmap() : 1;
|
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;
|
if (info.mipmap > 1)
|
||||||
info.lod_bias = tex.bias();
|
{
|
||||||
|
info.min_lod = tex.min_lod() >> 8;
|
||||||
|
info.max_lod = tex.max_lod() >> 8;
|
||||||
|
info.lod_bias = tex.bias();
|
||||||
|
}
|
||||||
|
|
||||||
if (is_compressed)
|
if (is_compressed)
|
||||||
{
|
{
|
||||||
|
@ -180,14 +180,12 @@ namespace rsx
|
|||||||
|
|
||||||
switch (tile->comp)
|
switch (tile->comp)
|
||||||
{
|
{
|
||||||
case CELL_GCM_COMPMODE_C32_2X1:
|
|
||||||
case CELL_GCM_COMPMODE_DISABLED:
|
case CELL_GCM_COMPMODE_DISABLED:
|
||||||
for (int y = 0; y < height; ++y)
|
for (int y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
memcpy(ptr + (offset_y + y) * tile->pitch + offset_x, (u8*)src + pitch * y, pitch);
|
memcpy(ptr + (offset_y + y) * tile->pitch + offset_x, (u8*)src + pitch * y, pitch);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
case CELL_GCM_COMPMODE_C32_2X1:
|
case CELL_GCM_COMPMODE_C32_2X1:
|
||||||
for (u32 y = 0; y < height; ++y)
|
for (u32 y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
@ -200,7 +198,6 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
case CELL_GCM_COMPMODE_C32_2X2:
|
case CELL_GCM_COMPMODE_C32_2X2:
|
||||||
for (u32 y = 0; y < height; ++y)
|
for (u32 y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
@ -233,14 +230,12 @@ namespace rsx
|
|||||||
|
|
||||||
switch (tile->comp)
|
switch (tile->comp)
|
||||||
{
|
{
|
||||||
case CELL_GCM_COMPMODE_C32_2X1:
|
|
||||||
case CELL_GCM_COMPMODE_DISABLED:
|
case CELL_GCM_COMPMODE_DISABLED:
|
||||||
for (int y = 0; y < height; ++y)
|
for (int y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
memcpy((u8*)dst + pitch * y, ptr + (offset_y + y) * tile->pitch + offset_x, pitch);
|
memcpy((u8*)dst + pitch * y, ptr + (offset_y + y) * tile->pitch + offset_x, pitch);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
case CELL_GCM_COMPMODE_C32_2X1:
|
case CELL_GCM_COMPMODE_C32_2X1:
|
||||||
for (u32 y = 0; y < height; ++y)
|
for (u32 y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
@ -252,7 +247,6 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
case CELL_GCM_COMPMODE_C32_2X2:
|
case CELL_GCM_COMPMODE_C32_2X2:
|
||||||
for (u32 y = 0; y < height; ++y)
|
for (u32 y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
@ -845,7 +839,7 @@ namespace rsx
|
|||||||
|
|
||||||
tiled_region thread::get_tiled_address(u32 offset, u32 location)
|
tiled_region thread::get_tiled_address(u32 offset, u32 location)
|
||||||
{
|
{
|
||||||
u32 address = get_address(offset, location);
|
u32 address;
|
||||||
|
|
||||||
GcmTileInfo *tile = find_tile(offset, location);
|
GcmTileInfo *tile = find_tile(offset, location);
|
||||||
u32 base = 0;
|
u32 base = 0;
|
||||||
@ -855,6 +849,10 @@ namespace rsx
|
|||||||
base = offset - tile->offset;
|
base = offset - tile->offset;
|
||||||
address = get_address(tile->offset, location);
|
address = get_address(tile->offset, location);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
address = get_address(offset, location);
|
||||||
|
}
|
||||||
|
|
||||||
return{ address, base, tile, (u8*)vm::base(address) };
|
return{ address, base, tile, (u8*)vm::base(address) };
|
||||||
}
|
}
|
||||||
|
@ -344,8 +344,8 @@ namespace rsx
|
|||||||
u8 in_inter = method_registers[NV3089_IMAGE_IN_FORMAT] >> 24;
|
u8 in_inter = method_registers[NV3089_IMAGE_IN_FORMAT] >> 24;
|
||||||
u32 src_color_format = method_registers[NV3089_SET_COLOR_FORMAT];
|
u32 src_color_format = method_registers[NV3089_SET_COLOR_FORMAT];
|
||||||
|
|
||||||
f32 in_x = (method_registers[NV3089_IMAGE_IN] & 0xffff) / 16.f;
|
f32 in_x = (arg & 0xffff) / 16.f;
|
||||||
f32 in_y = (method_registers[NV3089_IMAGE_IN] >> 16) / 16.f;
|
f32 in_y = (arg >> 16) / 16.f;
|
||||||
|
|
||||||
if (in_origin != CELL_GCM_TRANSFER_ORIGIN_CORNER)
|
if (in_origin != CELL_GCM_TRANSFER_ORIGIN_CORNER)
|
||||||
{
|
{
|
||||||
@ -395,7 +395,7 @@ namespace rsx
|
|||||||
u32 in_bpp = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? 2 : 4; // bytes per pixel
|
u32 in_bpp = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? 2 : 4; // bytes per pixel
|
||||||
u32 out_bpp = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? 2 : 4;
|
u32 out_bpp = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? 2 : 4;
|
||||||
|
|
||||||
u32 in_offset = u32(in_x * in_bpp + in_pitch * in_y);
|
u32 in_offset = u32(in_x) * u32(in_bpp + in_pitch * in_y);
|
||||||
u32 out_offset = out_x * out_bpp + out_pitch * out_y;
|
u32 out_offset = out_x * out_bpp + out_pitch * out_y;
|
||||||
|
|
||||||
tiled_region src_region = rsx->get_tiled_address(src_offset + in_offset, src_dma & 0xf);//get_address(src_offset, src_dma);
|
tiled_region src_region = rsx->get_tiled_address(src_offset + in_offset, src_dma & 0xf);//get_address(src_offset, src_dma);
|
||||||
@ -473,7 +473,7 @@ namespace rsx
|
|||||||
if (size > src_region.tile->size - src_region.base)
|
if (size > src_region.tile->size - src_region.base)
|
||||||
{
|
{
|
||||||
u32 diff = size - (src_region.tile->size - src_region.base);
|
u32 diff = size - (src_region.tile->size - src_region.base);
|
||||||
slice_h -= diff / in_pitch + (diff % in_pitch ? 1 : 0);
|
slice_h -= (diff + in_pitch - 1) / in_pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (out_pitch != in_pitch || out_pitch != out_bpp * out_w)
|
if (out_pitch != in_pitch || out_pitch != out_bpp * out_w || in_pitch != in_bpp * in_w)
|
||||||
{
|
{
|
||||||
for (u32 y = 0; y < out_h; ++y)
|
for (u32 y = 0; y < out_h; ++y)
|
||||||
{
|
{
|
||||||
@ -561,10 +561,12 @@ namespace rsx
|
|||||||
u8* linear_pixels = pixels_src;
|
u8* linear_pixels = pixels_src;
|
||||||
u8* swizzled_pixels = temp2.get();
|
u8* swizzled_pixels = temp2.get();
|
||||||
|
|
||||||
|
std::unique_ptr<u8[]> sw_temp;
|
||||||
|
|
||||||
// Check and pad texture out if we are given non square texture for swizzle to be correct
|
// Check and pad texture out if we are given non square texture for swizzle to be correct
|
||||||
if (sw_width != out_w || sw_height != out_h)
|
if (sw_width != out_w || sw_height != out_h)
|
||||||
{
|
{
|
||||||
std::unique_ptr<u8[]> sw_temp(new u8[out_bpp * sw_width * sw_height]);
|
sw_temp.reset(new u8[out_bpp * sw_width * sw_height]);
|
||||||
|
|
||||||
switch (out_bpp)
|
switch (out_bpp)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user