mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-24 23:11:14 +01:00
VideoBackends:Metal: Use base vertex
This commit is contained in:
parent
5742ccf8de
commit
c0fd128171
@ -46,6 +46,7 @@ public:
|
|||||||
|
|
||||||
enum class AlignMask : size_t
|
enum class AlignMask : size_t
|
||||||
{
|
{
|
||||||
|
None = 0,
|
||||||
Other = 15,
|
Other = 15,
|
||||||
Uniform = 255,
|
Uniform = 255,
|
||||||
};
|
};
|
||||||
@ -83,7 +84,7 @@ public:
|
|||||||
void InvalidateUniforms(bool vertex, bool fragment);
|
void InvalidateUniforms(bool vertex, bool fragment);
|
||||||
void SetUtilityUniform(const void* buffer, size_t size);
|
void SetUtilityUniform(const void* buffer, size_t size);
|
||||||
void SetTexelBuffer(id<MTLBuffer> buffer, u32 offset0, u32 offset1);
|
void SetTexelBuffer(id<MTLBuffer> buffer, u32 offset0, u32 offset1);
|
||||||
void SetVerticesAndIndices(Map vertices, Map indices);
|
void SetVerticesAndIndices(id<MTLBuffer> vertices, id<MTLBuffer> indices);
|
||||||
void SetBBoxBuffer(id<MTLBuffer> bbox, id<MTLFence> upload, id<MTLFence> download);
|
void SetBBoxBuffer(id<MTLBuffer> bbox, id<MTLFence> upload, id<MTLFence> download);
|
||||||
void SetVertexBufferNow(u32 idx, id<MTLBuffer> buffer, u32 offset);
|
void SetVertexBufferNow(u32 idx, id<MTLBuffer> buffer, u32 offset);
|
||||||
void SetFragmentBufferNow(u32 idx, id<MTLBuffer> buffer, u32 offset);
|
void SetFragmentBufferNow(u32 idx, id<MTLBuffer> buffer, u32 offset);
|
||||||
@ -107,7 +108,7 @@ public:
|
|||||||
Preallocate(buffer_idx, amt);
|
Preallocate(buffer_idx, amt);
|
||||||
return CommitPreallocation(buffer_idx, amt, align);
|
return CommitPreallocation(buffer_idx, amt, align);
|
||||||
}
|
}
|
||||||
void* Preallocate(UploadBuffer buffer_idx, size_t amt);
|
std::pair<void*, size_t> Preallocate(UploadBuffer buffer_idx, size_t amt);
|
||||||
/// Must follow a call to Preallocate where amt is >= to the one provided here
|
/// Must follow a call to Preallocate where amt is >= to the one provided here
|
||||||
Map CommitPreallocation(UploadBuffer buffer_idx, size_t amt, AlignMask align)
|
Map CommitPreallocation(UploadBuffer buffer_idx, size_t amt, AlignMask align)
|
||||||
{
|
{
|
||||||
@ -247,8 +248,6 @@ private:
|
|||||||
id<MTLBuffer> vertices = nullptr;
|
id<MTLBuffer> vertices = nullptr;
|
||||||
id<MTLBuffer> indices = nullptr;
|
id<MTLBuffer> indices = nullptr;
|
||||||
id<MTLBuffer> texels = nullptr;
|
id<MTLBuffer> texels = nullptr;
|
||||||
u32 vertices_offset;
|
|
||||||
u32 indices_offset;
|
|
||||||
u32 texel_buffer_offset0;
|
u32 texel_buffer_offset0;
|
||||||
u32 texel_buffer_offset1;
|
u32 texel_buffer_offset1;
|
||||||
} m_state;
|
} m_state;
|
||||||
|
@ -154,7 +154,7 @@ Metal::StateTracker::Map Metal::StateTracker::AllocateForTextureUpload(size_t am
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Metal::StateTracker::Preallocate(UploadBuffer buffer_idx, size_t amt)
|
std::pair<void*, size_t> Metal::StateTracker::Preallocate(UploadBuffer buffer_idx, size_t amt)
|
||||||
{
|
{
|
||||||
BufferPair& buffer = m_upload_buffers[static_cast<int>(buffer_idx)];
|
BufferPair& buffer = m_upload_buffers[static_cast<int>(buffer_idx)];
|
||||||
u64 last_draw = m_last_finished_draw.load(std::memory_order_acquire);
|
u64 last_draw = m_last_finished_draw.load(std::memory_order_acquire);
|
||||||
@ -195,7 +195,8 @@ void* Metal::StateTracker::Preallocate(UploadBuffer buffer_idx, size_t amt)
|
|||||||
ASSERT_MSG(VIDEO, buffer.gpubuffer, "Failed to allocate MTLBuffer (out of memory?)");
|
ASSERT_MSG(VIDEO, buffer.gpubuffer, "Failed to allocate MTLBuffer (out of memory?)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reinterpret_cast<char*>(buffer.buffer) + buffer.usage.Pos();
|
size_t pos = buffer.usage.Pos();
|
||||||
|
return std::make_pair(reinterpret_cast<char*>(buffer.buffer) + pos, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
Metal::StateTracker::Map Metal::StateTracker::CommitPreallocation(UploadBuffer buffer_idx,
|
Metal::StateTracker::Map Metal::StateTracker::CommitPreallocation(UploadBuffer buffer_idx,
|
||||||
@ -558,13 +559,14 @@ void Metal::StateTracker::SetTexelBuffer(id<MTLBuffer> buffer, u32 offset0, u32
|
|||||||
m_flags.has_texel_buffer = false;
|
m_flags.has_texel_buffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::StateTracker::SetVerticesAndIndices(Map vertices, Map indices)
|
void Metal::StateTracker::SetVerticesAndIndices(id<MTLBuffer> vertices, id<MTLBuffer> indices)
|
||||||
{
|
{
|
||||||
m_state.vertices = vertices.gpu_buffer;
|
if (m_state.vertices != vertices)
|
||||||
m_state.indices = indices.gpu_buffer;
|
{
|
||||||
m_state.vertices_offset = vertices.gpu_offset;
|
m_flags.has_vertices = false;
|
||||||
m_state.indices_offset = indices.gpu_offset;
|
m_state.vertices = vertices;
|
||||||
m_flags.has_vertices = false;
|
}
|
||||||
|
m_state.indices = indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::StateTracker::SetBBoxBuffer(id<MTLBuffer> bbox, id<MTLFence> upload,
|
void Metal::StateTracker::SetBBoxBuffer(id<MTLBuffer> bbox, id<MTLFence> upload,
|
||||||
@ -691,7 +693,7 @@ void Metal::StateTracker::PrepareRender()
|
|||||||
{
|
{
|
||||||
m_flags.has_vertices = true;
|
m_flags.has_vertices = true;
|
||||||
if (m_state.vertices)
|
if (m_state.vertices)
|
||||||
SetVertexBufferNow(0, m_state.vertices, m_state.vertices_offset);
|
SetVertexBufferNow(0, m_state.vertices, 0);
|
||||||
}
|
}
|
||||||
if (u8 dirty = m_dirty_textures & pipe->GetTextures())
|
if (u8 dirty = m_dirty_textures & pipe->GetTextures())
|
||||||
{
|
{
|
||||||
@ -801,27 +803,14 @@ void Metal::StateTracker::Draw(u32 base_vertex, u32 num_vertices)
|
|||||||
void Metal::StateTracker::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
|
void Metal::StateTracker::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex)
|
||||||
{
|
{
|
||||||
PrepareRender();
|
PrepareRender();
|
||||||
if (!base_vertex)
|
[m_current_render_encoder drawIndexedPrimitives:m_state.render_pipeline->Prim()
|
||||||
{
|
indexCount:num_indices
|
||||||
[m_current_render_encoder
|
indexType:MTLIndexTypeUInt16
|
||||||
drawIndexedPrimitives:m_state.render_pipeline->Prim()
|
indexBuffer:m_state.indices
|
||||||
indexCount:num_indices
|
indexBufferOffset:base_index * sizeof(u16)
|
||||||
indexType:MTLIndexTypeUInt16
|
instanceCount:1
|
||||||
indexBuffer:m_state.indices
|
baseVertex:base_vertex
|
||||||
indexBufferOffset:m_state.indices_offset + base_index * sizeof(u16)];
|
baseInstance:0];
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[m_current_render_encoder
|
|
||||||
drawIndexedPrimitives:m_state.render_pipeline->Prim()
|
|
||||||
indexCount:num_indices
|
|
||||||
indexType:MTLIndexTypeUInt16
|
|
||||||
indexBuffer:m_state.indices
|
|
||||||
indexBufferOffset:m_state.indices_offset + base_index * sizeof(u16)
|
|
||||||
instanceCount:1
|
|
||||||
baseVertex:base_vertex
|
|
||||||
baseInstance:0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::StateTracker::DispatchComputeShader(u32 groupsize_x, u32 groupsize_y, u32 groupsize_z,
|
void Metal::StateTracker::DispatchComputeShader(u32 groupsize_x, u32 groupsize_y, u32 groupsize_z,
|
||||||
|
@ -26,5 +26,9 @@ protected:
|
|||||||
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
|
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
|
||||||
u32* out_base_index) override;
|
u32* out_base_index) override;
|
||||||
void UploadUniforms() override;
|
void UploadUniforms() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
u32 m_vertex_offset;
|
||||||
|
u32 m_base_vertex;
|
||||||
};
|
};
|
||||||
} // namespace Metal
|
} // namespace Metal
|
||||||
|
@ -54,31 +54,36 @@ bool Metal::VertexManager::UploadTexelBuffer(const void* data, u32 data_size,
|
|||||||
void Metal::VertexManager::ResetBuffer(u32 vertex_stride)
|
void Metal::VertexManager::ResetBuffer(u32 vertex_stride)
|
||||||
{
|
{
|
||||||
const u32 max_vertex_size = 65535 * vertex_stride;
|
const u32 max_vertex_size = 65535 * vertex_stride;
|
||||||
void* vertex = g_state_tracker->Preallocate(StateTracker::UploadBuffer::Vertex, max_vertex_size);
|
const u32 vertex_alloc = max_vertex_size + vertex_stride - 1; // for alignment
|
||||||
void* index =
|
auto vertex = g_state_tracker->Preallocate(StateTracker::UploadBuffer::Vertex, vertex_alloc);
|
||||||
|
auto index =
|
||||||
g_state_tracker->Preallocate(StateTracker::UploadBuffer::Index, MAXIBUFFERSIZE * sizeof(u16));
|
g_state_tracker->Preallocate(StateTracker::UploadBuffer::Index, MAXIBUFFERSIZE * sizeof(u16));
|
||||||
|
|
||||||
m_cur_buffer_pointer = m_base_buffer_pointer = static_cast<u8*>(vertex);
|
// Align the base vertex
|
||||||
|
m_base_vertex = (vertex.second + vertex_stride - 1) / vertex_stride;
|
||||||
|
m_vertex_offset = m_base_vertex * vertex_stride - vertex.second;
|
||||||
|
m_cur_buffer_pointer = m_base_buffer_pointer = static_cast<u8*>(vertex.first) + m_vertex_offset;
|
||||||
m_end_buffer_pointer = m_base_buffer_pointer + max_vertex_size;
|
m_end_buffer_pointer = m_base_buffer_pointer + max_vertex_size;
|
||||||
m_index_generator.Start(static_cast<u16*>(index));
|
m_index_generator.Start(static_cast<u16*>(index.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,
|
void Metal::VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,
|
||||||
u32* out_base_vertex, u32* out_base_index)
|
u32* out_base_vertex, u32* out_base_index)
|
||||||
{
|
{
|
||||||
const u32 vsize = num_vertices * vertex_stride;
|
const u32 vsize = num_vertices * vertex_stride + m_vertex_offset;
|
||||||
const u32 isize = num_indices * sizeof(u16);
|
const u32 isize = num_indices * sizeof(u16);
|
||||||
StateTracker::Map vmap = g_state_tracker->CommitPreallocation(
|
StateTracker::Map vmap = g_state_tracker->CommitPreallocation(
|
||||||
StateTracker::UploadBuffer::Vertex, vsize, StateTracker::AlignMask::Other);
|
StateTracker::UploadBuffer::Vertex, vsize, StateTracker::AlignMask::None);
|
||||||
StateTracker::Map imap = g_state_tracker->CommitPreallocation(
|
StateTracker::Map imap = g_state_tracker->CommitPreallocation(
|
||||||
StateTracker::UploadBuffer::Index, isize, StateTracker::AlignMask::Other);
|
StateTracker::UploadBuffer::Index, isize, StateTracker::AlignMask::None);
|
||||||
|
|
||||||
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, vsize);
|
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, vsize);
|
||||||
ADDSTAT(g_stats.this_frame.bytes_index_streamed, isize);
|
ADDSTAT(g_stats.this_frame.bytes_index_streamed, isize);
|
||||||
|
|
||||||
g_state_tracker->SetVerticesAndIndices(vmap, imap);
|
DEBUG_ASSERT(vmap.gpu_offset + m_vertex_offset == m_base_vertex * vertex_stride);
|
||||||
*out_base_vertex = 0;
|
g_state_tracker->SetVerticesAndIndices(vmap.gpu_buffer, imap.gpu_buffer);
|
||||||
*out_base_index = 0;
|
*out_base_vertex = m_base_vertex;
|
||||||
|
*out_base_index = imap.gpu_offset / sizeof(u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::VertexManager::UploadUniforms()
|
void Metal::VertexManager::UploadUniforms()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user