gl_buffer_cache: Return used buffer from Upload function
This commit is contained in:
		
							parent
							
								
									a6d2f52fc3
								
							
						
					
					
						commit
						b54fb8fc4c
					
				@ -4,6 +4,7 @@
 | 
			
		||||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
#include "common/alignment.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
@ -21,9 +22,10 @@ CachedBufferEntry::CachedBufferEntry(VAddr cpu_addr, std::size_t size, GLintptr
 | 
			
		||||
OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size)
 | 
			
		||||
    : RasterizerCache{rasterizer}, stream_buffer(size, true) {}
 | 
			
		||||
 | 
			
		||||
GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment,
 | 
			
		||||
                                      bool cache) {
 | 
			
		||||
std::pair<GLuint, GLintptr> OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size,
 | 
			
		||||
                                                         std::size_t alignment, bool cache) {
 | 
			
		||||
    std::lock_guard lock{mutex};
 | 
			
		||||
 | 
			
		||||
    auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
 | 
			
		||||
 | 
			
		||||
    // Cache management is a big overhead, so only cache entries with a given size.
 | 
			
		||||
@ -35,7 +37,7 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::
 | 
			
		||||
        auto entry = TryGet(host_ptr);
 | 
			
		||||
        if (entry) {
 | 
			
		||||
            if (entry->GetSize() >= size && entry->GetAlignment() == alignment) {
 | 
			
		||||
                return entry->GetOffset();
 | 
			
		||||
                return {stream_buffer.GetHandle(), entry->GetOffset()};
 | 
			
		||||
            }
 | 
			
		||||
            Unregister(entry);
 | 
			
		||||
        }
 | 
			
		||||
@ -45,7 +47,7 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::
 | 
			
		||||
    const GLintptr uploaded_offset = buffer_offset;
 | 
			
		||||
 | 
			
		||||
    if (!host_ptr) {
 | 
			
		||||
        return uploaded_offset;
 | 
			
		||||
        return {stream_buffer.GetHandle(), uploaded_offset};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::memcpy(buffer_ptr, host_ptr, size);
 | 
			
		||||
@ -58,11 +60,12 @@ GLintptr OGLBufferCache::UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::
 | 
			
		||||
        Register(entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return uploaded_offset;
 | 
			
		||||
    return {stream_buffer.GetHandle(), uploaded_offset};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t size,
 | 
			
		||||
                                          std::size_t alignment) {
 | 
			
		||||
std::pair<GLuint, GLintptr> OGLBufferCache::UploadHostMemory(const void* raw_pointer,
 | 
			
		||||
                                                             std::size_t size,
 | 
			
		||||
                                                             std::size_t alignment) {
 | 
			
		||||
    std::lock_guard lock{mutex};
 | 
			
		||||
    AlignBuffer(alignment);
 | 
			
		||||
    std::memcpy(buffer_ptr, raw_pointer, size);
 | 
			
		||||
@ -70,7 +73,7 @@ GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, std::size_t s
 | 
			
		||||
 | 
			
		||||
    buffer_ptr += size;
 | 
			
		||||
    buffer_offset += size;
 | 
			
		||||
    return uploaded_offset;
 | 
			
		||||
    return {stream_buffer.GetHandle(), uploaded_offset};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool OGLBufferCache::Map(std::size_t max_size) {
 | 
			
		||||
@ -89,10 +92,6 @@ void OGLBufferCache::Unmap() {
 | 
			
		||||
    stream_buffer.Unmap(buffer_offset - buffer_offset_base);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLuint OGLBufferCache::GetHandle() const {
 | 
			
		||||
    return stream_buffer.GetHandle();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OGLBufferCache::AlignBuffer(std::size_t alignment) {
 | 
			
		||||
    // Align the offset, not the mapped pointer
 | 
			
		||||
    const GLintptr offset_aligned =
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <tuple>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "video_core/rasterizer_cache.h"
 | 
			
		||||
@ -53,19 +54,18 @@ class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBuffer
 | 
			
		||||
public:
 | 
			
		||||
    explicit OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size);
 | 
			
		||||
 | 
			
		||||
    /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been
 | 
			
		||||
    /// allocated.
 | 
			
		||||
    GLintptr UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4,
 | 
			
		||||
                          bool cache = true);
 | 
			
		||||
    /// Uploads data from a guest GPU address. Returns the OpenGL buffer where it's located and its
 | 
			
		||||
    /// offset.
 | 
			
		||||
    std::pair<GLuint, GLintptr> UploadMemory(GPUVAddr gpu_addr, std::size_t size,
 | 
			
		||||
                                             std::size_t alignment = 4, bool cache = true);
 | 
			
		||||
 | 
			
		||||
    /// Uploads from a host memory. Returns host's buffer offset where it's been allocated.
 | 
			
		||||
    GLintptr UploadHostMemory(const void* raw_pointer, std::size_t size, std::size_t alignment = 4);
 | 
			
		||||
    /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
 | 
			
		||||
    std::pair<GLuint, GLintptr> UploadHostMemory(const void* raw_pointer, std::size_t size,
 | 
			
		||||
                                                 std::size_t alignment = 4);
 | 
			
		||||
 | 
			
		||||
    bool Map(std::size_t max_size);
 | 
			
		||||
    void Unmap();
 | 
			
		||||
 | 
			
		||||
    GLuint GetHandle() const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void AlignBuffer(std::size_t alignment);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -129,8 +129,6 @@ GLuint RasterizerOpenGL::SetupVertexFormat() {
 | 
			
		||||
        state.draw.vertex_array = vao;
 | 
			
		||||
        state.ApplyVertexArrayState();
 | 
			
		||||
 | 
			
		||||
        glVertexArrayElementBuffer(vao, buffer_cache.GetHandle());
 | 
			
		||||
 | 
			
		||||
        // 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 capping this to 16
 | 
			
		||||
@ -197,10 +195,10 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
 | 
			
		||||
 | 
			
		||||
        ASSERT(end > start);
 | 
			
		||||
        const u64 size = end - start + 1;
 | 
			
		||||
        const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size);
 | 
			
		||||
        const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
 | 
			
		||||
 | 
			
		||||
        // Bind the vertex array to the buffer at the current offset.
 | 
			
		||||
        glVertexArrayVertexBuffer(vao, index, buffer_cache.GetHandle(), vertex_buffer_offset,
 | 
			
		||||
        glVertexArrayVertexBuffer(vao, index, vertex_buffer, vertex_buffer_offset,
 | 
			
		||||
                                  vertex_array.stride);
 | 
			
		||||
 | 
			
		||||
        if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
 | 
			
		||||
@ -215,12 +213,16 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
 | 
			
		||||
    gpu.dirty_flags.vertex_array.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLintptr RasterizerOpenGL::SetupIndexBuffer() {
 | 
			
		||||
GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) {
 | 
			
		||||
    if (accelerate_draw != AccelDraw::Indexed) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    MICROPROFILE_SCOPE(OpenGL_Index);
 | 
			
		||||
    const auto& regs = system.GPU().Maxwell3D().regs;
 | 
			
		||||
    return buffer_cache.UploadMemory(regs.index_array.IndexStart(), CalculateIndexBufferSize());
 | 
			
		||||
    const std::size_t size = CalculateIndexBufferSize();
 | 
			
		||||
    const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
 | 
			
		||||
    glVertexArrayElementBuffer(vao, buffer);
 | 
			
		||||
    return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DrawParameters RasterizerOpenGL::SetupDraw(GLintptr index_buffer_offset) {
 | 
			
		||||
@ -235,7 +237,6 @@ DrawParameters RasterizerOpenGL::SetupDraw(GLintptr index_buffer_offset) {
 | 
			
		||||
    params.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
 | 
			
		||||
 | 
			
		||||
    if (is_indexed) {
 | 
			
		||||
        MICROPROFILE_SCOPE(OpenGL_Index);
 | 
			
		||||
        params.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
 | 
			
		||||
        params.count = regs.index_array.count;
 | 
			
		||||
        params.index_buffer_offset = index_buffer_offset;
 | 
			
		||||
@ -278,12 +279,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
 | 
			
		||||
 | 
			
		||||
        GLShader::MaxwellUniformData ubo{};
 | 
			
		||||
        ubo.SetFromRegs(gpu, stage);
 | 
			
		||||
        const GLintptr offset =
 | 
			
		||||
        const auto [buffer, offset] =
 | 
			
		||||
            buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
 | 
			
		||||
 | 
			
		||||
        // Bind the emulation info buffer
 | 
			
		||||
        bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset,
 | 
			
		||||
                                 static_cast<GLsizeiptr>(sizeof(ubo)));
 | 
			
		||||
        bind_ubo_pushbuffer.Push(buffer, offset, static_cast<GLsizeiptr>(sizeof(ubo)));
 | 
			
		||||
 | 
			
		||||
        Shader shader{shader_cache.GetStageProgram(program)};
 | 
			
		||||
 | 
			
		||||
@ -651,11 +651,11 @@ void RasterizerOpenGL::DrawArrays() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Prepare vertex array format.
 | 
			
		||||
    const GLuint vertex_array = SetupVertexFormat();
 | 
			
		||||
    const GLuint vao = SetupVertexFormat();
 | 
			
		||||
 | 
			
		||||
    // Upload vertex and index data.
 | 
			
		||||
    SetupVertexBuffer(vertex_array);
 | 
			
		||||
    const GLintptr index_buffer_offset = SetupIndexBuffer();
 | 
			
		||||
    SetupVertexBuffer(vao);
 | 
			
		||||
    const GLintptr index_buffer_offset = SetupIndexBuffer(vao);
 | 
			
		||||
 | 
			
		||||
    // Setup draw parameters. It will automatically choose what glDraw* method to use.
 | 
			
		||||
    const DrawParameters params = SetupDraw(index_buffer_offset);
 | 
			
		||||
@ -791,8 +791,8 @@ void RasterizerOpenGL::SetupConstBuffer(const Tegra::Engines::ConstBufferInfo& b
 | 
			
		||||
    ASSERT_MSG(size <= MaxConstbufferSize, "Constant buffer is too big");
 | 
			
		||||
 | 
			
		||||
    const std::size_t alignment = device.GetUniformBufferAlignment();
 | 
			
		||||
    const GLintptr offset = buffer_cache.UploadMemory(buffer.address, size, alignment);
 | 
			
		||||
    bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset, size);
 | 
			
		||||
    const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment);
 | 
			
		||||
    bind_ubo_pushbuffer.Push(cbuf, offset, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
 | 
			
		||||
 | 
			
		||||
@ -220,7 +220,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    void SetupVertexBuffer(GLuint vao);
 | 
			
		||||
 | 
			
		||||
    GLintptr SetupIndexBuffer();
 | 
			
		||||
    GLintptr SetupIndexBuffer(GLuint vao);
 | 
			
		||||
 | 
			
		||||
    DrawParameters SetupDraw(GLintptr index_buffer_offset);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user