mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 14:31:24 +12:00
Fixed OpenGL renderer crash
Temporary downgraded OpenGL requirements to OpenGL 3.1 (GLSL 1.40) Fixed some D3D12 Renderer compilation errors
This commit is contained in:
parent
4fdeeace66
commit
3721941ffb
8 changed files with 163 additions and 151 deletions
|
@ -179,14 +179,14 @@ ComPtr<ID3D12Resource> uploadSingleTexture(
|
|||
*/
|
||||
static
|
||||
void updateExistingTexture(
|
||||
const RSXTexture &texture,
|
||||
const rsx::texture &texture,
|
||||
ID3D12GraphicsCommandList *commandList,
|
||||
DataHeap<ID3D12Resource, 65536> &textureBuffersHeap,
|
||||
ID3D12Resource *existingTexture)
|
||||
{
|
||||
size_t w = texture.GetWidth(), h = texture.GetHeight();
|
||||
size_t w = texture.width(), h = texture.height();
|
||||
|
||||
int format = texture.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format);
|
||||
|
||||
size_t textureSize = getPlacedTextureStorageSpace(texture, 256);
|
||||
|
@ -309,12 +309,12 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
|
|||
vramTexture = ItRTT->second;
|
||||
isRenderTarget = true;
|
||||
}
|
||||
else if (cachedTex != nullptr && (cachedTex->first == TextureEntry(format, w, h, m_textures[i].GetMipmap())))
|
||||
else if (cachedTex != nullptr && (cachedTex->first == TextureEntry(format, w, h, textures[i].mipmap())))
|
||||
{
|
||||
if (cachedTex->first.m_isDirty)
|
||||
{
|
||||
updateExistingTexture(m_textures[i], cmdlist, m_textureUploadData, cachedTex->second.Get());
|
||||
m_textureCache.protectData(texaddr, texaddr, getTextureSize(m_textures[i]));
|
||||
updateExistingTexture(textures[i], cmdlist, m_textureUploadData, cachedTex->second.Get());
|
||||
m_textureCache.protectData(texaddr, texaddr, getTextureSize(textures[i]));
|
||||
}
|
||||
vramTexture = cachedTex->second.Get();
|
||||
}
|
||||
|
@ -322,9 +322,9 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
|
|||
{
|
||||
if (cachedTex != nullptr)
|
||||
getCurrentResourceStorage().m_dirtyTextures.push_back(m_textureCache.removeFromCache(texaddr));
|
||||
ComPtr<ID3D12Resource> tex = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData);
|
||||
ComPtr<ID3D12Resource> tex = uploadSingleTexture(textures[i], m_device.Get(), cmdlist, m_textureUploadData);
|
||||
vramTexture = tex.Get();
|
||||
m_textureCache.storeAndProtectData(texaddr, texaddr, getTextureSize(m_textures[i]), format, w, h, m_textures[i].mipmap(), tex);
|
||||
m_textureCache.storeAndProtectData(texaddr, texaddr, getTextureSize(textures[i]), format, w, h, textures[i].mipmap(), tex);
|
||||
}
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||
|
|
|
@ -28,7 +28,7 @@ std::string GLFragmentDecompilerThread::compareFunction(COMPARE f, const std::st
|
|||
|
||||
void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
||||
{
|
||||
OS << "#version 420" << std::endl;
|
||||
OS << "#version 140" << std::endl;
|
||||
}
|
||||
|
||||
void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
|
||||
|
@ -110,7 +110,7 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
OS << " " << table[i].first << " = " << table[i].second << ";" << std::endl;
|
||||
}
|
||||
|
||||
OS << "};" << std::endl;
|
||||
OS << "}" << std::endl;
|
||||
}
|
||||
|
||||
void GLFragmentDecompilerThread::Task()
|
||||
|
|
|
@ -605,28 +605,27 @@ void GLGSRender::begin()
|
|||
|
||||
__glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST))
|
||||
{
|
||||
__glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]);
|
||||
__glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]);
|
||||
}
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))
|
||||
if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT)))
|
||||
{
|
||||
__glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]);
|
||||
}
|
||||
|
||||
__glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]);
|
||||
__glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]);
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER);
|
||||
|
||||
enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER);
|
||||
if (enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST))
|
||||
{
|
||||
//TODO: NV4097_SET_ALPHA_REF must be converted to f32
|
||||
//glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF]));
|
||||
}
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND))
|
||||
{
|
||||
u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR];
|
||||
u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR];
|
||||
|
@ -667,14 +666,14 @@ void GLGSRender::begin()
|
|||
__glcheck glBlendEquationSeparate(equation_rgb, equation_a);
|
||||
}
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST))
|
||||
{
|
||||
__glcheck glStencilFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC], rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF],
|
||||
rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]);
|
||||
__glcheck glStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL], rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL],
|
||||
rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]);
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE], GL_STENCIL_TEST_TWO_SIDE_EXT))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE], GL_STENCIL_TEST_TWO_SIDE_EXT))
|
||||
{
|
||||
__glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_MASK]);
|
||||
__glcheck glStencilFuncSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC],
|
||||
|
@ -693,14 +692,14 @@ void GLGSRender::begin()
|
|||
__glcheck enable(blend_mrt & 8, GL_BLEND, GL_COLOR_ATTACHMENT3);
|
||||
}
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP))
|
||||
{
|
||||
__glcheck glLogicOp(rsx::method_registers[NV4097_SET_LOGIC_OP]);
|
||||
}
|
||||
|
||||
u32 line_width = rsx::method_registers[NV4097_SET_LINE_WIDTH];
|
||||
__glcheck glLineWidth((line_width >> 3) + (line_width & 7) / 8.f);
|
||||
enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH);
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH);
|
||||
|
||||
//TODO
|
||||
//NV4097_SET_ANISO_SPREAD
|
||||
|
@ -740,16 +739,16 @@ void GLGSRender::begin()
|
|||
u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf;
|
||||
|
||||
//TODO
|
||||
if (enable(clip_plane_0, GL_CLIP_DISTANCE0)) {}
|
||||
if (enable(clip_plane_1, GL_CLIP_DISTANCE1)) {}
|
||||
if (enable(clip_plane_2, GL_CLIP_DISTANCE2)) {}
|
||||
if (enable(clip_plane_3, GL_CLIP_DISTANCE3)) {}
|
||||
if (enable(clip_plane_4, GL_CLIP_DISTANCE4)) {}
|
||||
if (enable(clip_plane_5, GL_CLIP_DISTANCE5)) {}
|
||||
if (__glcheck enable(clip_plane_0, GL_CLIP_DISTANCE0)) {}
|
||||
if (__glcheck enable(clip_plane_1, GL_CLIP_DISTANCE1)) {}
|
||||
if (__glcheck enable(clip_plane_2, GL_CLIP_DISTANCE2)) {}
|
||||
if (__glcheck enable(clip_plane_3, GL_CLIP_DISTANCE3)) {}
|
||||
if (__glcheck enable(clip_plane_4, GL_CLIP_DISTANCE4)) {}
|
||||
if (__glcheck enable(clip_plane_5, GL_CLIP_DISTANCE5)) {}
|
||||
|
||||
__glcheck (enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL));
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_POLYGON_STIPPLE], GL_POLYGON_STIPPLE))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_POLYGON_STIPPLE], GL_POLYGON_STIPPLE))
|
||||
{
|
||||
__glcheck glPolygonStipple((GLubyte*)(rsx::method_registers + NV4097_SET_POLYGON_STIPPLE_PATTERN));
|
||||
}
|
||||
|
@ -757,13 +756,13 @@ void GLGSRender::begin()
|
|||
__glcheck glPolygonMode(GL_FRONT, rsx::method_registers[NV4097_SET_FRONT_POLYGON_MODE]);
|
||||
__glcheck glPolygonMode(GL_BACK, rsx::method_registers[NV4097_SET_BACK_POLYGON_MODE]);
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE))
|
||||
{
|
||||
__glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]);
|
||||
__glcheck glFrontFace(rsx::method_registers[NV4097_SET_FRONT_FACE]);
|
||||
}
|
||||
|
||||
enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH);
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH);
|
||||
|
||||
//NV4097_SET_COLOR_KEY_COLOR
|
||||
//NV4097_SET_SHADER_CONTROL
|
||||
|
@ -771,12 +770,12 @@ void GLGSRender::begin()
|
|||
//NV4097_SET_ANTI_ALIASING_CONTROL
|
||||
//NV4097_SET_CLIP_ID_TEST_ENABLE
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART))
|
||||
{
|
||||
__glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]);
|
||||
}
|
||||
|
||||
if (enable(rsx::method_registers[NV4097_SET_LINE_STIPPLE], GL_LINE_STIPPLE))
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_LINE_STIPPLE], GL_LINE_STIPPLE))
|
||||
{
|
||||
u32 line_stipple_pattern = rsx::method_registers[NV4097_SET_LINE_STIPPLE_PATTERN];
|
||||
u16 factor = line_stipple_pattern;
|
||||
|
@ -791,45 +790,45 @@ struct apply_attrib_t;
|
|||
template<typename T>
|
||||
struct apply_attrib_t<T, 1>
|
||||
{
|
||||
static void func(gl::glsl::program& program, int index, const T* data)
|
||||
static void func(gl::glsl::program& program, int location, const T* data)
|
||||
{
|
||||
program.attribs[index] = data[0];
|
||||
program.attribs[location] = data[0];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct apply_attrib_t<T, 2>
|
||||
{
|
||||
static void func(gl::glsl::program& program, int index, const T* data)
|
||||
static void func(gl::glsl::program& program, int location, const T* data)
|
||||
{
|
||||
program.attribs[index] = color2_base<T>{ data[0], data[1] };
|
||||
program.attribs[location] = color2_base<T>{ data[0], data[1] };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct apply_attrib_t<T, 3>
|
||||
{
|
||||
static void func(gl::glsl::program& program, int index, const T* data)
|
||||
static void func(gl::glsl::program& program, int location, const T* data)
|
||||
{
|
||||
program.attribs[index] = color3_base<T>{ data[0], data[1], data[2] };
|
||||
program.attribs[location] = color3_base<T>{ data[0], data[1], data[2] };
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct apply_attrib_t<T, 4>
|
||||
{
|
||||
static void func(gl::glsl::program& program, int index, const T* data)
|
||||
static void func(gl::glsl::program& program, int location, const T* data)
|
||||
{
|
||||
program.attribs[index] = color4_base<T>{ data[0], data[1], data[2], data[3] };
|
||||
program.attribs[location] = color4_base<T>{ data[0], data[1], data[2], data[3] };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T, int count>
|
||||
void apply_attrib_array(gl::glsl::program& program, int index, const std::vector<u8>& data)
|
||||
void apply_attrib_array(gl::glsl::program& program, int location, const std::vector<u8>& data)
|
||||
{
|
||||
for (size_t offset = 0; offset < data.size(); offset += count * sizeof(T))
|
||||
{
|
||||
apply_attrib_t<T, count>::func(program, index, (T*)(data.data() + offset));
|
||||
apply_attrib_t<T, count>::func(program, location, (T*)(data.data() + offset));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -992,9 +991,21 @@ void GLGSRender::end()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (0 || vertex_info.array)
|
||||
static const std::string reg_table[] =
|
||||
{
|
||||
__glcheck m_program.attribs[index] =
|
||||
"in_pos", "in_weight", "in_normal",
|
||||
"in_diff_color", "in_spec_color",
|
||||
"in_fog",
|
||||
"in_point_size", "in_7",
|
||||
"in_tc0", "in_tc1", "in_tc2", "in_tc3",
|
||||
"in_tc4", "in_tc5", "in_tc6", "in_tc7"
|
||||
};
|
||||
|
||||
int location = m_program.attribs.location(reg_table[index]);
|
||||
|
||||
if (vertex_info.array)
|
||||
{
|
||||
__glcheck m_program.attribs[location] =
|
||||
(vao + vertex_arrays_offsets[index])
|
||||
.config(gl_types[vertex_info.type], vertex_info.size, gl_normalized[vertex_info.type]);
|
||||
}
|
||||
|
@ -1007,10 +1018,10 @@ void GLGSRender::end()
|
|||
case CELL_GCM_VERTEX_F:
|
||||
switch (vertex_info.size)
|
||||
{
|
||||
case 1: apply_attrib_array<f32, 1>(m_program, index, vertex_data); break;
|
||||
case 2: apply_attrib_array<f32, 2>(m_program, index, vertex_data); break;
|
||||
case 3: apply_attrib_array<f32, 3>(m_program, index, vertex_data); break;
|
||||
case 4: apply_attrib_array<f32, 4>(m_program, index, vertex_data); break;
|
||||
case 1: apply_attrib_array<f32, 1>(m_program, location, vertex_data); break;
|
||||
case 2: apply_attrib_array<f32, 2>(m_program, location, vertex_data); break;
|
||||
case 3: apply_attrib_array<f32, 3>(m_program, location, vertex_data); break;
|
||||
case 4: apply_attrib_array<f32, 4>(m_program, location, vertex_data); break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1042,23 +1053,14 @@ void GLGSRender::end()
|
|||
rsx::thread::end();
|
||||
}
|
||||
|
||||
void GLGSRender::oninit()
|
||||
{
|
||||
GSRender::oninit();
|
||||
|
||||
m_draw_frames = 1;
|
||||
m_skip_frames = 0;
|
||||
}
|
||||
|
||||
void GLGSRender::oninit_thread()
|
||||
{
|
||||
GSRender::oninit_thread();
|
||||
|
||||
gl::init();
|
||||
LOG_NOTICE(Log::RSX, "%s", glGetString(GL_VERSION));
|
||||
LOG_NOTICE(Log::RSX, "%s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel");
|
||||
LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_VERSION));
|
||||
LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_VENDOR));
|
||||
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
|
|
|
@ -57,8 +57,6 @@ private:
|
|||
GLTexture m_gl_textures[rsx::limits::textures_count];
|
||||
GLTexture m_gl_vertex_textures[rsx::limits::vertex_textures_count];
|
||||
|
||||
draw_context_t m_context = nullptr;
|
||||
|
||||
//TODO: program cache
|
||||
gl::glsl::program m_program;
|
||||
|
||||
|
@ -78,11 +76,6 @@ private:
|
|||
gl::texture m_flip_tex_color;
|
||||
|
||||
public:
|
||||
GSFrameBase* m_frame = nullptr;
|
||||
u32 m_draw_frames;
|
||||
u32 m_skip_frames;
|
||||
bool is_intel_vendor;
|
||||
|
||||
GLGSRender();
|
||||
|
||||
private:
|
||||
|
@ -99,7 +92,6 @@ protected:
|
|||
void begin() override;
|
||||
void end() override;
|
||||
|
||||
void oninit() override;
|
||||
void oninit_thread() override;
|
||||
void onexit_thread() override;
|
||||
bool domethod(u32 id, u32 arg) override;
|
||||
|
|
|
@ -40,6 +40,10 @@ struct GLTraits
|
|||
__glcheck result->create()
|
||||
.attach(gl::glsl::shader_view(vertexProgramData.id))
|
||||
.attach(gl::glsl::shader_view(fragmentProgramData.id))
|
||||
.bind_fragment_data_location("ocol0", 0)
|
||||
.bind_fragment_data_location("ocol1", 1)
|
||||
.bind_fragment_data_location("ocol2", 2)
|
||||
.bind_fragment_data_location("ocol3", 3)
|
||||
.make();
|
||||
__glcheck result->use();
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::stri
|
|||
|
||||
void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||
{
|
||||
OS << "#version 420" << std::endl << std::endl;
|
||||
OS << "#version 140" << std::endl << std::endl;
|
||||
OS << "uniform mat4 scaleOffsetMat = mat4(1.0);" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v
|
|||
for (const ParamType PT : inputs)
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
OS << "layout(location = " << PI.location << ") in " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
OS << /*"layout(location = " << PI.location << ") "*/ "in " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,12 @@
|
|||
|
||||
draw_context_t GSFrameBase::new_context()
|
||||
{
|
||||
return std::shared_ptr<void>(make_context(), [this](void* ctxt) { delete_context(ctxt); });
|
||||
if (void* context = make_context())
|
||||
{
|
||||
return std::shared_ptr<void>(context, [this](void* ctxt) { delete_context(ctxt); });
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GSFrameBase::title_message(const std::wstring& msg)
|
||||
|
|
|
@ -960,98 +960,107 @@ namespace rsx
|
|||
|
||||
reset();
|
||||
|
||||
while (joinable())
|
||||
try
|
||||
{
|
||||
//TODO: async mode
|
||||
if (Emu.IsStopped())
|
||||
while (joinable())
|
||||
{
|
||||
LOG_WARNING(RSX, "RSX thread aborted");
|
||||
break;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(cs_main);
|
||||
|
||||
inc = 1;
|
||||
|
||||
be_t<u32> get = ctrl->get;
|
||||
be_t<u32> put = ctrl->put;
|
||||
|
||||
if (put == get || !Emu.IsRunning())
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
continue;
|
||||
}
|
||||
|
||||
const u32 cmd = ReadIO32(get);
|
||||
const u32 count = (cmd >> 18) & 0x7ff;
|
||||
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||
{
|
||||
u32 offs = cmd & 0x1fffffff;
|
||||
//LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
|
||||
ctrl->get.exchange(offs);
|
||||
continue;
|
||||
}
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||
{
|
||||
m_call_stack.push(get + 4);
|
||||
u32 offs = cmd & ~3;
|
||||
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
||||
ctrl->get.exchange(offs);
|
||||
continue;
|
||||
}
|
||||
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||
{
|
||||
u32 get = m_call_stack.top();
|
||||
m_call_stack.pop();
|
||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
||||
ctrl->get.exchange(get);
|
||||
continue;
|
||||
}
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||
{
|
||||
//LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd);
|
||||
inc = 0;
|
||||
}
|
||||
|
||||
if (cmd == 0) //nop
|
||||
{
|
||||
ctrl->get.atomic_op([](be_t<u32>& value)
|
||||
//TODO: async mode
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
value += 4;
|
||||
});
|
||||
LOG_WARNING(RSX, "RSX thread aborted");
|
||||
break;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(cs_main);
|
||||
|
||||
continue;
|
||||
}
|
||||
inc = 1;
|
||||
|
||||
auto args = vm::ptr<u32>::make((u32)RSXIOMem.RealAddr(get + 4));
|
||||
be_t<u32> get = ctrl->get;
|
||||
be_t<u32> put = ctrl->put;
|
||||
|
||||
u32 first_cmd = (cmd & 0xffff) >> 2;
|
||||
|
||||
if (cmd & 0x3)
|
||||
{
|
||||
LOG_WARNING(Log::RSX, "unaligned command: %s (0x%x from 0x%x)", get_method_name(first_cmd).c_str(), first_cmd, cmd & 0xffff);
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
u32 reg = first_cmd + (i * inc);
|
||||
u32 value = args[i];
|
||||
|
||||
if (Ini.RSXLogging.GetValue())
|
||||
if (put == get || !Emu.IsRunning())
|
||||
{
|
||||
LOG_NOTICE(Log::RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
continue;
|
||||
}
|
||||
|
||||
method_registers[reg] = value;
|
||||
const u32 cmd = ReadIO32(get);
|
||||
const u32 count = (cmd >> 18) & 0x7ff;
|
||||
|
||||
if (auto method = methods[reg])
|
||||
method(this, value);
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||
{
|
||||
u32 offs = cmd & 0x1fffffff;
|
||||
//LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
|
||||
ctrl->get.exchange(offs);
|
||||
continue;
|
||||
}
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||
{
|
||||
m_call_stack.push(get + 4);
|
||||
u32 offs = cmd & ~3;
|
||||
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
||||
ctrl->get.exchange(offs);
|
||||
continue;
|
||||
}
|
||||
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||
{
|
||||
u32 get = m_call_stack.top();
|
||||
m_call_stack.pop();
|
||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
||||
ctrl->get.exchange(get);
|
||||
continue;
|
||||
}
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||
{
|
||||
//LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd);
|
||||
inc = 0;
|
||||
}
|
||||
|
||||
if (cmd == 0) //nop
|
||||
{
|
||||
ctrl->get.atomic_op([](be_t<u32>& value)
|
||||
{
|
||||
value += 4;
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
auto args = vm::ptr<u32>::make((u32)RSXIOMem.RealAddr(get + 4));
|
||||
|
||||
u32 first_cmd = (cmd & 0xffff) >> 2;
|
||||
|
||||
if (cmd & 0x3)
|
||||
{
|
||||
LOG_WARNING(Log::RSX, "unaligned command: %s (0x%x from 0x%x)", get_method_name(first_cmd).c_str(), first_cmd, cmd & 0xffff);
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
u32 reg = first_cmd + (i * inc);
|
||||
u32 value = args[i];
|
||||
|
||||
if (Ini.RSXLogging.GetValue())
|
||||
{
|
||||
LOG_NOTICE(Log::RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
|
||||
}
|
||||
|
||||
method_registers[reg] = value;
|
||||
|
||||
if (auto method = methods[reg])
|
||||
method(this, value);
|
||||
}
|
||||
|
||||
ctrl->get.atomic_op([count](be_t<u32>& value)
|
||||
{
|
||||
value += (count + 1) * 4;
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
LOG_ERROR(Log::RSX, ex.what());
|
||||
|
||||
ctrl->get.atomic_op([count](be_t<u32>& value)
|
||||
{
|
||||
value += (count + 1) * 4;
|
||||
});
|
||||
std::rethrow_exception(std::current_exception());
|
||||
}
|
||||
|
||||
LOG_NOTICE(RSX, "RSX thread ended");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue