mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
fixed random crashes
improved nv0039::buffer_notify added print_call_stack utility (TODO)
This commit is contained in:
parent
8aeac09741
commit
10ec26ace8
7 changed files with 159 additions and 99 deletions
|
@ -441,7 +441,7 @@ void GLGSRender::end()
|
|||
int location;
|
||||
if (m_program->uniforms.has_location("tex" + std::to_string(i), &location))
|
||||
{
|
||||
__glcheck rsx::gl_texture::bind(m_texture_cache, textures[i]);
|
||||
__glcheck rsx::gl_texture::bind(texture_cache, textures[i]);
|
||||
__glcheck glProgramUniform1i(m_program->id(), location, i);
|
||||
}
|
||||
}
|
||||
|
@ -708,7 +708,7 @@ void GLGSRender::end()
|
|||
|
||||
rsx::thread::end();
|
||||
|
||||
m_texture_cache.update_protection();
|
||||
texture_cache.update_protection();
|
||||
}
|
||||
|
||||
void GLGSRender::set_viewport()
|
||||
|
@ -829,7 +829,7 @@ void GLGSRender::on_exit()
|
|||
}
|
||||
}
|
||||
|
||||
void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
||||
bool nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
||||
{
|
||||
//LOG_NOTICE(RSX, "nv4097_clear_surface(0x%x)", arg);
|
||||
|
||||
|
@ -844,7 +844,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
|||
if ((arg & (depth_stencil | color_mask)) == 0)
|
||||
{
|
||||
//do nothing
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -941,13 +941,22 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
|||
{
|
||||
__glcheck glClear(mask);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
using rsx_method_impl_t = void(*)(u32, GLGSRender*);
|
||||
bool nv3089_image_in(u32 arg, GLGSRender* renderer)
|
||||
{
|
||||
//TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
using rsx_method_impl_t = bool(*)(u32, GLGSRender*);
|
||||
|
||||
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 },
|
||||
};
|
||||
|
||||
bool GLGSRender::do_method(u32 cmd, u32 arg)
|
||||
|
@ -959,8 +968,7 @@ bool GLGSRender::do_method(u32 cmd, u32 arg)
|
|||
return false;
|
||||
}
|
||||
|
||||
found->second(arg, this);
|
||||
return true;
|
||||
return found->second(arg, this);
|
||||
}
|
||||
|
||||
bool GLGSRender::load_program()
|
||||
|
@ -1205,7 +1213,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
|||
|
||||
info.swizzled = swizzled;
|
||||
|
||||
cached_color_buffers[index] = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
|
||||
cached_color_buffers[index] = &texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
|
||||
draw_fbo.color[index] = cached_color_buffers[index]->view();
|
||||
});
|
||||
|
||||
|
@ -1269,7 +1277,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
|||
|
||||
info.format.remap = { GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO };
|
||||
|
||||
__glcheck cached_depth_buffer = &m_texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
|
||||
__glcheck cached_depth_buffer = &texture_cache.entry(info, skip_reading ? gl::cache_buffers::none : gl::cache_buffers::local);
|
||||
|
||||
switch (m_surface.depth_format)
|
||||
{
|
||||
|
@ -1333,7 +1341,7 @@ void GLGSRender::flip(int buffer)
|
|||
glDisable(GL_LOGIC_OP);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
gl::cached_texture& texture = m_texture_cache.entry(surface_info(rsx::surface_color_format::a8r8g8b8, gcm_buffers[buffer].offset,
|
||||
gl::cached_texture& texture = texture_cache.entry(surface_info(rsx::surface_color_format::a8r8g8b8, gcm_buffers[buffer].offset,
|
||||
CELL_GCM_LOCATION_LOCAL, buffer_width, buffer_height, buffer_pitch), gl::cache_buffers::local);
|
||||
|
||||
//std::lock_guard<gl::cached_texture> lock(texture);
|
||||
|
@ -1389,7 +1397,7 @@ u64 GLGSRender::timestamp() const
|
|||
|
||||
bool GLGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
{
|
||||
if (auto region = m_texture_cache.find_region(address))
|
||||
if (auto region = texture_cache.find_region(address))
|
||||
{
|
||||
//std::lock_guard<gl::protected_region> lock(*region);
|
||||
|
||||
|
|
|
@ -28,9 +28,8 @@ private:
|
|||
|
||||
texture_buffer_pair m_gl_attrib_buffers[rsx::limits::vertex_count];
|
||||
|
||||
gl::texture_cache m_texture_cache;
|
||||
|
||||
public:
|
||||
gl::texture_cache texture_cache;
|
||||
gl::fbo draw_fbo;
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,6 +1,42 @@
|
|||
#include "stdafx.h"
|
||||
#include "gl_helpers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <DbgHelp.h>
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
#endif
|
||||
|
||||
//TODO: find proper place
|
||||
void print_call_stack(int skip)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE current_process = GetCurrentProcess();
|
||||
SymInitialize(current_process, nullptr, true);
|
||||
|
||||
void* stack[61];
|
||||
u32 frames_count = CaptureStackBackTrace(skip + 1, 61 - skip, stack, nullptr);
|
||||
|
||||
u32 max_sym_length = 255;
|
||||
|
||||
std::unique_ptr<SYMBOL_INFO, decltype(&std::free)> sym_info
|
||||
{
|
||||
(SYMBOL_INFO*)std::calloc(sizeof(SYMBOL_INFO) + (max_sym_length + 1) * sizeof(char), 1),
|
||||
std::free
|
||||
};
|
||||
|
||||
sym_info->MaxNameLen = max_sym_length;
|
||||
sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
|
||||
LOG_ERROR(GENERAL, "CALL STACK:");
|
||||
|
||||
for (s32 i = frames_count - 1; i > 0; --i)
|
||||
{
|
||||
SymFromAddr(current_process, (DWORD64)stack[i], 0, sym_info.get());
|
||||
LOG_ERROR(GENERAL, "%u: %s:%u - 0x%0X", i, sym_info->Name, sym_info->Index, sym_info->Address);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
const fbo screen{};
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "OpenGL.h"
|
||||
#include "../GCM.h"
|
||||
|
||||
void print_call_stack(int skip);
|
||||
|
||||
namespace gl
|
||||
{
|
||||
#if 1//def _DEBUG
|
||||
|
@ -44,6 +46,7 @@ namespace gl
|
|||
default: error = "unknown error"; break;
|
||||
}
|
||||
|
||||
print_call_stack(1);
|
||||
throw std::runtime_error(fmt::format("OpenGL error: %s. file '%s' function '%s' line %ld", error.c_str(), file, function, line));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,19 +18,19 @@ namespace gl
|
|||
void cached_texture::read()
|
||||
{
|
||||
cached_texture* found_texture = nullptr;
|
||||
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)
|
||||
{
|
||||
if ((texture.m_state & cache_entry_state::local_synchronized) == cache_entry_state::invalid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture.info->start_address != info->start_address ||
|
||||
texture.info->pitch != info->pitch ||
|
||||
texture.info->height < info->height ||
|
||||
texture.info->width < info->width)
|
||||
if (texture.info.start_address != info.start_address ||
|
||||
texture.info.pitch != info.pitch ||
|
||||
texture.info.height < info.height ||
|
||||
texture.info.width < info.width)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -42,35 +42,35 @@ namespace gl
|
|||
{
|
||||
//read from local
|
||||
__glcheck glCopyImageSubData(
|
||||
found_texture->gl_name, (GLenum)found_texture->info->target, 0, 0, 0, 0,
|
||||
gl_name, (GLenum)info->target, 0, 0, 0, 0,
|
||||
info->width, info->height, info->depth);
|
||||
found_texture->gl_name, (GLenum)found_texture->info.target, 0, 0, 0, 0,
|
||||
gl_name, (GLenum)info.target, 0, 0, 0, 0,
|
||||
info.width, info.height, info.depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read from host
|
||||
//flush all local textures at region
|
||||
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);
|
||||
});
|
||||
|
||||
bind();
|
||||
|
||||
if (info->format.format == gl::texture::format::depth || info->format.format == gl::texture::format::depth_stencil)
|
||||
if (info.format.format == gl::texture::format::depth || info.format.format == gl::texture::format::depth_stencil)
|
||||
{
|
||||
gl::buffer pbo_depth;
|
||||
|
||||
__glcheck pbo_depth.create(info->size());
|
||||
__glcheck pbo_depth.create(info.size());
|
||||
__glcheck pbo_depth.map([&](GLubyte* pixels)
|
||||
{
|
||||
switch (info->format.bpp)
|
||||
switch (info.format.bpp)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
u16 *dst = (u16*)pixels;
|
||||
const be_t<u16>* src = (const be_t<u16>*)vm::base_priv(info->start_address);
|
||||
for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i)
|
||||
const be_t<u16>* src = (const be_t<u16>*)vm::base_priv(info.start_address);
|
||||
for (u32 i = 0, end = info.pitch / info.format.bpp * info.height; i < end; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
@ -80,8 +80,8 @@ namespace gl
|
|||
case 4:
|
||||
{
|
||||
u32 *dst = (u32*)pixels;
|
||||
const be_t<u32>* src = (const be_t<u32>*)vm::base_priv(info->start_address);
|
||||
for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i)
|
||||
const be_t<u32>* src = (const be_t<u32>*)vm::base_priv(info.start_address);
|
||||
for (u32 i = 0, end = info.pitch / info.format.bpp * info.height; i < end; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
@ -94,47 +94,47 @@ namespace gl
|
|||
}, gl::buffer::access::write);
|
||||
|
||||
gl::pixel_unpack_settings{}
|
||||
.row_length(info->pitch / info->format.bpp)
|
||||
.row_length(info.pitch / info.format.bpp)
|
||||
.aligment(1)
|
||||
.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();
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_depth.id());
|
||||
|
||||
__glcheck glTexSubImage2D((GLenum)info->target, 0, 0, 0, info->width, info->height,
|
||||
(GLenum)info->format.format, (GLenum)info->format.type, nullptr);
|
||||
__glcheck glTexSubImage2D((GLenum)info.target, 0, 0, 0, info.width, info.height,
|
||||
(GLenum)info.format.format, (GLenum)info.format.type, nullptr);
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
else if (info->compressed_size)
|
||||
else if (info.compressed_size)
|
||||
{
|
||||
__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));
|
||||
__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));
|
||||
}
|
||||
else
|
||||
{
|
||||
void *pixels = vm::base_priv(info->start_address);
|
||||
void *pixels = vm::base_priv(info.start_address);
|
||||
|
||||
std::unique_ptr<u8[]> linear_pixels;
|
||||
|
||||
if (info->swizzled && (info->format.flags & texture_flags::allow_swizzle) != texture_flags::none)
|
||||
if (info.swizzled && (info.format.flags & texture_flags::allow_swizzle) != texture_flags::none)
|
||||
{
|
||||
linear_pixels.reset(new u8[info->size()]);
|
||||
switch (info->format.bpp)
|
||||
linear_pixels.reset(new u8[info.size()]);
|
||||
switch (info.format.bpp)
|
||||
{
|
||||
case 1:
|
||||
rsx::convert_linear_swizzle<u8>(pixels, linear_pixels.get(), info->width, info->height, true);
|
||||
rsx::convert_linear_swizzle<u8>(pixels, linear_pixels.get(), info.width, info.height, true);
|
||||
break;
|
||||
case 2:
|
||||
rsx::convert_linear_swizzle<u16>(pixels, linear_pixels.get(), info->width, info->height, true);
|
||||
rsx::convert_linear_swizzle<u16>(pixels, linear_pixels.get(), info.width, info.height, true);
|
||||
break;
|
||||
case 4:
|
||||
rsx::convert_linear_swizzle<u32>(pixels, linear_pixels.get(), info->width, info->height, true);
|
||||
rsx::convert_linear_swizzle<u32>(pixels, linear_pixels.get(), info.width, info.height, true);
|
||||
break;
|
||||
case 8:
|
||||
rsx::convert_linear_swizzle<u64>(pixels, linear_pixels.get(), info->width, info->height, true);
|
||||
rsx::convert_linear_swizzle<u64>(pixels, linear_pixels.get(), info.width, info.height, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -145,22 +145,22 @@ namespace gl
|
|||
}
|
||||
|
||||
gl::pixel_unpack_settings{}
|
||||
.row_length(info->pitch / info->format.bpp)
|
||||
.row_length(info.pitch / info.format.bpp)
|
||||
.aligment(1)
|
||||
.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();
|
||||
|
||||
__glcheck glTexSubImage2D((GLenum)info->target, 0, 0, 0, info->width, info->height,
|
||||
(GLenum)info->format.format, (GLenum)info->format.type, pixels);
|
||||
__glcheck glTexSubImage2D((GLenum)info.target, 0, 0, 0, info.width, info.height,
|
||||
(GLenum)info.format.format, (GLenum)info.format.type, pixels);
|
||||
}
|
||||
|
||||
if (info->mipmap > 1)
|
||||
if (info.mipmap > 1)
|
||||
{
|
||||
__glcheck glTexParameteri((GLenum)info->target, GL_TEXTURE_MIN_LOD, info->min_lod);
|
||||
__glcheck glTexParameteri((GLenum)info->target, GL_TEXTURE_MAX_LOD, info->max_lod);
|
||||
__glcheck glTexParameterf((GLenum)info->target, GL_TEXTURE_LOD_BIAS, info->lod_bias);
|
||||
__glcheck glTexParameteri((GLenum)info.target, GL_TEXTURE_MIN_LOD, info.min_lod);
|
||||
__glcheck glTexParameteri((GLenum)info.target, GL_TEXTURE_MAX_LOD, info.max_lod);
|
||||
__glcheck glTexParameterf((GLenum)info.target, GL_TEXTURE_LOD_BIAS, info.lod_bias);
|
||||
|
||||
__glcheck glGenerateMipmap((GLenum)info->target);
|
||||
__glcheck glGenerateMipmap((GLenum)info.target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,33 +171,33 @@ namespace gl
|
|||
{
|
||||
bind();
|
||||
|
||||
if (info->format.format == gl::texture::format::depth || info->format.format == gl::texture::format::depth_stencil)
|
||||
if (info.format.format == gl::texture::format::depth || info.format.format == gl::texture::format::depth_stencil)
|
||||
{
|
||||
//LOG_ERROR(RSX, "write depth color to host[0x%x]", info->start_address);
|
||||
//LOG_ERROR(RSX, "write depth color to host[0x%x]", info.start_address);
|
||||
|
||||
gl::buffer pbo_depth;
|
||||
|
||||
pbo_depth.create(info->size());
|
||||
pbo_depth.create(info.size());
|
||||
|
||||
gl::pixel_pack_settings{}
|
||||
.row_length(info->pitch / info->format.bpp)
|
||||
.row_length(info.pitch / info.format.bpp)
|
||||
.aligment(1)
|
||||
//.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();
|
||||
|
||||
__glcheck glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_depth.id());
|
||||
__glcheck glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, nullptr);
|
||||
__glcheck glGetTexImage((GLenum)info.target, 0, (GLenum)info.format.format, (GLenum)info.format.type, nullptr);
|
||||
__glcheck glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
||||
__glcheck pbo_depth.map([&](GLubyte* pixels)
|
||||
{
|
||||
switch (info->format.bpp)
|
||||
switch (info.format.bpp)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
const u16 *src = (const u16*)pixels;
|
||||
be_t<u16>* dst = (be_t<u16>*)vm::base_priv(info->start_address);
|
||||
for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i)
|
||||
be_t<u16>* dst = (be_t<u16>*)vm::base_priv(info.start_address);
|
||||
for (u32 i = 0, end = info.pitch / info.format.bpp * info.height; i < end; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
@ -207,8 +207,8 @@ namespace gl
|
|||
case 4:
|
||||
{
|
||||
const u32 *src = (const u32*)pixels;
|
||||
be_t<u32>* dst = (be_t<u32>*)vm::base_priv(info->start_address);
|
||||
for (u32 i = 0, end = info->pitch / info->format.bpp * info->height; i < end; ++i)
|
||||
be_t<u32>* dst = (be_t<u32>*)vm::base_priv(info.start_address);
|
||||
for (u32 i = 0, end = info.pitch / info.format.bpp * info.height; i < end; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
@ -221,25 +221,25 @@ namespace gl
|
|||
|
||||
}, gl::buffer::access::read);
|
||||
}
|
||||
else if (info->compressed_size)
|
||||
else if (info.compressed_size)
|
||||
{
|
||||
LOG_ERROR(RSX, "writing compressed texture[0x%x] to host buffer", info->start_address);
|
||||
LOG_ERROR(RSX, "writing compressed texture[0x%x] to host buffer", info.start_address);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->swizzled && (info->format.flags & texture_flags::allow_swizzle) != texture_flags::none)
|
||||
if (info.swizzled && (info.format.flags & texture_flags::allow_swizzle) != texture_flags::none)
|
||||
{
|
||||
//TODO
|
||||
LOG_ERROR(RSX, "writing swizzled texture[0x%x] to host buffer", info->start_address);
|
||||
LOG_ERROR(RSX, "writing swizzled texture[0x%x] to host buffer", info.start_address);
|
||||
}
|
||||
|
||||
gl::pixel_pack_settings{}
|
||||
.row_length(info->pitch / info->format.bpp)
|
||||
.row_length(info.pitch / info.format.bpp)
|
||||
.aligment(1)
|
||||
.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();
|
||||
|
||||
__glcheck glGetTexImage((GLenum)info->target, 0, (GLenum)info->format.format, (GLenum)info->format.type, vm::base_priv(info->start_address));
|
||||
__glcheck glGetTexImage((GLenum)info.target, 0, (GLenum)info.format.format, (GLenum)info.format.type, vm::base_priv(info.start_address));
|
||||
}
|
||||
|
||||
ignore(gl::cache_buffers::all);
|
||||
|
@ -280,13 +280,13 @@ namespace gl
|
|||
if ((buffers & cache_buffers::host) != cache_buffers::none)
|
||||
{
|
||||
m_state &= ~cache_entry_state::host_synchronized;
|
||||
m_parent_region->for_each(info->start_address, info->size(), [this](cached_texture& texture)
|
||||
m_parent_region->for_each(info.start_address, info.size(), [this](cached_texture& texture)
|
||||
{
|
||||
if (std::addressof(texture) != this)
|
||||
{
|
||||
//LOG_WARNING(RSX, "cached_texture[0x%x,0x%x) invalidate cached_texture[0x%x, 0x%x)",
|
||||
// info->start_address, info->start_address + info->size(),
|
||||
// texture.info->start_address, texture.info->start_address + texture.info->size());
|
||||
// info.start_address, info.start_address + info.size(),
|
||||
// texture.info.start_address, texture.info.start_address + texture.info.size());
|
||||
texture.invalidate(cache_buffers::local);
|
||||
}
|
||||
});
|
||||
|
@ -368,7 +368,7 @@ namespace gl
|
|||
__glcheck glActiveTexture(GL_TEXTURE0 + index);
|
||||
}
|
||||
|
||||
__glcheck glBindTexture((GLenum)info->target, gl_name);
|
||||
__glcheck glBindTexture((GLenum)info.target, gl_name);
|
||||
}
|
||||
|
||||
void cached_texture::create()
|
||||
|
@ -378,8 +378,8 @@ namespace gl
|
|||
glGenTextures(1, &gl_name);
|
||||
|
||||
bind();
|
||||
__glcheck glTexStorage2D((GLenum)info->target, info->mipmap, (GLenum)info->format.internal_format, info->width, info->height);
|
||||
//__glcheck glClearTexImage(gl_name, 0, (GLenum)info->format.format, (GLenum)info->format.type, nullptr);
|
||||
__glcheck glTexStorage2D((GLenum)info.target, info.mipmap, (GLenum)info.format.internal_format, info.width, info.height);
|
||||
//__glcheck glClearTexImage(gl_name, 0, (GLenum)info.format.format, (GLenum)info.format.type, nullptr);
|
||||
}
|
||||
|
||||
void cached_texture::remove()
|
||||
|
@ -528,7 +528,7 @@ namespace gl
|
|||
|
||||
auto& texture_info = *result.first;
|
||||
|
||||
texture_info.second.info = &texture_info.first;
|
||||
texture_info.second.info = texture_info.first;
|
||||
texture_info.second.parent(this);
|
||||
|
||||
return texture_info.second;
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace gl
|
|||
|
||||
struct cached_texture
|
||||
{
|
||||
const texture_info *info;
|
||||
texture_info info;
|
||||
GLuint gl_name = 0;
|
||||
|
||||
private:
|
||||
|
@ -103,7 +103,7 @@ namespace gl
|
|||
|
||||
gl::texture_view view() const
|
||||
{
|
||||
return{ info->target, gl_name };
|
||||
return{ info.target, gl_name };
|
||||
}
|
||||
|
||||
cache_access requires_protection() const;
|
||||
|
|
|
@ -604,31 +604,45 @@ namespace rsx
|
|||
{
|
||||
force_inline void buffer_notify(u32 arg)
|
||||
{
|
||||
const u32 inPitch = method_registers[NV0039_PITCH_IN];
|
||||
const u32 outPitch = method_registers[NV0039_PITCH_OUT];
|
||||
const u32 lineLength = method_registers[NV0039_LINE_LENGTH_IN];
|
||||
const u32 lineCount = method_registers[NV0039_LINE_COUNT];
|
||||
const u8 outFormat = method_registers[NV0039_FORMAT] >> 8;
|
||||
const u8 inFormat = method_registers[NV0039_FORMAT];
|
||||
u32 in_pitch = method_registers[NV0039_PITCH_IN];
|
||||
u32 out_pitch = method_registers[NV0039_PITCH_OUT];
|
||||
const u32 line_length = method_registers[NV0039_LINE_LENGTH_IN];
|
||||
const u32 line_count = method_registers[NV0039_LINE_COUNT];
|
||||
const u8 out_format = method_registers[NV0039_FORMAT] >> 8;
|
||||
const u8 in_format = method_registers[NV0039_FORMAT];
|
||||
const u32 notify = arg;
|
||||
|
||||
// The existing GCM commands use only the value 0x1 for inFormat and outFormat
|
||||
if (inFormat != 0x01 || outFormat != 0x01)
|
||||
if (in_format != 0x01 || out_format != 0x01)
|
||||
{
|
||||
LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat);
|
||||
LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", in_format, out_format);
|
||||
}
|
||||
|
||||
if (lineCount == 1 && !inPitch && !outPitch && !notify)
|
||||
if (!in_pitch)
|
||||
{
|
||||
std::memcpy(
|
||||
vm::base(get_address(method_registers[NV0039_OFFSET_OUT], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT])),
|
||||
vm::base(get_address(method_registers[NV0039_OFFSET_IN], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN])),
|
||||
lineLength);
|
||||
in_pitch = line_length;
|
||||
}
|
||||
|
||||
if (!out_pitch)
|
||||
{
|
||||
out_pitch = line_length;
|
||||
}
|
||||
|
||||
u8 *dst = (u8*)vm::base(get_address(method_registers[NV0039_OFFSET_OUT], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT]));
|
||||
const u8 *src = (u8*)vm::base(get_address(method_registers[NV0039_OFFSET_IN], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN]));
|
||||
|
||||
if (in_pitch == out_pitch && out_pitch == line_length)
|
||||
{
|
||||
std::memcpy(dst, src, line_length * line_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x",
|
||||
method_registers[NV0039_OFFSET_IN], method_registers[NV0039_OFFSET_OUT], inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify);
|
||||
for (u32 i = 0; i < line_count; ++i)
|
||||
{
|
||||
std::memcpy(dst, src, line_length);
|
||||
dst += out_pitch;
|
||||
src += in_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue