mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-26 23:20:05 +00:00
glBufferSubData VBO
This commit is contained in:
parent
e258faf0f0
commit
a1112cb712
@ -352,10 +352,6 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
|||||||
shader_engine->SetupBatch(g_state.vs, regs.vs.main_offset);
|
shader_engine->SetupBatch(g_state.vs, regs.vs.main_offset);
|
||||||
|
|
||||||
const bool use_gs = regs.pipeline.use_gs == PipelineRegs::UseGS::Yes;
|
const bool use_gs = regs.pipeline.use_gs == PipelineRegs::UseGS::Yes;
|
||||||
g_state.geometry_pipeline.Reconfigure();
|
|
||||||
g_state.geometry_pipeline.Setup(shader_engine);
|
|
||||||
if (g_state.geometry_pipeline.NeedIndexInput())
|
|
||||||
ASSERT(is_indexed);
|
|
||||||
|
|
||||||
auto VSUnitLoop = [&](u32 thread_id, auto num_threads) {
|
auto VSUnitLoop = [&](u32 thread_id, auto num_threads) {
|
||||||
constexpr bool single_thread = std::is_same_v<std::integral_constant<u32, 1>, decltype(num_threads)>;
|
constexpr bool single_thread = std::is_same_v<std::integral_constant<u32, 1>, decltype(num_threads)>;
|
||||||
@ -436,6 +432,11 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_state.geometry_pipeline.Reconfigure();
|
||||||
|
g_state.geometry_pipeline.Setup(shader_engine);
|
||||||
|
if (g_state.geometry_pipeline.NeedIndexInput())
|
||||||
|
ASSERT(is_indexed);
|
||||||
|
|
||||||
for (unsigned int index = 0; index < regs.pipeline.num_vertices; ++index) {
|
for (unsigned int index = 0; index < regs.pipeline.num_vertices; ++index) {
|
||||||
unsigned int vertex = VertexIndex(index);
|
unsigned int vertex = VertexIndex(index);
|
||||||
auto& cached_vertex = vs_output[is_indexed ? vertex : index];
|
auto& cached_vertex = vs_output[is_indexed ? vertex : index];
|
||||||
|
@ -15,7 +15,7 @@ PrimitiveAssembler<VertexType>::PrimitiveAssembler(PipelineRegs::TriangleTopolog
|
|||||||
|
|
||||||
template <typename VertexType>
|
template <typename VertexType>
|
||||||
void PrimitiveAssembler<VertexType>::SubmitVertex(const VertexType& vtx,
|
void PrimitiveAssembler<VertexType>::SubmitVertex(const VertexType& vtx,
|
||||||
TriangleHandler triangle_handler) {
|
const TriangleHandler& triangle_handler) {
|
||||||
switch (topology) {
|
switch (topology) {
|
||||||
case PipelineRegs::TriangleTopology::List:
|
case PipelineRegs::TriangleTopology::List:
|
||||||
case PipelineRegs::TriangleTopology::Shader:
|
case PipelineRegs::TriangleTopology::Shader:
|
||||||
|
@ -27,7 +27,7 @@ struct PrimitiveAssembler {
|
|||||||
* NOTE: We could specify the triangle handler in the constructor, but this way we can
|
* NOTE: We could specify the triangle handler in the constructor, but this way we can
|
||||||
* keep event and handler code next to each other.
|
* keep event and handler code next to each other.
|
||||||
*/
|
*/
|
||||||
void SubmitVertex(const VertexType& vtx, TriangleHandler triangle_handler);
|
void SubmitVertex(const VertexType& vtx, const TriangleHandler& triangle_handler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invert the vertex order of the next triangle. Called by geometry shader emitter.
|
* Invert the vertex order of the next triangle. Called by geometry shader emitter.
|
||||||
|
@ -27,7 +27,7 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
|
|||||||
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
||||||
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
||||||
|
|
||||||
RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) {
|
RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true), vertex_buffer_size(0) {
|
||||||
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
|
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
|
||||||
state.clip_distance[0] = true;
|
state.clip_distance[0] = true;
|
||||||
|
|
||||||
@ -236,24 +236,24 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
color_surface != nullptr ? color_surface->texture.handle : 0, 0);
|
color_surface != nullptr ? color_surface->texture.handle : 0, 0);
|
||||||
if (depth_surface != nullptr) {
|
if (depth_surface != nullptr) {
|
||||||
if (regs.framebuffer.framebuffer.depth_format ==
|
if (regs.framebuffer.framebuffer.depth_format ==
|
||||||
Pica::FramebufferRegs::DepthFormat::D24S8) {
|
Pica::FramebufferRegs::DepthFormat::D24S8) {
|
||||||
// attach both depth and stencil
|
// attach both depth and stencil
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||||
depth_surface->texture.handle, 0);
|
depth_surface->texture.handle, 0);
|
||||||
} else {
|
} else {
|
||||||
// attach depth
|
// attach depth
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
||||||
depth_surface->texture.handle, 0);
|
depth_surface->texture.handle, 0);
|
||||||
// clear stencil attachment
|
// clear stencil attachment
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// clear both depth and stencil attachment
|
// clear both depth and stencil attachment
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the viewport
|
// Sync the viewport
|
||||||
@ -263,6 +263,11 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
GLsizei viewport_height =
|
GLsizei viewport_height =
|
||||||
(GLsizei)Pica::float24::FromRaw(regs.rasterizer.viewport_size_y).ToFloat32() * 2;
|
(GLsizei)Pica::float24::FromRaw(regs.rasterizer.viewport_size_y).ToFloat32() * 2;
|
||||||
|
|
||||||
|
const float res_scale_width = color_surface != nullptr ? color_surface->res_scale_width :
|
||||||
|
(depth_surface == nullptr ? 1.0f : depth_surface->res_scale_width);
|
||||||
|
const float res_scale_height = color_surface != nullptr ? color_surface->res_scale_height :
|
||||||
|
(depth_surface == nullptr ? 1.0f : depth_surface->res_scale_height);
|
||||||
|
|
||||||
glViewport(
|
glViewport(
|
||||||
(GLint)(rect.left + regs.rasterizer.viewport_corner.x * color_surface->res_scale_width),
|
(GLint)(rect.left + regs.rasterizer.viewport_corner.x * color_surface->res_scale_width),
|
||||||
(GLint)(rect.bottom + regs.rasterizer.viewport_corner.y * color_surface->res_scale_height),
|
(GLint)(rect.bottom + regs.rasterizer.viewport_corner.y * color_surface->res_scale_height),
|
||||||
@ -374,16 +379,21 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
// Sync the uniform data
|
// Sync the uniform data
|
||||||
if (uniform_block_data.dirty) {
|
if (uniform_block_data.dirty) {
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data,
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data,
|
||||||
GL_STATIC_DRAW);
|
GL_STATIC_DRAW);
|
||||||
uniform_block_data.dirty = false;
|
uniform_block_data.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
// Draw the vertex batch
|
// Draw the vertex batch
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(),
|
GLsizeiptr target_size = vertex_batch.size() * sizeof(HardwareVertex);
|
||||||
GL_STREAM_DRAW);
|
if (vertex_buffer_size < target_size) {
|
||||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size());
|
vertex_buffer_size = target_size * 2;
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, nullptr, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, target_size, vertex_batch.data());
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertex_batch.size()));
|
||||||
|
vertex_batch.clear();
|
||||||
|
|
||||||
// Mark framebuffer surfaces as dirty
|
// Mark framebuffer surfaces as dirty
|
||||||
// TODO: Restrict invalidation area to the viewport
|
// TODO: Restrict invalidation area to the viewport
|
||||||
@ -396,8 +406,6 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
res_cache.FlushRegion(depth_surface->addr, depth_surface->size, depth_surface, true);
|
res_cache.FlushRegion(depth_surface->addr, depth_surface->size, depth_surface, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex_batch.clear();
|
|
||||||
|
|
||||||
// Unbind textures for potential future use as framebuffer attachments
|
// Unbind textures for potential future use as framebuffer attachments
|
||||||
for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) {
|
for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) {
|
||||||
state.texture_units[texture_index].texture_2d = 0;
|
state.texture_units[texture_index].texture_2d = 0;
|
||||||
|
@ -283,6 +283,7 @@ private:
|
|||||||
std::array<SamplerInfo, 3> texture_samplers;
|
std::array<SamplerInfo, 3> texture_samplers;
|
||||||
OGLVertexArray vertex_array;
|
OGLVertexArray vertex_array;
|
||||||
OGLBuffer vertex_buffer;
|
OGLBuffer vertex_buffer;
|
||||||
|
GLsizeiptr vertex_buffer_size;
|
||||||
OGLBuffer uniform_buffer;
|
OGLBuffer uniform_buffer;
|
||||||
OGLFramebuffer framebuffer;
|
OGLFramebuffer framebuffer;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user