summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-05-01 17:47:52 +0200
committerdegasus <wickmarkus@web.de>2015-05-20 11:05:31 +0200
commitd91d93505710aaef711a2cbb1b3ca6b8cee66cfa (patch)
tree48b64362840f1f137b8f54df827fc032c168fe08 /Source
parentc7bae5ad114061cc14084344a0f1761d3583334e (diff)
OGL: reimplement poke-color
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoBackends/OGL/FramebufferManager.cpp83
-rw-r--r--Source/Core/VideoBackends/OGL/FramebufferManager.h7
-rw-r--r--Source/Core/VideoBackends/OGL/Render.cpp40
-rw-r--r--Source/Core/VideoBackends/OGL/Render.h1
4 files changed, 114 insertions, 17 deletions
diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp
index 3eea0dcd36..2504dbe260 100644
--- a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp
+++ b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp
@@ -35,6 +35,10 @@ GLuint FramebufferManager::m_resolvedDepthTexture;
// reinterpret pixel format
SHADER FramebufferManager::m_pixel_format_shaders[2];
+// EFB pokes
+GLuint FramebufferManager::m_EfbColorPokes_VBO;
+GLuint FramebufferManager::m_EfbColorPokes_VAO;
+SHADER FramebufferManager::m_EfbColorPokes;
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples)
{
@@ -318,6 +322,51 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6.c_str(), (m_EFBLayers > 1) ? gs.c_str() : nullptr);
ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8.c_str(), (m_EFBLayers > 1) ? gs.c_str() : nullptr);
+
+ ProgramShaderCache::CompileShader(m_EfbColorPokes,
+ StringFromFormat(
+ "in vec2 rawpos;\n"
+ "in vec4 color0;\n"
+ "out vec4 v_c;\n"
+ "void main(void) {\n"
+ " gl_Position = vec4(((rawpos + 0.5) / vec2(640.0, 528.0) * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);\n"
+ " gl_PointSize = %d.0 / 640.0;\n"
+ " v_c = color0;\n"
+ "}\n", m_targetWidth).c_str(),
+
+ StringFromFormat(
+ "in vec4 %s_c;\n"
+ "out vec4 ocol0;\n"
+ "void main(void) {\n"
+ " ocol0 = %s_c.bgra;\n"
+ "}\n", m_EFBLayers > 1 ? "g" : "v", m_EFBLayers > 1 ? "g" : "v").c_str(),
+
+ m_EFBLayers > 1 ? StringFromFormat(
+ "layout(points) in;\n"
+ "layout(points, max_vertices = %d) out;\n"
+ "in vec4 v_c[1];\n"
+ "out vec4 g_c;\n"
+ "void main()\n"
+ "{\n"
+ " for (int j = 0; j < %d; ++j) {\n"
+ " gl_Layer = j;\n"
+ " gl_Position = gl_in[0].gl_Position;\n"
+ " gl_PointSize = %d.0 / 640.0;\n"
+ " g_c = v_c[0];\n"
+ " EmitVertex();\n"
+ " EndPrimitive();\n"
+ " }\n"
+ "}\n", m_EFBLayers, m_EFBLayers, m_targetWidth).c_str() : nullptr);
+ glGenBuffers(1, &m_EfbColorPokes_VBO);
+ glGenVertexArrays(1, &m_EfbColorPokes_VAO);
+ glBindBuffer(GL_ARRAY_BUFFER, m_EfbColorPokes_VBO);
+ glBindVertexArray(m_EfbColorPokes_VAO );
+ glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
+ glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_UNSIGNED_SHORT, 0, sizeof(EfbPokeData), (void*)offsetof(EfbPokeData, x));
+ glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB);
+ glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 4, GL_UNSIGNED_BYTE, 1, sizeof(EfbPokeData), (void*)offsetof(EfbPokeData, data));
+
+ glEnable(GL_PROGRAM_POINT_SIZE);
}
FramebufferManager::~FramebufferManager()
@@ -355,6 +404,13 @@ FramebufferManager::~FramebufferManager()
// reinterpret pixel format
m_pixel_format_shaders[0].Destroy();
m_pixel_format_shaders[1].Destroy();
+
+ // EFB pokes
+ glDeleteBuffers(1, &m_EfbColorPokes_VBO);
+ glDeleteVertexArrays(1, &m_EfbColorPokes_VAO);
+ m_EfbColorPokes_VBO = 0;
+ m_EfbColorPokes_VAO = 0;
+ m_EfbColorPokes.Destroy();
}
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
@@ -551,4 +607,31 @@ void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height
*height = m_targetHeight;
}
+void FramebufferManager::PokeEFB(EFBAccessType type, const std::vector<EfbPokeData>& data)
+{
+ switch (type)
+ {
+ case POKE_COLOR:
+ {
+ g_renderer->ResetAPIState();
+
+ glBindVertexArray(m_EfbColorPokes_VAO);
+ glBindBuffer(GL_ARRAY_BUFFER, m_EfbColorPokes_VBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(EfbPokeData) * data.size(), data.data(), GL_STREAM_DRAW);
+ m_EfbColorPokes.Bind();
+ glViewport(0, 0, m_targetWidth, m_targetHeight);
+ glDrawArrays(GL_POINTS, 0, (GLsizei)data.size());
+
+ g_renderer->RestoreAPIState();
+
+ // TODO: Could just update the EFB cache with the new value
+ ClearEFBCache();
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
} // namespace OGL
diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.h b/Source/Core/VideoBackends/OGL/FramebufferManager.h
index 9b26e32335..88909f4ff6 100644
--- a/Source/Core/VideoBackends/OGL/FramebufferManager.h
+++ b/Source/Core/VideoBackends/OGL/FramebufferManager.h
@@ -91,6 +91,8 @@ public:
// convtype=0 -> rgb8->rgba6, convtype=2 -> rgba6->rgb8
static void ReinterpretPixelData(unsigned int convtype);
+ static void PokeEFB(EFBAccessType type, const std::vector<EfbPokeData>& data);
+
private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height, unsigned int layers) override;
void GetTargetSize(unsigned int *width, unsigned int *height) override;
@@ -115,6 +117,11 @@ private:
// For pixel format draw
static SHADER m_pixel_format_shaders[2];
+
+ // For EFB pokes
+ static GLuint m_EfbColorPokes_VBO;
+ static GLuint m_EfbColorPokes_VAO;
+ static SHADER m_EfbColorPokes;
};
} // namespace OGL
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index 1b13595386..812b7f2656 100644
--- a/Source/Core/VideoBackends/OGL/Render.cpp
+++ b/Source/Core/VideoBackends/OGL/Render.cpp
@@ -1106,23 +1106,13 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
case POKE_COLOR:
{
- ResetAPIState();
-
- glClearColor(float((poke_data >> 16) & 0xFF) / 255.0f,
- float((poke_data >> 8) & 0xFF) / 255.0f,
- float((poke_data >> 0) & 0xFF) / 255.0f,
- float((poke_data >> 24) & 0xFF) / 255.0f);
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(targetPixelRc.left, targetPixelRc.bottom, targetPixelRc.GetWidth(), targetPixelRc.GetHeight());
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- RestoreAPIState();
-
- // TODO: Could just update the EFB cache with the new value
- ClearEFBCache();
-
+ std::vector<EfbPokeData> vector;
+ EfbPokeData d;
+ d.x = x;
+ d.y = y;
+ d.data = poke_data;
+ vector.push_back(d);
+ PokeEFB(type, vector);
break;
}
@@ -1153,6 +1143,22 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
return 0;
}
+void Renderer::PokeEFB(EFBAccessType type, const std::vector<EfbPokeData>& data)
+{
+ switch(type)
+ {
+ case POKE_COLOR:
+ {
+ FramebufferManager::PokeEFB(type, data);
+ break;
+ }
+
+ default:
+ ::Renderer::PokeEFB(type, data);
+ break;
+ }
+}
+
u16 Renderer::BBoxRead(int index)
{
int swapped_index = index;
diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h
index 9d4951b54c..0b1d82cb42 100644
--- a/Source/Core/VideoBackends/OGL/Render.h
+++ b/Source/Core/VideoBackends/OGL/Render.h
@@ -71,6 +71,7 @@ public:
void FlipImageData(u8 *data, int w, int h, int pixel_width = 3);
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
+ void PokeEFB(EFBAccessType type, const std::vector<EfbPokeData>& data) override;
u16 BBoxRead(int index) override;
void BBoxWrite(int index, u16 value) override;