diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 3 | 
3 files changed, 39 insertions, 9 deletions
| diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7cb378a71..362457ffe 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -61,7 +61,8 @@ constexpr std::size_t NUM_CONST_BUFFERS_BYTES_PER_STAGE =  constexpr std::size_t TOTAL_CONST_BUFFER_BYTES =      NUM_CONST_BUFFERS_BYTES_PER_STAGE * Maxwell::MaxShaderStage; -constexpr std::size_t NumSupportedVertexAttributes = 16; +constexpr std::size_t NUM_SUPPORTED_VERTEX_ATTRIBUTES = 16; +constexpr std::size_t NUM_SUPPORTED_VERTEX_BINDINGS = 16;  template <typename Engine, typename Entry>  Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry, @@ -193,7 +194,7 @@ void RasterizerOpenGL::SetupVertexFormat() {      // avoid OpenGL errors.      // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't      // assume every shader uses them all. -    for (std::size_t index = 0; index < NumSupportedVertexAttributes; ++index) { +    for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {          if (!flags[Dirty::VertexFormat0 + index]) {              continue;          } @@ -231,9 +232,11 @@ void RasterizerOpenGL::SetupVertexBuffer() {      MICROPROFILE_SCOPE(OpenGL_VB); +    const bool use_unified_memory = device.HasVertexBufferUnifiedMemory(); +      // Upload all guest vertex arrays sequentially to our buffer      const auto& regs = gpu.regs; -    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { +    for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_BINDINGS; ++index) {          if (!flags[Dirty::VertexBuffer0 + index]) {              continue;          } @@ -246,16 +249,25 @@ void RasterizerOpenGL::SetupVertexBuffer() {          const GPUVAddr start = vertex_array.StartAddress();          const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); -          ASSERT(end >= start); + +        const GLuint gl_index = static_cast<GLuint>(index);          const u64 size = end - start;          if (size == 0) { -            glBindVertexBuffer(static_cast<GLuint>(index), 0, 0, vertex_array.stride); +            glBindVertexBuffer(gl_index, 0, 0, vertex_array.stride); +            if (use_unified_memory) { +                glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, gl_index, 0, 0); +            }              continue;          }          const auto info = buffer_cache.UploadMemory(start, size); -        glBindVertexBuffer(static_cast<GLuint>(index), info.handle, info.offset, -                           vertex_array.stride); +        if (use_unified_memory) { +            glBindVertexBuffer(gl_index, 0, 0, vertex_array.stride); +            glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, gl_index, +                                   info.address + info.offset, size); +        } else { +            glBindVertexBuffer(gl_index, info.handle, info.offset, vertex_array.stride); +        }      }  } @@ -268,7 +280,7 @@ void RasterizerOpenGL::SetupVertexInstances() {      flags[Dirty::VertexInstances] = false;      const auto& regs = gpu.regs; -    for (std::size_t index = 0; index < NumSupportedVertexAttributes; ++index) { +    for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {          if (!flags[Dirty::VertexInstance0 + index]) {              continue;          } diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 6214fcbc3..c40adb6e7 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -488,6 +488,15 @@ void RendererOpenGL::InitOpenGLObjects() {      // Clear screen to black      LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture); + +    // Enable unified vertex attributes and query vertex buffer address when the driver supports it +    if (device.HasVertexBufferUnifiedMemory()) { +        glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); + +        glMakeNamedBufferResidentNV(vertex_buffer.handle, GL_READ_ONLY); +        glGetNamedBufferParameterui64vNV(vertex_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, +                                         &vertex_buffer_address); +    }  }  void RendererOpenGL::AddTelemetryFields() { @@ -656,7 +665,13 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {                           offsetof(ScreenRectVertex, tex_coord));      glVertexAttribBinding(PositionLocation, 0);      glVertexAttribBinding(TexCoordLocation, 0); -    glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex)); +    if (device.HasVertexBufferUnifiedMemory()) { +        glBindVertexBuffer(0, 0, 0, sizeof(ScreenRectVertex)); +        glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, vertex_buffer_address, +                               sizeof(vertices)); +    } else { +        glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex)); +    }      glBindTextureUnit(0, screen_info.display_texture);      glBindSampler(0, 0); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 61bf507f4..8b18d32e6 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -107,6 +107,9 @@ private:      OGLPipeline pipeline;      OGLFramebuffer screenshot_framebuffer; +    // GPU address of the vertex buffer +    GLuint64EXT vertex_buffer_address = 0; +      /// Display information for Switch screen      ScreenInfo screen_info; | 
