From ed2134784e173e071a124c768eea5dd12be8425c Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 02:01:03 -0400 Subject: gl_rasterizer: Implement AnalyzeVertexArray. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 286491b73..982e84768 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -14,7 +14,10 @@ #include "common/microprofile.h" #include "common/scope_exit.h" #include "common/vector_math.h" +#include "core/core.h" +#include "core/hle/kernel/process.h" #include "core/settings.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/renderer_opengl.h" @@ -146,7 +149,24 @@ static constexpr std::array vs_attrib_types{ }; void RasterizerOpenGL::AnalyzeVertexArray(bool is_indexed) { - UNIMPLEMENTED(); + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + const auto& vertex_attributes = regs.vertex_attrib_format; + + if (is_indexed) { + UNREACHABLE(); + } + const u32 vertex_num = regs.vertex_buffer.count; + + vs_input_size = 0; + u32 max_offset{}; + for (const auto& attrib : vertex_attributes) { + if (max_offset >= attrib.offset) { + continue; + } + max_offset = attrib.offset; + vs_input_size = max_offset + attrib.SizeInBytes(); + } + vs_input_size *= vertex_num; } void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { -- cgit v1.2.3 From 0162a2d5cbfb0e0df7f99187a87c031416fd79cc Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 03:59:51 -0400 Subject: gl_rasterizer: Implement DrawTriangles. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 195 ++++++++++++++++++++++- 1 file changed, 194 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 982e84768..c44ce4a18 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -197,8 +197,201 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { } void RasterizerOpenGL::DrawTriangles() { + if (accelerate_draw == AccelDraw::Disabled) + return; + MICROPROFILE_SCOPE(OpenGL_Drawing); - UNIMPLEMENTED(); + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + + // TODO(bunnei): Implement these + const bool has_stencil = false; + const bool using_color_fb = true; + const bool using_depth_fb = false; + + MathUtil::Rectangle viewport_rect_unscaled{ + static_cast(regs.viewport[0].x), // left + static_cast(regs.viewport[0].y + regs.viewport[0].height), // top + static_cast(regs.viewport[0].x + regs.viewport[0].width), // right + static_cast(regs.viewport[0].y) // bottom + }; + + const bool write_color_fb = + state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || + state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE; + + const bool write_depth_fb = + (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) || + (has_stencil && state.stencil.test_enabled && state.stencil.write_mask != 0); + + Surface color_surface; + Surface depth_surface; + MathUtil::Rectangle surfaces_rect; + std::tie(color_surface, depth_surface, surfaces_rect) = + res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect_unscaled); + + const u16 res_scale = color_surface != nullptr + ? color_surface->res_scale + : (depth_surface == nullptr ? 1u : depth_surface->res_scale); + + MathUtil::Rectangle draw_rect{ + static_cast(MathUtil::Clamp(static_cast(surfaces_rect.left) + + viewport_rect_unscaled.left * res_scale, + surfaces_rect.left, surfaces_rect.right)), // Left + static_cast(MathUtil::Clamp(static_cast(surfaces_rect.bottom) + + viewport_rect_unscaled.top * res_scale, + surfaces_rect.bottom, surfaces_rect.top)), // Top + static_cast(MathUtil::Clamp(static_cast(surfaces_rect.left) + + viewport_rect_unscaled.right * res_scale, + surfaces_rect.left, surfaces_rect.right)), // Right + static_cast(MathUtil::Clamp(static_cast(surfaces_rect.bottom) + + viewport_rect_unscaled.bottom * res_scale, + surfaces_rect.bottom, surfaces_rect.top))}; // Bottom + + // Bind the framebuffer surfaces + state.draw.draw_framebuffer = framebuffer.handle; + state.Apply(); + + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + color_surface != nullptr ? color_surface->texture.handle : 0, 0); + if (depth_surface != nullptr) { + if (has_stencil) { + // attach both depth and stencil + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + depth_surface->texture.handle, 0); + } else { + // attach depth + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + depth_surface->texture.handle, 0); + // clear stencil attachment + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + } + } else { + // clear both depth and stencil attachment + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, + 0); + } + + // Sync the viewport + state.viewport.x = + static_cast(surfaces_rect.left) + viewport_rect_unscaled.left * res_scale; + state.viewport.y = + static_cast(surfaces_rect.bottom) + viewport_rect_unscaled.bottom * res_scale; + state.viewport.width = static_cast(viewport_rect_unscaled.GetWidth() * res_scale); + state.viewport.height = static_cast(viewport_rect_unscaled.GetHeight() * res_scale); + + // TODO(bunnei): Sync framebuffer_scale uniform here + // TODO(bunnei): Sync scissorbox uniform(s) here + // TODO(bunnei): Sync and bind the texture surfaces + + // Sync and bind the shader + if (shader_dirty) { + SetShader(); + shader_dirty = false; + } + + // Sync the uniform data + if (uniform_block_data.dirty) { + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformData), &uniform_block_data.data); + uniform_block_data.dirty = false; + } + + // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable + // scissor test to prevent drawing outside of the framebuffer region + state.scissor.enabled = true; + state.scissor.x = draw_rect.left; + state.scissor.y = draw_rect.bottom; + state.scissor.width = draw_rect.GetWidth(); + state.scissor.height = draw_rect.GetHeight(); + state.Apply(); + + // Draw the vertex batch + GLenum primitive_mode; + switch (regs.draw.topology) { + case Maxwell::PrimitiveTopology::TriangleStrip: + primitive_mode = GL_TRIANGLE_STRIP; + break; + default: + UNREACHABLE(); + } + + const bool is_indexed = accelerate_draw == AccelDraw::Indexed; + + AnalyzeVertexArray(is_indexed); + state.draw.vertex_buffer = stream_buffer->GetHandle(); + state.Apply(); + + size_t buffer_size = static_cast(vs_input_size); + if (is_indexed) { + UNREACHABLE(); + } + buffer_size += sizeof(VSUniformData); + + size_t ptr_pos = 0; + u8* buffer_ptr; + GLintptr buffer_offset; + std::tie(buffer_ptr, buffer_offset) = + stream_buffer->Map(static_cast(buffer_size), 4); + + SetupVertexArray(buffer_ptr, buffer_offset); + ptr_pos += vs_input_size; + + GLintptr index_buffer_offset = 0; + if (is_indexed) { + UNREACHABLE(); + } + + SetupVertexShader(reinterpret_cast(&buffer_ptr[ptr_pos]), + buffer_offset + static_cast(ptr_pos)); + const GLintptr vs_ubo_offset = buffer_offset + static_cast(ptr_pos); + ptr_pos += sizeof(VSUniformData); + + stream_buffer->Unmap(); + + const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { + if (has_ARB_direct_state_access) { + glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size); + } else { + glBindBuffer(GL_COPY_WRITE_BUFFER, handle); + glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size); + } + }; + + copy_buffer(vs_uniform_buffer.handle, vs_ubo_offset, sizeof(VSUniformData)); + + glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_shader->shader.handle); + + if (is_indexed) { + UNREACHABLE(); + } else { + glDrawArrays(primitive_mode, 0, regs.vertex_buffer.count); + } + + // Disable scissor test + state.scissor.enabled = false; + + accelerate_draw = AccelDraw::Disabled; + + // Unbind textures for potential future use as framebuffer attachments + for (auto& texture_unit : state.texture_units) { + texture_unit.texture_2d = 0; + } + state.Apply(); + + // Mark framebuffer surfaces as dirty + MathUtil::Rectangle draw_rect_unscaled{ + draw_rect.left / res_scale, draw_rect.top / res_scale, draw_rect.right / res_scale, + draw_rect.bottom / res_scale}; + + if (color_surface != nullptr && write_color_fb) { + auto interval = color_surface->GetSubRectInterval(draw_rect_unscaled); + res_cache.InvalidateRegion(boost::icl::first(interval), boost::icl::length(interval), + color_surface); + } + if (depth_surface != nullptr && write_depth_fb) { + auto interval = depth_surface->GetSubRectInterval(draw_rect_unscaled); + res_cache.InvalidateRegion(boost::icl::first(interval), boost::icl::length(interval), + depth_surface); + } } void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {} -- cgit v1.2.3 From 0ee38e136376964c0f80362952130258cc661c60 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 04:06:26 -0400 Subject: gl_rasterizer: Use 32 texture units instead of 3. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c44ce4a18..fae9abd19 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -22,6 +22,7 @@ #include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/renderer_opengl.h" +using Maxwell = Tegra::Engines::Maxwell3D::Regs; using PixelFormat = SurfaceParams::PixelFormat; using SurfaceType = SurfaceParams::SurfaceType; -- cgit v1.2.3 From c2dbdefedf2496b383e4686fdf3227c8c9576b09 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 21:29:47 -0400 Subject: gl_rasterizer: Implement SetupVertexArray. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 58 ++++++++++++++++-------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index fae9abd19..41e4ece1e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -142,37 +142,55 @@ RasterizerOpenGL::~RasterizerOpenGL() { } } -static constexpr std::array vs_attrib_types{ - GL_BYTE, // VertexAttributeFormat::BYTE - GL_UNSIGNED_BYTE, // VertexAttributeFormat::UBYTE - GL_SHORT, // VertexAttributeFormat::SHORT - GL_FLOAT // VertexAttributeFormat::FLOAT -}; - void RasterizerOpenGL::AnalyzeVertexArray(bool is_indexed) { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; - const auto& vertex_attributes = regs.vertex_attrib_format; if (is_indexed) { UNREACHABLE(); } - const u32 vertex_num = regs.vertex_buffer.count; - vs_input_size = 0; - u32 max_offset{}; - for (const auto& attrib : vertex_attributes) { - if (max_offset >= attrib.offset) { - continue; - } - max_offset = attrib.offset; - vs_input_size = max_offset + attrib.SizeInBytes(); - } - vs_input_size *= vertex_num; + // TODO(bunnei): Add support for 1+ vertex arrays + vs_input_size = regs.vertex_buffer.count * regs.vertex_array[0].stride; } void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { MICROPROFILE_SCOPE(OpenGL_VAO); - UNIMPLEMENTED(); + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; + + state.draw.vertex_array = hw_vao.handle; + state.draw.vertex_buffer = stream_buffer->GetHandle(); + state.Apply(); + + // TODO(bunnei): Add support for 1+ vertex arrays + const auto& vertex_array{regs.vertex_array[0]}; + ASSERT_MSG(vertex_array.enable, "vertex array 0 is disabled?"); + ASSERT_MSG(!vertex_array.divisor, "vertex array 0 divisor is unimplemented!"); + for (unsigned index = 1; index < Maxwell::NumVertexArrays; ++index) { + ASSERT_MSG(!regs.vertex_array[index].enable, "vertex array %d is unimplemented!", index); + } + + // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. + // Enables the first 16 vertex attributes always, as we don't know which ones are actually used + // until shader time. Note, Tegra technically supports 32, but we're cappinig this to 16 for now + // to avoid OpenGL errors. + for (unsigned index = 0; index < 16; ++index) { + auto& attrib = regs.vertex_attrib_format[index]; + glVertexAttribPointer(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + GL_FALSE, vertex_array.stride, + reinterpret_cast(buffer_offset + attrib.offset)); + glEnableVertexAttribArray(index); + hw_vao_enabled_attributes[index] = true; + } + + // Copy vertex array data + const u32 data_size{vertex_array.stride * regs.vertex_buffer.count}; + const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(vertex_array.StartAddress())}; + res_cache.FlushRegion(data_addr, data_size, nullptr); + std::memcpy(array_ptr, Memory::GetPointer(data_addr), data_size); + + array_ptr += data_size; + buffer_offset += data_size; } void RasterizerOpenGL::SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset) { -- cgit v1.2.3 From 0a5832798a0ce33a84e74a6f9aedc90278cb05ac Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 22:38:08 -0400 Subject: renderer_opengl: Logging, etc. cleanup. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 35 ++++++++++++------------ 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 41e4ece1e..72481509b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -20,6 +20,7 @@ #include "video_core/engines/maxwell_3d.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_gen.h" +#include "video_core/renderer_opengl/maxwell_to_gl.h" #include "video_core/renderer_opengl/renderer_opengl.h" using Maxwell = Tegra::Engines::Maxwell3D::Regs; @@ -124,14 +125,14 @@ RasterizerOpenGL::RasterizerOpenGL() { glBufferData(GL_UNIFORM_BUFFER, sizeof(VSUniformData), nullptr, GL_STREAM_COPY); glBindBufferBase(GL_UNIFORM_BUFFER, 1, vs_uniform_buffer.handle); } else { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } accelerate_draw = AccelDraw::Disabled; glEnable(GL_BLEND); - LOG_WARNING(HW_GPU, "Sync fixed function OpenGL state here when ready"); + LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); } RasterizerOpenGL::~RasterizerOpenGL() { @@ -200,12 +201,12 @@ void RasterizerOpenGL::SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_ void RasterizerOpenGL::SetupFragmentShader(FSUniformData* ub_ptr, GLintptr buffer_offset) { MICROPROFILE_SCOPE(OpenGL_FS); - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { if (!has_ARB_separate_shader_objects) { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); return false; } @@ -438,17 +439,17 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) { MICROPROFILE_SCOPE(OpenGL_Blits); - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); return true; } bool RasterizerOpenGL::AccelerateTextureCopy(const void* config) { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); return true; } bool RasterizerOpenGL::AccelerateFill(const void* config) { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); return true; } @@ -529,14 +530,14 @@ void main() { return; } - LOG_ERROR(HW_GPU, "Emulated shaders are not supported! Using a passthrough shader."); + LOG_CRITICAL(Render_OpenGL, "Emulated shaders are not supported! Using a passthrough shader."); current_shader = &test_shader; if (has_ARB_separate_shader_objects) { test_shader.shader.Create(vertex_shader, nullptr, fragment_shader, {}, true); glActiveShaderProgram(pipeline.handle, test_shader.shader.handle); } else { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } state.draw.shader_program = test_shader.shader.handle; @@ -549,33 +550,33 @@ void main() { } void RasterizerOpenGL::SyncClipEnabled() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncClipCoef() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncCullMode() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncDepthScale() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncDepthOffset() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncBlendEnabled() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncBlendFuncs() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } void RasterizerOpenGL::SyncBlendColor() { - ASSERT_MSG(false, "Unimplemented"); + UNREACHABLE(); } -- cgit v1.2.3 From 1bfc0dc2dbb0caf02dce673e08a66762afee1457 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 22:42:28 -0400 Subject: gl_rasterizer: Use passthrough shader for SetupVertexShader. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 72481509b..630b46737 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -196,7 +196,8 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { void RasterizerOpenGL::SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset) { MICROPROFILE_SCOPE(OpenGL_VS); - UNIMPLEMENTED(); + LOG_CRITICAL(Render_OpenGL, "Emulated shaders are not supported! Using a passthrough shader."); + glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_shader->shader.handle); } void RasterizerOpenGL::SetupFragmentShader(FSUniformData* ub_ptr, GLintptr buffer_offset) { -- cgit v1.2.3 From d89bfec5f55854daa1ff717e4a5f721bfa08a541 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Mar 2018 22:50:21 -0400 Subject: rasterizer: Rename DrawTriangles to DrawArrays. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 630b46737..dfc4beb9a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -212,12 +212,12 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { } accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; - DrawTriangles(); + DrawArrays(); return true; } -void RasterizerOpenGL::DrawTriangles() { +void RasterizerOpenGL::DrawArrays() { if (accelerate_draw == AccelDraw::Disabled) return; -- cgit v1.2.3 From a6cab532f89ada46988e391708eb06b3be5ade19 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 25 Mar 2018 00:09:53 -0400 Subject: gl_rasterizer: Normalize vertex array data as appropriate. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index dfc4beb9a..7950bac9e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -178,7 +178,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { for (unsigned index = 0; index < 16; ++index) { auto& attrib = regs.vertex_attrib_format[index]; glVertexAttribPointer(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - GL_FALSE, vertex_array.stride, + attrib.IsNormalized() ? GL_TRUE : GL_FALSE, vertex_array.stride, reinterpret_cast(buffer_offset + attrib.offset)); glEnableVertexAttribArray(index); hw_vao_enabled_attributes[index] = true; -- cgit v1.2.3 From ac19e3d06193d5035694bb9918c705d5eb6762db Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 25 Mar 2018 01:00:41 -0400 Subject: gl_rasterizer: Use ReadBlock instead of GetPointer for SetupVertexArray. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7950bac9e..c4abbb2cd 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -188,7 +188,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { const u32 data_size{vertex_array.stride * regs.vertex_buffer.count}; const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(vertex_array.StartAddress())}; res_cache.FlushRegion(data_addr, data_size, nullptr); - std::memcpy(array_ptr, Memory::GetPointer(data_addr), data_size); + Memory::ReadBlock(data_addr, array_ptr, data_size); array_ptr += data_size; buffer_offset += data_size; -- cgit v1.2.3 From 67bc2f5ecd325d8d23d6d3d1ac979c8c78fdd743 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 26 Mar 2018 20:09:01 -0400 Subject: gl_rasterizer: Move PrimitiveTopology check to MaxwellToGL. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c4abbb2cd..487d37a26 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -326,17 +326,7 @@ void RasterizerOpenGL::DrawArrays() { state.Apply(); // Draw the vertex batch - GLenum primitive_mode; - switch (regs.draw.topology) { - case Maxwell::PrimitiveTopology::TriangleStrip: - primitive_mode = GL_TRIANGLE_STRIP; - break; - default: - UNREACHABLE(); - } - const bool is_indexed = accelerate_draw == AccelDraw::Indexed; - AnalyzeVertexArray(is_indexed); state.draw.vertex_buffer = stream_buffer->GetHandle(); state.Apply(); @@ -384,7 +374,8 @@ void RasterizerOpenGL::DrawArrays() { if (is_indexed) { UNREACHABLE(); } else { - glDrawArrays(primitive_mode, 0, regs.vertex_buffer.count); + glDrawArrays(MaxwellToGL::PrimitiveTopology(regs.draw.topology), 0, + regs.vertex_buffer.count); } // Disable scissor test -- cgit v1.2.3 From d30110348b10e1cf9765a5c7cec294a4e076a3af Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 26 Mar 2018 20:45:10 -0400 Subject: gl_rasterizer: Add a SyncViewport method. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 35 ++++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 487d37a26..d83c38cf8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -228,13 +228,7 @@ void RasterizerOpenGL::DrawArrays() { const bool has_stencil = false; const bool using_color_fb = true; const bool using_depth_fb = false; - - MathUtil::Rectangle viewport_rect_unscaled{ - static_cast(regs.viewport[0].x), // left - static_cast(regs.viewport[0].y + regs.viewport[0].height), // top - static_cast(regs.viewport[0].x + regs.viewport[0].width), // right - static_cast(regs.viewport[0].y) // bottom - }; + const MathUtil::Rectangle viewport_rect{regs.viewport[0].GetRect()}; const bool write_color_fb = state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || @@ -248,7 +242,7 @@ void RasterizerOpenGL::DrawArrays() { Surface depth_surface; MathUtil::Rectangle surfaces_rect; std::tie(color_surface, depth_surface, surfaces_rect) = - res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect_unscaled); + res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect); const u16 res_scale = color_surface != nullptr ? color_surface->res_scale @@ -256,16 +250,16 @@ void RasterizerOpenGL::DrawArrays() { MathUtil::Rectangle draw_rect{ static_cast(MathUtil::Clamp(static_cast(surfaces_rect.left) + - viewport_rect_unscaled.left * res_scale, + viewport_rect.left * res_scale, surfaces_rect.left, surfaces_rect.right)), // Left static_cast(MathUtil::Clamp(static_cast(surfaces_rect.bottom) + - viewport_rect_unscaled.top * res_scale, + viewport_rect.top * res_scale, surfaces_rect.bottom, surfaces_rect.top)), // Top static_cast(MathUtil::Clamp(static_cast(surfaces_rect.left) + - viewport_rect_unscaled.right * res_scale, + viewport_rect.right * res_scale, surfaces_rect.left, surfaces_rect.right)), // Right static_cast(MathUtil::Clamp(static_cast(surfaces_rect.bottom) + - viewport_rect_unscaled.bottom * res_scale, + viewport_rect.bottom * res_scale, surfaces_rect.bottom, surfaces_rect.top))}; // Bottom // Bind the framebuffer surfaces @@ -293,12 +287,7 @@ void RasterizerOpenGL::DrawArrays() { } // Sync the viewport - state.viewport.x = - static_cast(surfaces_rect.left) + viewport_rect_unscaled.left * res_scale; - state.viewport.y = - static_cast(surfaces_rect.bottom) + viewport_rect_unscaled.bottom * res_scale; - state.viewport.width = static_cast(viewport_rect_unscaled.GetWidth() * res_scale); - state.viewport.height = static_cast(viewport_rect_unscaled.GetHeight() * res_scale); + SyncViewport(surfaces_rect, res_scale); // TODO(bunnei): Sync framebuffer_scale uniform here // TODO(bunnei): Sync scissorbox uniform(s) here @@ -541,6 +530,16 @@ void main() { } } +void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle& surfaces_rect, u16 res_scale) { + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + const MathUtil::Rectangle viewport_rect{regs.viewport[0].GetRect()}; + + state.viewport.x = static_cast(surfaces_rect.left) + viewport_rect.left * res_scale; + state.viewport.y = static_cast(surfaces_rect.bottom) + viewport_rect.bottom * res_scale; + state.viewport.width = static_cast(viewport_rect.GetWidth() * res_scale); + state.viewport.height = static_cast(viewport_rect.GetHeight() * res_scale); +} + void RasterizerOpenGL::SyncClipEnabled() { UNREACHABLE(); } -- cgit v1.2.3 From c33abac275a356a9b6c7a6c8d4214e1f8cb1a80c Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 26 Mar 2018 20:58:19 -0400 Subject: gl_rasterizer: Move code to bind framebuffer surfaces before draw to its own function. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 49 +++++++++++++----------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d83c38cf8..911890f16 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -263,28 +263,7 @@ void RasterizerOpenGL::DrawArrays() { surfaces_rect.bottom, surfaces_rect.top))}; // Bottom // Bind the framebuffer surfaces - state.draw.draw_framebuffer = framebuffer.handle; - state.Apply(); - - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - color_surface != nullptr ? color_surface->texture.handle : 0, 0); - if (depth_surface != nullptr) { - if (has_stencil) { - // attach both depth and stencil - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - depth_surface->texture.handle, 0); - } else { - // attach depth - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - depth_surface->texture.handle, 0); - // clear stencil attachment - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - } - } else { - // clear both depth and stencil attachment - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, - 0); - } + BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); // Sync the viewport SyncViewport(surfaces_rect, res_scale); @@ -530,6 +509,32 @@ void main() { } } +void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface, + const Surface& depth_surface, bool has_stencil) { + state.draw.draw_framebuffer = framebuffer.handle; + state.Apply(); + + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + color_surface != nullptr ? color_surface->texture.handle : 0, 0); + if (depth_surface != nullptr) { + if (has_stencil) { + // attach both depth and stencil + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + depth_surface->texture.handle, 0); + } else { + // attach depth + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + depth_surface->texture.handle, 0); + // clear stencil attachment + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + } + } else { + // clear both depth and stencil attachment + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, + 0); + } +} + void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle& surfaces_rect, u16 res_scale) { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; const MathUtil::Rectangle viewport_rect{regs.viewport[0].GetRect()}; -- cgit v1.2.3