glBufferSubData VBO

This commit is contained in:
Phantom 2017-10-10 03:43:26 +02:00
parent e258faf0f0
commit a1112cb712
5 changed files with 27 additions and 17 deletions

View File

@ -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];

View File

@ -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:

View File

@ -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.

View File

@ -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;

View File

@ -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;