mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Rename RSXThread
This commit is contained in:
parent
b5127e68de
commit
4154a1026f
@ -295,6 +295,18 @@ void D3D12GSRender::OnReset()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool D3D12GSRender::domethod(u32 cmd, u32 arg)
|
||||||
|
{
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case NV4097_CLEAR_SURFACE:
|
||||||
|
clear_surface(arg);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void D3D12GSRender::clear_surface(u32 arg)
|
void D3D12GSRender::clear_surface(u32 arg)
|
||||||
{
|
{
|
||||||
std::chrono::time_point<std::chrono::system_clock> startDuration = std::chrono::system_clock::now();
|
std::chrono::time_point<std::chrono::system_clock> startDuration = std::chrono::system_clock::now();
|
||||||
@ -623,6 +635,8 @@ void D3D12GSRender::end()
|
|||||||
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
|
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
|
||||||
getCurrentResourceStorage().setNewCommandList();
|
getCurrentResourceStorage().setNewCommandList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread::end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -508,10 +508,12 @@ private:
|
|||||||
*/
|
*/
|
||||||
void renderOverlay();
|
void renderOverlay();
|
||||||
|
|
||||||
|
void clear_surface(u32 arg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onexit_thread() override;
|
virtual void onexit_thread() override;
|
||||||
virtual void OnReset() override;
|
virtual void OnReset() override;
|
||||||
virtual void clear_surface(u32 arg) override;
|
virtual bool domethod(u32 cmd, u32 arg) override;
|
||||||
virtual void end() override;
|
virtual void end() override;
|
||||||
virtual void flip(int buffer) override;
|
virtual void flip(int buffer) override;
|
||||||
};
|
};
|
||||||
|
@ -1043,7 +1043,7 @@ void GLGSRender::InitVertexData()
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
scaleOffsetMat[0] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale);
|
/* scaleOffsetMat[0] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale);
|
||||||
scaleOffsetMat[5] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale);
|
scaleOffsetMat[5] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale);
|
||||||
scaleOffsetMat[10] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)];
|
scaleOffsetMat[10] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)];
|
||||||
|
|
||||||
@ -1053,7 +1053,7 @@ void GLGSRender::InitVertexData()
|
|||||||
scaleOffsetMat[11] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)] - 1 / 2.0f;
|
scaleOffsetMat[11] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)] - 1 / 2.0f;
|
||||||
|
|
||||||
scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale;
|
scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale;
|
||||||
scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale;
|
scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale;*/
|
||||||
|
|
||||||
l = m_program.GetLocation("scaleOffsetMat");
|
l = m_program.GetLocation("scaleOffsetMat");
|
||||||
glUniformMatrix4fv(l, 1, false, scaleOffsetMat);
|
glUniformMatrix4fv(l, 1, false, scaleOffsetMat);
|
||||||
@ -1137,7 +1137,6 @@ void GLGSRender::WriteBuffers()
|
|||||||
if (Ini.GSDumpDepthBuffer.GetValue())
|
if (Ini.GSDumpDepthBuffer.GetValue())
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]);
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
WriteDepthBuffer();
|
WriteDepthBuffer();
|
||||||
}
|
}
|
||||||
@ -1150,212 +1149,38 @@ void GLGSRender::WriteBuffers()
|
|||||||
|
|
||||||
void GLGSRender::WriteDepthBuffer()
|
void GLGSRender::WriteDepthBuffer()
|
||||||
{
|
{
|
||||||
/* if (!m_set_context_dma_z)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 address;// = rsx::get_address(m_surface_offset_z, m_context_dma_z - 0xfeed0000);
|
|
||||||
|
|
||||||
auto ptr = vm::get_ptr<void>(address);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]);
|
|
||||||
checkForGlError("WriteDepthBuffer(): glBindBuffer");
|
|
||||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
checkForGlError("WriteDepthBuffer(): glReadPixels");
|
|
||||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
|
||||||
if (packed)
|
|
||||||
{
|
|
||||||
memcpy(ptr, packed, RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
checkForGlError("WriteDepthBuffer(): glUnmapBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
|
|
||||||
checkForGlError("WriteDepthBuffer(): glReadPixels");
|
|
||||||
glBindTexture(GL_TEXTURE_2D, g_depth_tex);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RSXThread::m_width, RSXThread::m_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, ptr);
|
|
||||||
checkForGlError("WriteDepthBuffer(): glTexImage2D");
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ptr);
|
|
||||||
checkForGlError("WriteDepthBuffer(): glGetTexImage");*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::WriteColorBufferA()
|
void GLGSRender::WriteColorBufferA()
|
||||||
{
|
{
|
||||||
/*if (!m_set_context_dma_color_a)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 address;// = rsx::get_address(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000);
|
|
||||||
|
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
|
||||||
checkForGlError("WriteColorBufferA(): glReadBuffer");
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[0]);
|
|
||||||
checkForGlError("WriteColorBufferA(): glBindBuffer");
|
|
||||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
|
||||||
checkForGlError("WriteColorBufferA(): glReadPixels");
|
|
||||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
|
||||||
if (packed)
|
|
||||||
{
|
|
||||||
memcpy(vm::get_ptr<void>(address), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
checkForGlError("WriteColorBufferA(): glUnmapBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::WriteColorBufferB()
|
void GLGSRender::WriteColorBufferB()
|
||||||
{
|
{
|
||||||
/* if (!m_set_context_dma_color_b)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 address;// = rsx::get_address(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000);
|
|
||||||
|
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
|
||||||
checkForGlError("WriteColorBufferB(): glReadBuffer");
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]);
|
|
||||||
checkForGlError("WriteColorBufferB(): glBindBuffer");
|
|
||||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
|
||||||
checkForGlError("WriteColorBufferB(): glReadPixels");
|
|
||||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
|
||||||
if (packed)
|
|
||||||
{
|
|
||||||
memcpy(vm::get_ptr<void>(address), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
checkForGlError("WriteColorBufferB(): glUnmapBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::WriteColorBufferC()
|
void GLGSRender::WriteColorBufferC()
|
||||||
{
|
{
|
||||||
/* if (!m_set_context_dma_color_c)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 address;// = rsx::get_address(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000);
|
|
||||||
|
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT2);
|
|
||||||
checkForGlError("WriteColorBufferC(): glReadBuffer");
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[2]);
|
|
||||||
checkForGlError("WriteColorBufferC(): glBindBuffer");
|
|
||||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
|
||||||
checkForGlError("WriteColorBufferC(): glReadPixels");
|
|
||||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
|
||||||
if (packed)
|
|
||||||
{
|
|
||||||
memcpy(vm::get_ptr<void>(address), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
checkForGlError("WriteColorBufferC(): glUnmapBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::WriteColorBufferD()
|
void GLGSRender::WriteColorBufferD()
|
||||||
{
|
{
|
||||||
/* if (!m_set_context_dma_color_d)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 address;// = rsx::get_address(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000);
|
|
||||||
|
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT3);
|
|
||||||
checkForGlError("WriteColorBufferD(): glReadBuffer");
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[3]);
|
|
||||||
checkForGlError("WriteColorBufferD(): glBindBuffer");
|
|
||||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
|
||||||
checkForGlError("WriteColorBufferD(): glReadPixels");
|
|
||||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
|
||||||
if (packed)
|
|
||||||
{
|
|
||||||
memcpy(vm::get_ptr<void>(address), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
checkForGlError("WriteColorBufferD(): glUnmapBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::WriteColorBuffers()
|
void GLGSRender::WriteColorBuffers()
|
||||||
{
|
{
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
|
||||||
|
|
||||||
switch(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
|
|
||||||
{
|
|
||||||
case CELL_GCM_SURFACE_TARGET_NONE:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CELL_GCM_SURFACE_TARGET_0:
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[0]);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
WriteColorBufferA();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GCM_SURFACE_TARGET_1:
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
WriteColorBufferB();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GCM_SURFACE_TARGET_MRT1:
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
}
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
WriteColorBufferA();
|
|
||||||
WriteColorBufferB();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GCM_SURFACE_TARGET_MRT2:
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
}
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
WriteColorBufferA();
|
|
||||||
WriteColorBufferB();
|
|
||||||
WriteColorBufferC();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GCM_SURFACE_TARGET_MRT3:
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[i]);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
}
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
WriteColorBufferA();
|
|
||||||
WriteColorBufferB();
|
|
||||||
WriteColorBufferC();
|
|
||||||
WriteColorBufferD();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::oninit()
|
void GLGSRender::oninit()
|
||||||
{
|
{
|
||||||
m_draw_frames = 1;
|
m_draw_frames = 1;
|
||||||
m_skip_frames = 0;
|
m_skip_frames = 0;
|
||||||
RSXThread::m_width = 720;
|
|
||||||
RSXThread::m_height = 576;
|
|
||||||
RSXThread::m_width_scale = 2.0f;
|
|
||||||
RSXThread::m_height_scale = 2.0f;
|
|
||||||
|
|
||||||
last_width = 0;
|
last_width = 0;
|
||||||
last_height = 0;
|
last_height = 0;
|
||||||
last_depth_format = 0;
|
last_depth_format = 0;
|
||||||
@ -1415,9 +1240,6 @@ void GLGSRender::InitDrawBuffers()
|
|||||||
{
|
{
|
||||||
// if (!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format)
|
// if (!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format)
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height);
|
|
||||||
last_width = RSXThread::m_width;
|
|
||||||
last_height = RSXThread::m_height;
|
|
||||||
// last_depth_format = m_surface_depth_format;
|
// last_depth_format = m_surface_depth_format;
|
||||||
|
|
||||||
m_fbo.Create();
|
m_fbo.Create();
|
||||||
@ -1430,7 +1252,6 @@ void GLGSRender::InitDrawBuffers()
|
|||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
m_rbo.Bind(i);
|
m_rbo.Bind(i);
|
||||||
m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height);
|
|
||||||
checkForGlError("m_rbo.Storage(GL_RGBA)");
|
checkForGlError("m_rbo.Storage(GL_RGBA)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,14 +1265,12 @@ void GLGSRender::InitDrawBuffers()
|
|||||||
// [E : RSXThread]: Bad depth format! (0)
|
// [E : RSXThread]: Bad depth format! (0)
|
||||||
// [E : RSXThread]: glEnable: opengl error 0x0506
|
// [E : RSXThread]: glEnable: opengl error 0x0506
|
||||||
// [E : RSXThread]: glDrawArrays: opengl error 0x0506
|
// [E : RSXThread]: glDrawArrays: opengl error 0x0506
|
||||||
m_rbo.Storage(GL_DEPTH_COMPONENT, RSXThread::m_width, RSXThread::m_height);
|
|
||||||
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)");
|
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_GCM_SURFACE_Z16:
|
case CELL_GCM_SURFACE_Z16:
|
||||||
{
|
{
|
||||||
m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height);
|
|
||||||
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)");
|
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)");
|
||||||
|
|
||||||
m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4));
|
m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4));
|
||||||
@ -1462,7 +1281,6 @@ void GLGSRender::InitDrawBuffers()
|
|||||||
|
|
||||||
case CELL_GCM_SURFACE_Z24S8:
|
case CELL_GCM_SURFACE_Z24S8:
|
||||||
{
|
{
|
||||||
m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height);
|
|
||||||
checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)");
|
checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)");
|
||||||
|
|
||||||
m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4));
|
m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4));
|
||||||
@ -1574,8 +1392,9 @@ void GLGSRender::InitDrawBuffers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::clear_surface(u32 arg)
|
bool GLGSRender::domethod(u32 arg, u32)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
InitDrawBuffers();
|
InitDrawBuffers();
|
||||||
|
|
||||||
// if (m_set_color_mask)
|
// if (m_set_color_mask)
|
||||||
@ -1938,10 +1757,10 @@ void GLGSRender::end()
|
|||||||
|
|
||||||
m_vao.Bind();
|
m_vao.Bind();
|
||||||
|
|
||||||
if (m_indexed_array.m_count)
|
/* if (m_indexed_array.m_count)
|
||||||
LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
|
LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
|
||||||
else
|
else
|
||||||
LoadVertexData(draw_array_first, draw_array_count);
|
LoadVertexData(draw_array_first, draw_array_count);*/
|
||||||
|
|
||||||
if (m_indexed_array.m_count || draw_array_count)
|
if (m_indexed_array.m_count || draw_array_count)
|
||||||
{
|
{
|
||||||
@ -1990,7 +1809,6 @@ void GLGSRender::flip(int buffer)
|
|||||||
// Set scissor to FBO size
|
// Set scissor to FBO size
|
||||||
if (m_set_scissor_horizontal && m_set_scissor_vertical)
|
if (m_set_scissor_horizontal && m_set_scissor_vertical)
|
||||||
{
|
{
|
||||||
glScissor(0, 0, RSXThread::m_width, RSXThread::m_height);
|
|
||||||
checkForGlError("glScissor");
|
checkForGlError("glScissor");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2005,7 +1823,6 @@ void GLGSRender::flip(int buffer)
|
|||||||
// Fast path for non-MRT using glBlitFramebuffer.
|
// Fast path for non-MRT using glBlitFramebuffer.
|
||||||
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
// Renderbuffer is upside turn , swapped srcY0 and srcY1
|
// Renderbuffer is upside turn , swapped srcY0 and srcY1
|
||||||
GLfbo::Blit(0, RSXThread::m_height, RSXThread::m_width, 0, 0, 0, RSXThread::m_width, RSXThread::m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2030,24 +1847,18 @@ void GLGSRender::flip(int buffer)
|
|||||||
{
|
{
|
||||||
format = GL_RGBA;
|
format = GL_RGBA;
|
||||||
static std::vector<u8> pixels;
|
static std::vector<u8> pixels;
|
||||||
pixels.resize(RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]);
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
|
||||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
|
||||||
checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)");
|
checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)");
|
||||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
||||||
if (packed)
|
if (packed)
|
||||||
{
|
{
|
||||||
memcpy(pixels.data(), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||||
checkForGlError("Flip(): glUnmapBuffer");
|
checkForGlError("Flip(): glUnmapBuffer");
|
||||||
}
|
}
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
|
||||||
src_buffer = pixels.data();
|
src_buffer = pixels.data();
|
||||||
width = RSXThread::m_width;
|
|
||||||
height = RSXThread::m_height;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -168,7 +168,7 @@ protected:
|
|||||||
virtual void oninit_thread() override;
|
virtual void oninit_thread() override;
|
||||||
virtual void onexit_thread() override;
|
virtual void onexit_thread() override;
|
||||||
virtual void OnReset() override;
|
virtual void OnReset() override;
|
||||||
virtual void clear_surface(u32 arg) override;
|
virtual bool domethod(u32, u32) override;
|
||||||
virtual void end() override;
|
virtual void end() override;
|
||||||
virtual void flip(int buffer) override;
|
virtual void flip(int buffer) override;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ enum class frame_type
|
|||||||
DX12
|
DX12
|
||||||
};
|
};
|
||||||
|
|
||||||
class GSRender : public RSXThread
|
class GSRender : public rsx::thread
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
GSFrameBase* m_frame;
|
GSFrameBase* m_frame;
|
||||||
|
@ -30,8 +30,9 @@ private:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void clear_surface(u32 arg) override
|
virtual bool domethod(u32, u32) override
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void end() override
|
virtual void end() override
|
||||||
|
@ -38,7 +38,7 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
//fire only when all data passed to rsx cmd buffer
|
//fire only when all data passed to rsx cmd buffer
|
||||||
template<u32 id, u32 index, int count, typename type>
|
template<u32 id, u32 index, int count, typename type>
|
||||||
force_inline void set_vertex_data_impl(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data_impl(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
static const size_t element_size = (count * sizeof(type));
|
static const size_t element_size = (count * sizeof(type));
|
||||||
static const size_t element_size_in_words = element_size / sizeof(u32);
|
static const size_t element_size_in_words = element_size / sizeof(u32);
|
||||||
@ -63,49 +63,49 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data4ub_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data4ub_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4UB_M, index, 4, u8>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4UB_M, index, 4, u8>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data1f_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data1f_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 1, f32>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 1, f32>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data2f_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data2f_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 2, f32>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 2, f32>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data3f_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data3f_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 3, f32>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 3, f32>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data4f_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data4f_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 4, f32>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 4, f32>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data2s_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data2s_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA2S_M, index, 2, u16>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA2S_M, index, 2, u16>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data4s_m(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data4s_m(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4S_M, index, 4, u16>(rsx, arg);
|
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4S_M, index, 4, u16>(rsx, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
force_inline void set_vertex_data_array_format(RSXThread* rsx, u32 arg)
|
force_inline void set_vertex_data_array_format(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
auto& info = rsx->vertex_arrays_info[index];
|
auto& info = rsx->vertex_arrays_info[index];
|
||||||
info.unpack(arg);
|
info.unpack(arg);
|
||||||
@ -203,9 +203,9 @@ namespace rsx
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr)
|
|
||||||
|
u32 thread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr)
|
||||||
{
|
{
|
||||||
auto args = vm::ps3::ptr<u32>::make(args_addr);
|
auto args = vm::ps3::ptr<u32>::make(args_addr);
|
||||||
std::string debug = GetMethodName(cmd);
|
std::string debug = GetMethodName(cmd);
|
||||||
@ -236,7 +236,7 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, cons
|
|||||||
case_##n(offset, step) \
|
case_##n(offset, step) \
|
||||||
index = (cmd - offset) / step
|
index = (cmd - offset) / step
|
||||||
|
|
||||||
void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count)
|
void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count)
|
||||||
{
|
{
|
||||||
auto args = vm::ps3::ptr<u32>::make(args_addr);
|
auto args = vm::ps3::ptr<u32>::make(args_addr);
|
||||||
|
|
||||||
@ -770,7 +770,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
|||||||
case NV4097_CLEAR_SURFACE:
|
case NV4097_CLEAR_SURFACE:
|
||||||
{
|
{
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
clear_surface(a0);
|
domethod(NV4097_CLEAR_SURFACE, a0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NV4097_SET_ZSTENCIL_CLEAR_VALUE:
|
case NV4097_SET_ZSTENCIL_CLEAR_VALUE:
|
||||||
@ -921,7 +921,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
End();
|
end();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2075,176 +2075,232 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSXThread::begin(u32 drawMode)
|
void thread::begin(u32 drawMode)
|
||||||
{
|
|
||||||
m_begin_end = 1;
|
|
||||||
draw_mode = drawMode;
|
|
||||||
draw_array_count = 0;
|
|
||||||
draw_array_first = ~0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSXThread::End()
|
|
||||||
{
|
|
||||||
end();
|
|
||||||
|
|
||||||
for (auto &vdata : vertex_arrays)
|
|
||||||
{
|
{
|
||||||
vdata.clear();
|
m_begin_end = 1;
|
||||||
|
draw_mode = drawMode;
|
||||||
|
draw_array_count = 0;
|
||||||
|
draw_array_first = ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_indexed_array.Reset();
|
void thread::end()
|
||||||
fragment_constants.clear();
|
|
||||||
|
|
||||||
m_clear_surface_mask = 0;
|
|
||||||
m_begin_end = 0;
|
|
||||||
|
|
||||||
OnReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSXThread::Task()
|
|
||||||
{
|
|
||||||
u8 inc;
|
|
||||||
LOG_NOTICE(RSX, "RSX thread started");
|
|
||||||
|
|
||||||
oninit_thread();
|
|
||||||
|
|
||||||
last_flip_time = get_system_time() - 1000000;
|
|
||||||
|
|
||||||
autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]()
|
|
||||||
{
|
{
|
||||||
const u64 start_time = get_system_time();
|
for (auto &vdata : vertex_arrays)
|
||||||
|
|
||||||
vblank_count = 0;
|
|
||||||
|
|
||||||
while (joinable())
|
|
||||||
{
|
{
|
||||||
CHECK_EMU_STATUS;
|
vdata.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (get_system_time() - start_time > vblank_count * 1000000 / 60)
|
m_indexed_array.Reset();
|
||||||
|
fragment_constants.clear();
|
||||||
|
|
||||||
|
m_clear_surface_mask = 0;
|
||||||
|
m_begin_end = 0;
|
||||||
|
|
||||||
|
OnReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread::task()
|
||||||
|
{
|
||||||
|
u8 inc;
|
||||||
|
LOG_NOTICE(RSX, "RSX thread started");
|
||||||
|
|
||||||
|
oninit_thread();
|
||||||
|
|
||||||
|
last_flip_time = get_system_time() - 1000000;
|
||||||
|
|
||||||
|
autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]()
|
||||||
|
{
|
||||||
|
const u64 start_time = get_system_time();
|
||||||
|
|
||||||
|
vblank_count = 0;
|
||||||
|
|
||||||
|
while (joinable())
|
||||||
{
|
{
|
||||||
vblank_count++;
|
CHECK_EMU_STATUS;
|
||||||
|
|
||||||
if (auto cb = vblank_handler)
|
if (get_system_time() - start_time > vblank_count * 1000000 / 60)
|
||||||
{
|
{
|
||||||
Emu.GetCallbackManager().Async([=](CPUThread& cpu)
|
vblank_count++;
|
||||||
|
|
||||||
|
if (auto cb = vblank_handler)
|
||||||
{
|
{
|
||||||
cb(static_cast<PPUThread&>(cpu), 1);
|
Emu.GetCallbackManager().Async([=](CPUThread& cpu)
|
||||||
});
|
{
|
||||||
|
cb(static_cast<PPUThread&>(cpu), 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
});
|
||||||
|
|
||||||
|
while (joinable() && !Emu.IsStopped())
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(cs_main);
|
||||||
|
|
||||||
|
inc = 1;
|
||||||
|
|
||||||
|
const be_t<u32> put = ctrl->put;
|
||||||
|
const be_t<u32> get = ctrl->get;
|
||||||
|
|
||||||
|
if (put == get || !Emu.IsRunning())
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
while (joinable() && !Emu.IsStopped())
|
const u32 cmd = ReadIO32(get);
|
||||||
{
|
const u32 count = (cmd >> 18) & 0x7ff;
|
||||||
std::lock_guard<std::mutex> lock(cs_main);
|
|
||||||
|
|
||||||
inc = 1;
|
if (Ini.RSXLogging.GetValue())
|
||||||
|
{
|
||||||
const be_t<u32> put = ctrl->put;
|
LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd);
|
||||||
const be_t<u32> get = ctrl->get;
|
}
|
||||||
|
|
||||||
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 (Ini.RSXLogging.GetValue())
|
|
||||||
{
|
|
||||||
LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||||
{
|
{
|
||||||
u32 offs = cmd & 0x1fffffff;
|
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);
|
//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);
|
ctrl->get.exchange(offs);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||||
{
|
{
|
||||||
m_call_stack.push(get + 4);
|
m_call_stack.push(get + 4);
|
||||||
u32 offs = cmd & ~3;
|
u32 offs = cmd & ~3;
|
||||||
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
||||||
ctrl->get.exchange(offs);
|
ctrl->get.exchange(offs);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||||
{
|
{
|
||||||
u32 get = m_call_stack.top();
|
u32 get = m_call_stack.top();
|
||||||
m_call_stack.pop();
|
m_call_stack.pop();
|
||||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
||||||
ctrl->get.exchange(get);
|
ctrl->get.exchange(get);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||||
{
|
{
|
||||||
//LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd);
|
//LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd);
|
||||||
inc = 0;
|
inc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == 0) //nop
|
||||||
|
{
|
||||||
|
ctrl->get += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto args = vm::ps3::ptr<u32>::make((u32)RSXIOMem.RealAddr(get + 4));
|
||||||
|
|
||||||
|
for (u32 i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
rsx::method_registers[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
DoCmd(cmd, cmd & 0x3ffff, args.addr(), count);
|
||||||
|
|
||||||
|
ctrl->get += (count + 1) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == 0) //nop
|
onexit_thread();
|
||||||
{
|
|
||||||
ctrl->get += 4;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto args = vm::ps3::ptr<u32>::make((u32)RSXIOMem.RealAddr(get + 4));
|
|
||||||
|
|
||||||
for (u32 i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
rsx::method_registers[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
DoCmd(cmd, cmd & 0x3ffff, args.addr(), count);
|
|
||||||
|
|
||||||
ctrl->get += (count + 1) * 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onexit_thread();
|
u64 thread::timestamp() const
|
||||||
}
|
|
||||||
|
|
||||||
void RSXThread::Init(const u32 ioAddress, const u32 io_size, const u32 ctrlAddress, const u32 localAddress)
|
|
||||||
{
|
|
||||||
ctrl = vm::get_ptr<CellGcmControl>(ctrlAddress);
|
|
||||||
this->ioAddress = ioAddress;
|
|
||||||
this->ioSize = io_size;
|
|
||||||
m_ctrlAddress = ctrlAddress;
|
|
||||||
local_mem_addr = localAddress;
|
|
||||||
|
|
||||||
m_cur_vertex_prog = nullptr;
|
|
||||||
|
|
||||||
m_used_gcm_commands.clear();
|
|
||||||
|
|
||||||
oninit();
|
|
||||||
|
|
||||||
start(WRAP_EXPR("RSXThread"), WRAP_EXPR(Task()));
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 RSXThread::ReadIO32(u32 addr)
|
|
||||||
{
|
|
||||||
u32 value;
|
|
||||||
|
|
||||||
if (!RSXIOMem.Read32(addr, &value))
|
|
||||||
{
|
{
|
||||||
throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr);
|
// Get timestamp, and convert it from microseconds to nanoseconds
|
||||||
|
return get_system_time() * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
void thread::reset()
|
||||||
}
|
|
||||||
|
|
||||||
void RSXThread::WriteIO32(u32 addr, u32 value)
|
|
||||||
{
|
|
||||||
if (!RSXIOMem.Write32(addr, value))
|
|
||||||
{
|
{
|
||||||
throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr);
|
rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false;
|
||||||
|
rsx::method_registers[NV4097_SET_DEPTH_MASK] = 1;
|
||||||
|
rsx::method_registers[NV4097_SET_DEPTH_FUNC] = 0x0201;
|
||||||
|
|
||||||
|
m_set_dither = false;
|
||||||
|
rsx::method_registers[NV4097_SET_COLOR_MASK] = -1;
|
||||||
|
m_set_clip = false;
|
||||||
|
m_set_depth_bounds_test = false;
|
||||||
|
m_set_depth_bounds = false;
|
||||||
|
m_set_scissor_horizontal = false;
|
||||||
|
m_set_scissor_vertical = false;
|
||||||
|
m_set_front_polygon_mode = false;
|
||||||
|
m_set_back_polygon_mode = false;
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0;
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false;
|
||||||
|
m_set_two_side_light_enable = false;
|
||||||
|
m_set_point_sprite_control = false;
|
||||||
|
m_set_point_size = false;
|
||||||
|
m_set_line_width = false;
|
||||||
|
m_set_line_smooth = false;
|
||||||
|
m_set_shade_mode = false;
|
||||||
|
m_set_fog_mode = false;
|
||||||
|
m_set_fog_params = false;
|
||||||
|
m_set_clip_plane = false;
|
||||||
|
rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false;
|
||||||
|
rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false;
|
||||||
|
rsx::method_registers[NV4097_SET_ALPHA_FUNC] = false;
|
||||||
|
rsx::method_registers[NV4097_SET_ALPHA_REF] = false;
|
||||||
|
m_set_poly_smooth = false;
|
||||||
|
m_set_poly_offset_fill = false;
|
||||||
|
m_set_poly_offset_line = false;
|
||||||
|
m_set_poly_offset_point = false;
|
||||||
|
m_set_poly_offset_mode = false;
|
||||||
|
m_set_restart_index = false;
|
||||||
|
m_set_specular = false;
|
||||||
|
m_set_line_stipple = false;
|
||||||
|
m_set_polygon_stipple = false;
|
||||||
|
m_set_surface_clip_horizontal = false;
|
||||||
|
m_set_surface_clip_vertical = false;
|
||||||
|
|
||||||
|
m_clear_surface_mask = 0;
|
||||||
|
m_begin_end = 0;
|
||||||
|
|
||||||
|
for (uint i = 0; i < rsx::limits::textures_count; ++i)
|
||||||
|
{
|
||||||
|
textures[i].init(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread::init(const u32 ioAddress, const u32 io_size, const u32 ctrlAddress, const u32 localAddress)
|
||||||
|
{
|
||||||
|
ctrl = vm::get_ptr<CellGcmControl>(ctrlAddress);
|
||||||
|
this->ioAddress = ioAddress;
|
||||||
|
this->ioSize = io_size;
|
||||||
|
m_ctrlAddress = ctrlAddress;
|
||||||
|
local_mem_addr = localAddress;
|
||||||
|
|
||||||
|
m_cur_vertex_prog = nullptr;
|
||||||
|
|
||||||
|
m_used_gcm_commands.clear();
|
||||||
|
|
||||||
|
oninit();
|
||||||
|
|
||||||
|
start(WRAP_EXPR("RSXThread"), WRAP_EXPR(task()));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 thread::ReadIO32(u32 addr)
|
||||||
|
{
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
if (!RSXIOMem.Read32(addr, &value))
|
||||||
|
{
|
||||||
|
throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread::WriteIO32(u32 addr, u32 value)
|
||||||
|
{
|
||||||
|
if (!RSXIOMem.Write32(addr, value))
|
||||||
|
{
|
||||||
|
throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,42 @@
|
|||||||
#include "Utilities/Timer.h"
|
#include "Utilities/Timer.h"
|
||||||
#include "Utilities/types.h"
|
#include "Utilities/types.h"
|
||||||
|
|
||||||
|
enum Method
|
||||||
|
{
|
||||||
|
CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000,
|
||||||
|
CELL_GCM_METHOD_FLAG_JUMP = 0x20000000,
|
||||||
|
CELL_GCM_METHOD_FLAG_CALL = 0x00000002,
|
||||||
|
CELL_GCM_METHOD_FLAG_RETURN = 0x00020000,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RSXIndexArrayData
|
||||||
|
{
|
||||||
|
std::vector<u8> m_data;
|
||||||
|
int m_type;
|
||||||
|
u32 m_first;
|
||||||
|
u32 m_count;
|
||||||
|
u32 m_addr;
|
||||||
|
u32 index_max;
|
||||||
|
u32 index_min;
|
||||||
|
|
||||||
|
RSXIndexArrayData()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
m_type = 0;
|
||||||
|
m_first = ~0;
|
||||||
|
m_count = 0;
|
||||||
|
m_addr = 0;
|
||||||
|
index_min = ~0;
|
||||||
|
index_max = 0;
|
||||||
|
m_data.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace rsx
|
namespace rsx
|
||||||
{
|
{
|
||||||
namespace limits
|
namespace limits
|
||||||
@ -76,489 +112,381 @@ namespace rsx
|
|||||||
type = data_array_format & 0xf;
|
type = data_array_format & 0xf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class thread : protected named_thread_t
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::stack<u32> m_call_stack;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CellGcmControl* ctrl = nullptr;
|
||||||
|
Timer timer_sync;
|
||||||
|
|
||||||
|
GcmTileInfo tiles[limits::tiles_count];
|
||||||
|
GcmZcullInfo zculls[limits::zculls_count];
|
||||||
|
texture textures[limits::textures_count];
|
||||||
|
vertex_texture m_vertex_textures[limits::vertex_textures_count];
|
||||||
|
|
||||||
|
data_array_format_info vertex_arrays_info[limits::vertex_count];
|
||||||
|
std::vector<u8> vertex_arrays[limits::vertex_count];
|
||||||
|
RSXIndexArrayData m_indexed_array;
|
||||||
|
|
||||||
|
std::unordered_map<u32, color4_base<f32>> transform_constants;
|
||||||
|
std::unordered_map<u32, color4_base<f32>> fragment_constants;
|
||||||
|
|
||||||
|
u32 m_shader_ctrl;
|
||||||
|
RSXVertexProgram m_vertex_progs[limits::vertex_count];
|
||||||
|
RSXVertexProgram* m_cur_vertex_prog;
|
||||||
|
|
||||||
|
public:
|
||||||
|
u32 ioAddress, ioSize;
|
||||||
|
int flip_status;
|
||||||
|
int flip_mode;
|
||||||
|
int debug_level;
|
||||||
|
int frequency_mode;
|
||||||
|
|
||||||
|
u32 tiles_addr;
|
||||||
|
u32 zculls_addr;
|
||||||
|
u32 m_gcm_buffers_addr;
|
||||||
|
u32 gcm_buffers_count;
|
||||||
|
u32 gcm_current_buffer;
|
||||||
|
u32 ctxt_addr;
|
||||||
|
u32 report_main_addr;
|
||||||
|
u32 label_addr;
|
||||||
|
u32 draw_mode;
|
||||||
|
|
||||||
|
// DMA
|
||||||
|
u32 dma_report;
|
||||||
|
|
||||||
|
u32 local_mem_addr, main_mem_addr;
|
||||||
|
bool strict_ordering[0x1000];
|
||||||
|
|
||||||
|
public:
|
||||||
|
u32 draw_array_count;
|
||||||
|
u32 draw_array_first;
|
||||||
|
double m_fps_limit = 59.94;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::mutex cs_main;
|
||||||
|
semaphore_t sem_flip;
|
||||||
|
u64 last_flip_time;
|
||||||
|
vm::ps3::ptr<void(u32)> flip_handler = { 0 };
|
||||||
|
vm::ps3::ptr<void(u32)> user_handler = { 0 };
|
||||||
|
vm::ps3::ptr<void(u32)> vblank_handler = { 0 };
|
||||||
|
u64 vblank_count;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::set<u32> m_used_gcm_commands;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~thread() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void begin(u32 draw_mode);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
virtual void oninit() = 0;
|
||||||
|
virtual void oninit_thread() = 0;
|
||||||
|
virtual void onexit_thread() = 0;
|
||||||
|
virtual bool domethod(u32 cmd, u32 value) { return false; }
|
||||||
|
virtual void flip(int buffer) = 0;
|
||||||
|
virtual u64 timestamp() const;
|
||||||
|
|
||||||
|
void task();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void reset();
|
||||||
|
void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);
|
||||||
|
|
||||||
|
u32 ReadIO32(u32 addr);
|
||||||
|
void WriteIO32(u32 addr, u32 value);
|
||||||
|
|
||||||
|
public:
|
||||||
|
u32 m_ctrlAddress;
|
||||||
|
u32 m_width;
|
||||||
|
u32 m_height;
|
||||||
|
float m_width_scale;
|
||||||
|
float m_height_scale;
|
||||||
|
// Dither
|
||||||
|
bool m_set_dither;
|
||||||
|
|
||||||
|
// Clip
|
||||||
|
bool m_set_clip;
|
||||||
|
float m_clip_min;
|
||||||
|
float m_clip_max;
|
||||||
|
|
||||||
|
// Depth bound test
|
||||||
|
bool m_set_depth_bounds_test;
|
||||||
|
bool m_set_depth_bounds;
|
||||||
|
float m_depth_bounds_min;
|
||||||
|
float m_depth_bounds_max;
|
||||||
|
|
||||||
|
// Primitive restart
|
||||||
|
bool m_set_restart_index;
|
||||||
|
u32 m_restart_index;
|
||||||
|
|
||||||
|
// Point
|
||||||
|
bool m_set_point_size;
|
||||||
|
bool m_set_point_sprite_control;
|
||||||
|
float m_point_size;
|
||||||
|
u16 m_point_x;
|
||||||
|
u16 m_point_y;
|
||||||
|
|
||||||
|
// Line smooth
|
||||||
|
bool m_set_line_smooth;
|
||||||
|
|
||||||
|
// Viewport & scissor
|
||||||
|
bool m_set_scissor_horizontal;
|
||||||
|
bool m_set_scissor_vertical;
|
||||||
|
u16 m_scissor_x;
|
||||||
|
u16 m_scissor_y;
|
||||||
|
u16 m_scissor_w;
|
||||||
|
u16 m_scissor_h;
|
||||||
|
|
||||||
|
// Polygon mode/offset
|
||||||
|
bool m_set_poly_smooth;
|
||||||
|
bool m_set_poly_offset_fill;
|
||||||
|
bool m_set_poly_offset_line;
|
||||||
|
bool m_set_poly_offset_point;
|
||||||
|
bool m_set_front_polygon_mode;
|
||||||
|
u32 m_front_polygon_mode;
|
||||||
|
bool m_set_back_polygon_mode;
|
||||||
|
u32 m_back_polygon_mode;
|
||||||
|
bool m_set_poly_offset_mode;
|
||||||
|
float m_poly_offset_scale_factor;
|
||||||
|
float m_poly_offset_bias;
|
||||||
|
|
||||||
|
// Line/Polygon stipple
|
||||||
|
bool m_set_line_stipple;
|
||||||
|
u16 m_line_stipple_pattern;
|
||||||
|
u16 m_line_stipple_factor;
|
||||||
|
bool m_set_polygon_stipple;
|
||||||
|
u32 m_polygon_stipple_pattern[32];
|
||||||
|
|
||||||
|
|
||||||
|
// Clearing
|
||||||
|
u32 m_clear_surface_mask;
|
||||||
|
|
||||||
|
// Stencil Test
|
||||||
|
bool m_set_two_side_light_enable;
|
||||||
|
|
||||||
|
// Line width
|
||||||
|
bool m_set_line_width;
|
||||||
|
float m_line_width;
|
||||||
|
|
||||||
|
// Shader mode
|
||||||
|
bool m_set_shade_mode;
|
||||||
|
u32 m_shade_mode;
|
||||||
|
|
||||||
|
// Lighting
|
||||||
|
bool m_set_specular;
|
||||||
|
|
||||||
|
// Color
|
||||||
|
u32 m_color_format;
|
||||||
|
u16 m_color_format_src_pitch;
|
||||||
|
u16 m_color_format_dst_pitch;
|
||||||
|
u32 m_color_conv;
|
||||||
|
u32 m_color_conv_fmt;
|
||||||
|
u32 m_color_conv_op;
|
||||||
|
s16 m_color_conv_clip_x;
|
||||||
|
s16 m_color_conv_clip_y;
|
||||||
|
u16 m_color_conv_clip_w;
|
||||||
|
u16 m_color_conv_clip_h;
|
||||||
|
s16 m_color_conv_out_x;
|
||||||
|
s16 m_color_conv_out_y;
|
||||||
|
u16 m_color_conv_out_w;
|
||||||
|
u16 m_color_conv_out_h;
|
||||||
|
s32 m_color_conv_dsdx;
|
||||||
|
s32 m_color_conv_dtdy;
|
||||||
|
|
||||||
|
// Semaphore
|
||||||
|
// PGRAPH
|
||||||
|
u32 m_PGRAPH_semaphore_offset;
|
||||||
|
//PFIFO
|
||||||
|
u32 m_PFIFO_semaphore_offset;
|
||||||
|
u32 m_PFIFO_semaphore_release_value;
|
||||||
|
|
||||||
|
// Fog
|
||||||
|
bool m_set_fog_mode;
|
||||||
|
u32 m_fog_mode;
|
||||||
|
bool m_set_fog_params;
|
||||||
|
float m_fog_param0;
|
||||||
|
float m_fog_param1;
|
||||||
|
|
||||||
|
// Clip plane
|
||||||
|
bool m_set_clip_plane;
|
||||||
|
bool m_clip_plane_0;
|
||||||
|
bool m_clip_plane_1;
|
||||||
|
bool m_clip_plane_2;
|
||||||
|
bool m_clip_plane_3;
|
||||||
|
bool m_clip_plane_4;
|
||||||
|
bool m_clip_plane_5;
|
||||||
|
|
||||||
|
// Surface
|
||||||
|
rsx::surface_info m_surface;
|
||||||
|
bool m_set_surface_clip_horizontal;
|
||||||
|
bool m_set_surface_clip_vertical;
|
||||||
|
|
||||||
|
// DMA context
|
||||||
|
u32 m_context_surface;
|
||||||
|
u32 m_context_dma_img_src;
|
||||||
|
u32 m_context_dma_img_dst;
|
||||||
|
u32 m_context_dma_buffer_in_src;
|
||||||
|
u32 m_context_dma_buffer_in_dst;
|
||||||
|
u32 m_dst_offset;
|
||||||
|
|
||||||
|
// Swizzle2D?
|
||||||
|
u16 m_swizzle_format;
|
||||||
|
u8 m_swizzle_width;
|
||||||
|
u8 m_swizzle_height;
|
||||||
|
u32 m_swizzle_offset;
|
||||||
|
|
||||||
|
// Shader
|
||||||
|
u16 m_shader_window_height;
|
||||||
|
u8 m_shader_window_origin;
|
||||||
|
u16 m_shader_window_pixel_centers;
|
||||||
|
|
||||||
|
// Vertex Data
|
||||||
|
u32 m_vertex_data_base_index;
|
||||||
|
|
||||||
|
// Frequency divider
|
||||||
|
u32 m_set_frequency_divider_operation;
|
||||||
|
|
||||||
|
u8 m_begin_end;
|
||||||
|
bool m_read_buffer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
thread()
|
||||||
|
: m_shader_ctrl(0x40)
|
||||||
|
, flip_status(0)
|
||||||
|
, flip_mode(CELL_GCM_DISPLAY_VSYNC)
|
||||||
|
, debug_level(CELL_GCM_DEBUG_LEVEL0)
|
||||||
|
, frequency_mode(CELL_GCM_DISPLAY_FREQUENCY_DISABLE)
|
||||||
|
, report_main_addr(0)
|
||||||
|
, main_mem_addr(0)
|
||||||
|
, local_mem_addr(0)
|
||||||
|
, draw_mode(0)
|
||||||
|
, draw_array_count(0)
|
||||||
|
, draw_array_first(~0)
|
||||||
|
, gcm_current_buffer(0)
|
||||||
|
, m_read_buffer(true)
|
||||||
|
{
|
||||||
|
flip_handler.set(0);
|
||||||
|
vblank_handler.set(0);
|
||||||
|
user_handler.set(0);
|
||||||
|
rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false;
|
||||||
|
m_set_depth_bounds_test = false;
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0;
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false;
|
||||||
|
m_set_dither = false;
|
||||||
|
m_set_scissor_horizontal = false;
|
||||||
|
m_set_scissor_vertical = false;
|
||||||
|
m_set_line_smooth = false;
|
||||||
|
m_set_poly_smooth = false;
|
||||||
|
m_set_point_sprite_control = false;
|
||||||
|
m_set_specular = false;
|
||||||
|
m_set_two_side_light_enable = false;
|
||||||
|
m_set_surface_clip_horizontal = false;
|
||||||
|
m_set_surface_clip_vertical = false;
|
||||||
|
m_set_poly_offset_fill = false;
|
||||||
|
m_set_poly_offset_line = false;
|
||||||
|
m_set_poly_offset_point = false;
|
||||||
|
m_set_restart_index = false;
|
||||||
|
m_set_line_stipple = false;
|
||||||
|
m_set_polygon_stipple = false;
|
||||||
|
|
||||||
|
// Default value
|
||||||
|
// TODO: Check against the default value on PS3
|
||||||
|
rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE] = 0;
|
||||||
|
rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff << 8;
|
||||||
|
m_poly_offset_scale_factor = 0.0;
|
||||||
|
m_poly_offset_bias = 0.0;
|
||||||
|
m_restart_index = 0xffffffff;
|
||||||
|
m_front_polygon_mode = 0x1b02; // GL_FILL
|
||||||
|
m_back_polygon_mode = 0x1b02; // GL_FILL
|
||||||
|
rsx::method_registers[NV4097_SET_FRONT_FACE] = 0x0901; // GL_CCW
|
||||||
|
rsx::method_registers[NV4097_SET_CULL_FACE] = 0x0405; // GL_BACK
|
||||||
|
rsx::method_registers[NV4097_SET_ALPHA_FUNC] = 0x0207; // GL_ALWAYS
|
||||||
|
rsx::method_registers[NV4097_SET_ALPHA_REF] = 0.0f;
|
||||||
|
m_shade_mode = 0x1D01; // GL_SMOOTH
|
||||||
|
|
||||||
|
m_depth_bounds_min = 0.0;
|
||||||
|
m_depth_bounds_max = 1.0;
|
||||||
|
m_clip_min = 0.0;
|
||||||
|
m_clip_max = 1.0;
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_EQUATION] = (0x8006) | (0x8006 << 16); // GL_FUNC_ADD
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = 1 | (1 << 16);
|
||||||
|
rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = 0;
|
||||||
|
m_point_x = 0;
|
||||||
|
m_point_y = 0;
|
||||||
|
m_point_size = 1.0;
|
||||||
|
m_line_width = 1.0;
|
||||||
|
m_line_stipple_pattern = 0xffff;
|
||||||
|
m_line_stipple_factor = 1;
|
||||||
|
rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] = 0;
|
||||||
|
m_vertex_data_base_index = 0;
|
||||||
|
|
||||||
|
// Construct Stipple Pattern
|
||||||
|
for (size_t i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
m_polygon_stipple_pattern[i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct Textures
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
textures[i] = rsx::texture();
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr);
|
||||||
|
void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count);
|
||||||
|
|
||||||
|
virtual void OnReset() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE
|
||||||
|
* command.
|
||||||
|
* Backend is expected to write value at offset when current draw textures aren't
|
||||||
|
* needed anymore by the GPU and can be modified.
|
||||||
|
*/
|
||||||
|
virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0;
|
||||||
|
/**
|
||||||
|
* This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE
|
||||||
|
* command.
|
||||||
|
* Backend is expected to write value at offset when current draw call has completed
|
||||||
|
* and render surface can be used.
|
||||||
|
*/
|
||||||
|
virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0;
|
||||||
|
/**
|
||||||
|
* This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command.
|
||||||
|
* Backend and associated GPU is expected to wait that memory at offset is the same
|
||||||
|
* as value. In particular buffer/texture buffers value can change while backend is
|
||||||
|
* waiting.
|
||||||
|
*/
|
||||||
|
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0;
|
||||||
|
/**
|
||||||
|
* Called when vertex or fragment shader changes.
|
||||||
|
* Backend can reuse same program if no change has been notified.
|
||||||
|
*/
|
||||||
|
virtual void notifyProgramChange() = 0;
|
||||||
|
/**
|
||||||
|
* Called when blend state changes.
|
||||||
|
* Backend can reuse same program if no change has been notified.
|
||||||
|
*/
|
||||||
|
virtual void notifyBlendStateChange() = 0;
|
||||||
|
/**
|
||||||
|
* Called when depth stencil state changes.
|
||||||
|
* Backend can reuse same program if no change has been notified.
|
||||||
|
*/
|
||||||
|
virtual void notifyDepthStencilStateChange() = 0;
|
||||||
|
/**
|
||||||
|
* Called when rasterizer state changes.
|
||||||
|
* Rasterizer state includes culling, color masking
|
||||||
|
* Backend can reuse same program if no change has been notified.
|
||||||
|
*/
|
||||||
|
virtual void notifyRasterizerStateChange() = 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Method
|
|
||||||
{
|
|
||||||
CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000,
|
|
||||||
CELL_GCM_METHOD_FLAG_JUMP = 0x20000000,
|
|
||||||
CELL_GCM_METHOD_FLAG_CALL = 0x00000002,
|
|
||||||
CELL_GCM_METHOD_FLAG_RETURN = 0x00020000,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RSXIndexArrayData
|
|
||||||
{
|
|
||||||
std::vector<u8> m_data;
|
|
||||||
int m_type;
|
|
||||||
u32 m_first;
|
|
||||||
u32 m_count;
|
|
||||||
u32 m_addr;
|
|
||||||
u32 index_max;
|
|
||||||
u32 index_min;
|
|
||||||
|
|
||||||
RSXIndexArrayData()
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset()
|
|
||||||
{
|
|
||||||
m_type = 0;
|
|
||||||
m_first = ~0;
|
|
||||||
m_count = 0;
|
|
||||||
m_addr = 0;
|
|
||||||
index_min = ~0;
|
|
||||||
index_max = 0;
|
|
||||||
m_data.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class RSXThread : protected named_thread_t
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::stack<u32> m_call_stack;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CellGcmControl* ctrl = nullptr;
|
|
||||||
Timer timer_sync;
|
|
||||||
|
|
||||||
GcmTileInfo tiles[rsx::limits::tiles_count];
|
|
||||||
GcmZcullInfo zculls[rsx::limits::zculls_count];
|
|
||||||
rsx::texture textures[rsx::limits::textures_count];
|
|
||||||
rsx::vertex_texture m_vertex_textures[rsx::limits::vertex_textures_count];
|
|
||||||
|
|
||||||
rsx::data_array_format_info vertex_arrays_info[rsx::limits::vertex_count];
|
|
||||||
std::vector<u8> vertex_arrays[rsx::limits::vertex_count];
|
|
||||||
RSXIndexArrayData m_indexed_array;
|
|
||||||
|
|
||||||
std::unordered_map<u32, color4_base<f32>> transform_constants;
|
|
||||||
std::unordered_map<u32, color4_base<f32>> fragment_constants;
|
|
||||||
|
|
||||||
u32 m_shader_ctrl;
|
|
||||||
RSXVertexProgram m_vertex_progs[rsx::limits::vertex_count];
|
|
||||||
RSXVertexProgram* m_cur_vertex_prog;
|
|
||||||
|
|
||||||
public:
|
|
||||||
u32 ioAddress, ioSize, m_ctrlAddress;
|
|
||||||
int flip_status;
|
|
||||||
int flip_mode;
|
|
||||||
int debug_level;
|
|
||||||
int frequency_mode;
|
|
||||||
|
|
||||||
u32 tiles_addr;
|
|
||||||
u32 zculls_addr;
|
|
||||||
u32 m_gcm_buffers_addr;
|
|
||||||
u32 gcm_buffers_count;
|
|
||||||
u32 gcm_current_buffer;
|
|
||||||
u32 ctxt_addr;
|
|
||||||
u32 report_main_addr;
|
|
||||||
u32 label_addr;
|
|
||||||
u32 draw_mode;
|
|
||||||
|
|
||||||
// DMA
|
|
||||||
u32 dma_report;
|
|
||||||
|
|
||||||
u32 local_mem_addr, main_mem_addr;
|
|
||||||
bool strict_ordering[0x1000];
|
|
||||||
|
|
||||||
public:
|
|
||||||
u32 draw_array_count;
|
|
||||||
u32 draw_array_first;
|
|
||||||
|
|
||||||
u32 m_width;
|
|
||||||
u32 m_height;
|
|
||||||
float m_width_scale;
|
|
||||||
float m_height_scale;
|
|
||||||
double m_fps_limit = 59.94;
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::mutex cs_main;
|
|
||||||
semaphore_t sem_flip;
|
|
||||||
u64 last_flip_time;
|
|
||||||
vm::ps3::ptr<void(u32)> flip_handler = { 0 };
|
|
||||||
vm::ps3::ptr<void(u32)> user_handler = { 0 };
|
|
||||||
vm::ps3::ptr<void(u32)> vblank_handler = { 0 };
|
|
||||||
u64 vblank_count;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Dither
|
|
||||||
bool m_set_dither;
|
|
||||||
|
|
||||||
// Clip
|
|
||||||
bool m_set_clip;
|
|
||||||
float m_clip_min;
|
|
||||||
float m_clip_max;
|
|
||||||
|
|
||||||
// Depth bound test
|
|
||||||
bool m_set_depth_bounds_test;
|
|
||||||
bool m_set_depth_bounds;
|
|
||||||
float m_depth_bounds_min;
|
|
||||||
float m_depth_bounds_max;
|
|
||||||
|
|
||||||
// Primitive restart
|
|
||||||
bool m_set_restart_index;
|
|
||||||
u32 m_restart_index;
|
|
||||||
|
|
||||||
// Point
|
|
||||||
bool m_set_point_size;
|
|
||||||
bool m_set_point_sprite_control;
|
|
||||||
float m_point_size;
|
|
||||||
u16 m_point_x;
|
|
||||||
u16 m_point_y;
|
|
||||||
|
|
||||||
// Line smooth
|
|
||||||
bool m_set_line_smooth;
|
|
||||||
|
|
||||||
// Viewport & scissor
|
|
||||||
bool m_set_scissor_horizontal;
|
|
||||||
bool m_set_scissor_vertical;
|
|
||||||
u16 m_scissor_x;
|
|
||||||
u16 m_scissor_y;
|
|
||||||
u16 m_scissor_w;
|
|
||||||
u16 m_scissor_h;
|
|
||||||
|
|
||||||
// Polygon mode/offset
|
|
||||||
bool m_set_poly_smooth;
|
|
||||||
bool m_set_poly_offset_fill;
|
|
||||||
bool m_set_poly_offset_line;
|
|
||||||
bool m_set_poly_offset_point;
|
|
||||||
bool m_set_front_polygon_mode;
|
|
||||||
u32 m_front_polygon_mode;
|
|
||||||
bool m_set_back_polygon_mode;
|
|
||||||
u32 m_back_polygon_mode;
|
|
||||||
bool m_set_poly_offset_mode;
|
|
||||||
float m_poly_offset_scale_factor;
|
|
||||||
float m_poly_offset_bias;
|
|
||||||
|
|
||||||
// Line/Polygon stipple
|
|
||||||
bool m_set_line_stipple;
|
|
||||||
u16 m_line_stipple_pattern;
|
|
||||||
u16 m_line_stipple_factor;
|
|
||||||
bool m_set_polygon_stipple;
|
|
||||||
u32 m_polygon_stipple_pattern[32];
|
|
||||||
|
|
||||||
|
|
||||||
// Clearing
|
|
||||||
u32 m_clear_surface_mask;
|
|
||||||
|
|
||||||
// Stencil Test
|
|
||||||
bool m_set_two_side_light_enable;
|
|
||||||
|
|
||||||
// Line width
|
|
||||||
bool m_set_line_width;
|
|
||||||
float m_line_width;
|
|
||||||
|
|
||||||
// Shader mode
|
|
||||||
bool m_set_shade_mode;
|
|
||||||
u32 m_shade_mode;
|
|
||||||
|
|
||||||
// Lighting
|
|
||||||
bool m_set_specular;
|
|
||||||
|
|
||||||
// Color
|
|
||||||
u32 m_color_format;
|
|
||||||
u16 m_color_format_src_pitch;
|
|
||||||
u16 m_color_format_dst_pitch;
|
|
||||||
u32 m_color_conv;
|
|
||||||
u32 m_color_conv_fmt;
|
|
||||||
u32 m_color_conv_op;
|
|
||||||
s16 m_color_conv_clip_x;
|
|
||||||
s16 m_color_conv_clip_y;
|
|
||||||
u16 m_color_conv_clip_w;
|
|
||||||
u16 m_color_conv_clip_h;
|
|
||||||
s16 m_color_conv_out_x;
|
|
||||||
s16 m_color_conv_out_y;
|
|
||||||
u16 m_color_conv_out_w;
|
|
||||||
u16 m_color_conv_out_h;
|
|
||||||
s32 m_color_conv_dsdx;
|
|
||||||
s32 m_color_conv_dtdy;
|
|
||||||
|
|
||||||
// Semaphore
|
|
||||||
// PGRAPH
|
|
||||||
u32 m_PGRAPH_semaphore_offset;
|
|
||||||
//PFIFO
|
|
||||||
u32 m_PFIFO_semaphore_offset;
|
|
||||||
u32 m_PFIFO_semaphore_release_value;
|
|
||||||
|
|
||||||
// Fog
|
|
||||||
bool m_set_fog_mode;
|
|
||||||
u32 m_fog_mode;
|
|
||||||
bool m_set_fog_params;
|
|
||||||
float m_fog_param0;
|
|
||||||
float m_fog_param1;
|
|
||||||
|
|
||||||
// Clip plane
|
|
||||||
bool m_set_clip_plane;
|
|
||||||
bool m_clip_plane_0;
|
|
||||||
bool m_clip_plane_1;
|
|
||||||
bool m_clip_plane_2;
|
|
||||||
bool m_clip_plane_3;
|
|
||||||
bool m_clip_plane_4;
|
|
||||||
bool m_clip_plane_5;
|
|
||||||
|
|
||||||
// Surface
|
|
||||||
rsx::surface_info m_surface;
|
|
||||||
bool m_set_surface_clip_horizontal;
|
|
||||||
bool m_set_surface_clip_vertical;
|
|
||||||
|
|
||||||
// DMA context
|
|
||||||
u32 m_context_surface;
|
|
||||||
u32 m_context_dma_img_src;
|
|
||||||
u32 m_context_dma_img_dst;
|
|
||||||
u32 m_context_dma_buffer_in_src;
|
|
||||||
u32 m_context_dma_buffer_in_dst;
|
|
||||||
u32 m_dst_offset;
|
|
||||||
|
|
||||||
// Swizzle2D?
|
|
||||||
u16 m_swizzle_format;
|
|
||||||
u8 m_swizzle_width;
|
|
||||||
u8 m_swizzle_height;
|
|
||||||
u32 m_swizzle_offset;
|
|
||||||
|
|
||||||
// Shader
|
|
||||||
u16 m_shader_window_height;
|
|
||||||
u8 m_shader_window_origin;
|
|
||||||
u16 m_shader_window_pixel_centers;
|
|
||||||
|
|
||||||
// Vertex Data
|
|
||||||
u32 m_vertex_data_base_index;
|
|
||||||
|
|
||||||
// Frequency divider
|
|
||||||
u32 m_set_frequency_divider_operation;
|
|
||||||
|
|
||||||
u8 m_begin_end;
|
|
||||||
bool m_read_buffer;
|
|
||||||
|
|
||||||
std::set<u32> m_used_gcm_commands;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
RSXThread()
|
|
||||||
: m_shader_ctrl(0x40)
|
|
||||||
, flip_status(0)
|
|
||||||
, flip_mode(CELL_GCM_DISPLAY_VSYNC)
|
|
||||||
, debug_level(CELL_GCM_DEBUG_LEVEL0)
|
|
||||||
, frequency_mode(CELL_GCM_DISPLAY_FREQUENCY_DISABLE)
|
|
||||||
, report_main_addr(0)
|
|
||||||
, main_mem_addr(0)
|
|
||||||
, local_mem_addr(0)
|
|
||||||
, draw_mode(0)
|
|
||||||
, draw_array_count(0)
|
|
||||||
, draw_array_first(~0)
|
|
||||||
, gcm_current_buffer(0)
|
|
||||||
, m_read_buffer(true)
|
|
||||||
{
|
|
||||||
flip_handler.set(0);
|
|
||||||
vblank_handler.set(0);
|
|
||||||
user_handler.set(0);
|
|
||||||
rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false;
|
|
||||||
m_set_depth_bounds_test = false;
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0;
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false;
|
|
||||||
m_set_dither = false;
|
|
||||||
m_set_scissor_horizontal = false;
|
|
||||||
m_set_scissor_vertical = false;
|
|
||||||
m_set_line_smooth = false;
|
|
||||||
m_set_poly_smooth = false;
|
|
||||||
m_set_point_sprite_control = false;
|
|
||||||
m_set_specular = false;
|
|
||||||
m_set_two_side_light_enable = false;
|
|
||||||
m_set_surface_clip_horizontal = false;
|
|
||||||
m_set_surface_clip_vertical = false;
|
|
||||||
m_set_poly_offset_fill = false;
|
|
||||||
m_set_poly_offset_line = false;
|
|
||||||
m_set_poly_offset_point = false;
|
|
||||||
m_set_restart_index = false;
|
|
||||||
m_set_line_stipple = false;
|
|
||||||
m_set_polygon_stipple = false;
|
|
||||||
|
|
||||||
// Default value
|
|
||||||
// TODO: Check against the default value on PS3
|
|
||||||
rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE] = 0;
|
|
||||||
rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff << 8;
|
|
||||||
m_poly_offset_scale_factor = 0.0;
|
|
||||||
m_poly_offset_bias = 0.0;
|
|
||||||
m_restart_index = 0xffffffff;
|
|
||||||
m_front_polygon_mode = 0x1b02; // GL_FILL
|
|
||||||
m_back_polygon_mode = 0x1b02; // GL_FILL
|
|
||||||
rsx::method_registers[NV4097_SET_FRONT_FACE] = 0x0901; // GL_CCW
|
|
||||||
rsx::method_registers[NV4097_SET_CULL_FACE] = 0x0405; // GL_BACK
|
|
||||||
rsx::method_registers[NV4097_SET_ALPHA_FUNC] = 0x0207; // GL_ALWAYS
|
|
||||||
rsx::method_registers[NV4097_SET_ALPHA_REF] = 0.0f;
|
|
||||||
m_shade_mode = 0x1D01; // GL_SMOOTH
|
|
||||||
|
|
||||||
m_depth_bounds_min = 0.0;
|
|
||||||
m_depth_bounds_max = 1.0;
|
|
||||||
m_clip_min = 0.0;
|
|
||||||
m_clip_max = 1.0;
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_EQUATION] = (0x8006) | (0x8006 << 16); // GL_FUNC_ADD
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = 1 | (1 << 16);
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = 0;
|
|
||||||
m_point_x = 0;
|
|
||||||
m_point_y = 0;
|
|
||||||
m_point_size = 1.0;
|
|
||||||
m_line_width = 1.0;
|
|
||||||
m_line_stipple_pattern = 0xffff;
|
|
||||||
m_line_stipple_factor = 1;
|
|
||||||
rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] = 0;
|
|
||||||
m_vertex_data_base_index = 0;
|
|
||||||
|
|
||||||
// Construct Stipple Pattern
|
|
||||||
for (size_t i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
m_polygon_stipple_pattern[i] = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct Textures
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
textures[i] = rsx::texture();
|
|
||||||
}
|
|
||||||
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~RSXThread() override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset()
|
|
||||||
{
|
|
||||||
rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false;
|
|
||||||
rsx::method_registers[NV4097_SET_DEPTH_MASK] = 1;
|
|
||||||
rsx::method_registers[NV4097_SET_DEPTH_FUNC] = 0x0201;
|
|
||||||
|
|
||||||
m_set_dither = false;
|
|
||||||
rsx::method_registers[NV4097_SET_COLOR_MASK] = -1;
|
|
||||||
m_set_clip = false;
|
|
||||||
m_set_depth_bounds_test = false;
|
|
||||||
m_set_depth_bounds = false;
|
|
||||||
m_set_scissor_horizontal = false;
|
|
||||||
m_set_scissor_vertical = false;
|
|
||||||
m_set_front_polygon_mode = false;
|
|
||||||
m_set_back_polygon_mode = false;
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0;
|
|
||||||
rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false;
|
|
||||||
m_set_two_side_light_enable = false;
|
|
||||||
m_set_point_sprite_control = false;
|
|
||||||
m_set_point_size = false;
|
|
||||||
m_set_line_width = false;
|
|
||||||
m_set_line_smooth = false;
|
|
||||||
m_set_shade_mode = false;
|
|
||||||
m_set_fog_mode = false;
|
|
||||||
m_set_fog_params = false;
|
|
||||||
m_set_clip_plane = false;
|
|
||||||
rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false;
|
|
||||||
rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false;
|
|
||||||
rsx::method_registers[NV4097_SET_ALPHA_FUNC] = false;
|
|
||||||
rsx::method_registers[NV4097_SET_ALPHA_REF] = false;
|
|
||||||
m_set_poly_smooth = false;
|
|
||||||
m_set_poly_offset_fill = false;
|
|
||||||
m_set_poly_offset_line = false;
|
|
||||||
m_set_poly_offset_point = false;
|
|
||||||
m_set_poly_offset_mode = false;
|
|
||||||
m_set_restart_index = false;
|
|
||||||
m_set_specular = false;
|
|
||||||
m_set_line_stipple = false;
|
|
||||||
m_set_polygon_stipple = false;
|
|
||||||
m_set_surface_clip_horizontal = false;
|
|
||||||
m_set_surface_clip_vertical = false;
|
|
||||||
|
|
||||||
m_clear_surface_mask = 0;
|
|
||||||
m_begin_end = 0;
|
|
||||||
|
|
||||||
for (uint i = 0; i < rsx::limits::textures_count; ++i)
|
|
||||||
{
|
|
||||||
textures[i].init(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void begin(u32 draw_mode);
|
|
||||||
void End();
|
|
||||||
|
|
||||||
u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr);
|
|
||||||
void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count);
|
|
||||||
|
|
||||||
virtual void oninit() = 0;
|
|
||||||
virtual void oninit_thread() = 0;
|
|
||||||
virtual void onexit_thread() = 0;
|
|
||||||
virtual void OnReset() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This member is called when the backend is expected to render a draw call, either
|
|
||||||
* indexed or not.
|
|
||||||
*/
|
|
||||||
virtual void end() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This member is called when the backend is expected to clear a target surface.
|
|
||||||
*/
|
|
||||||
virtual void clear_surface(u32 arg) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This member is called when the backend is expected to present a target surface in
|
|
||||||
* either local or main memory.
|
|
||||||
*/
|
|
||||||
virtual void flip(int buffer) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE
|
|
||||||
* command.
|
|
||||||
* Backend is expected to write value at offset when current draw textures aren't
|
|
||||||
* needed anymore by the GPU and can be modified.
|
|
||||||
*/
|
|
||||||
virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0;
|
|
||||||
/**
|
|
||||||
* This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE
|
|
||||||
* command.
|
|
||||||
* Backend is expected to write value at offset when current draw call has completed
|
|
||||||
* and render surface can be used.
|
|
||||||
*/
|
|
||||||
virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0;
|
|
||||||
/**
|
|
||||||
* This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command.
|
|
||||||
* Backend and associated GPU is expected to wait that memory at offset is the same
|
|
||||||
* as value. In particular buffer/texture buffers value can change while backend is
|
|
||||||
* waiting.
|
|
||||||
*/
|
|
||||||
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0;
|
|
||||||
/**
|
|
||||||
* Called when vertex or fragment shader changes.
|
|
||||||
* Backend can reuse same program if no change has been notified.
|
|
||||||
*/
|
|
||||||
virtual void notifyProgramChange() = 0;
|
|
||||||
/**
|
|
||||||
* Called when blend state changes.
|
|
||||||
* Backend can reuse same program if no change has been notified.
|
|
||||||
*/
|
|
||||||
virtual void notifyBlendStateChange() = 0;
|
|
||||||
/**
|
|
||||||
* Called when depth stencil state changes.
|
|
||||||
* Backend can reuse same program if no change has been notified.
|
|
||||||
*/
|
|
||||||
virtual void notifyDepthStencilStateChange() = 0;
|
|
||||||
/**
|
|
||||||
* Called when rasterizer state changes.
|
|
||||||
* Rasterizer state includes culling, color masking
|
|
||||||
* Backend can reuse same program if no change has been notified.
|
|
||||||
*/
|
|
||||||
virtual void notifyRasterizerStateChange() = 0;
|
|
||||||
|
|
||||||
void LoadVertexData(u32 first, u32 count)
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
|
|
||||||
{
|
|
||||||
// if (!m_vertex_data[i].IsEnabled()) continue;
|
|
||||||
|
|
||||||
// m_vertex_data[i].Load(first, count, m_vertex_data_base_offset, m_vertex_data_base_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Task();
|
|
||||||
|
|
||||||
public:
|
|
||||||
void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);
|
|
||||||
|
|
||||||
u32 ReadIO32(u32 addr);
|
|
||||||
|
|
||||||
void WriteIO32(u32 addr, u32 value);
|
|
||||||
};
|
|
||||||
|
@ -396,7 +396,7 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
|||||||
render.gcm_current_buffer = 0;
|
render.gcm_current_buffer = 0;
|
||||||
render.main_mem_addr = 0;
|
render.main_mem_addr = 0;
|
||||||
render.label_addr = gcm_info.label_addr;
|
render.label_addr = gcm_info.label_addr;
|
||||||
render.Init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr);
|
render.init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user