GroveEngine/modules/BgfxRenderer/RHI/RHICommandBuffer.h
StillHammer 1443c1209e feat(BgfxRenderer): Complete Phase 2-3 with shaders and triangle rendering
Phase 2 - RHI Layer:
- Fix Command struct default constructor for union with non-trivial types
- Add missing mutex includes in ResourceCache.cpp
- Fix const_cast for getChildReadOnly in SceneCollector

Phase 3 - Shaders & Visual Test:
- Add ShaderManager for centralized shader loading
- Embed pre-compiled shaders (OpenGL, Vulkan, DX11, Metal)
- Add test_20_bgfx_rhi: 23 unit tests for RHI components
- Add test_21_bgfx_triangle: visual test rendering colored triangle

Test results:
- RHI unit tests: 23/23 passing
- Visual test: ~567 FPS with Vulkan renderer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 16:43:17 +08:00

88 lines
3.4 KiB
C++

#pragma once
#include "RHITypes.h"
#include <vector>
#include <cstring>
namespace grove::rhi {
// ============================================================================
// Command Types - POD for serialization
// ============================================================================
enum class CommandType : uint8_t {
SetState,
SetTexture,
SetUniform,
SetVertexBuffer,
SetIndexBuffer,
SetInstanceBuffer,
SetScissor,
Draw,
DrawIndexed,
DrawInstanced,
Submit
};
struct Command {
CommandType type;
union {
struct { RenderState state; } setState;
struct { uint8_t slot; TextureHandle texture; UniformHandle sampler; } setTexture;
struct { UniformHandle uniform; float data[16]; uint8_t numVec4s; } setUniform;
struct { BufferHandle buffer; uint32_t offset; } setVertexBuffer;
struct { BufferHandle buffer; uint32_t offset; bool is32Bit; } setIndexBuffer;
struct { BufferHandle buffer; uint32_t start; uint32_t count; } setInstanceBuffer;
struct { uint16_t x, y, w, h; } setScissor;
struct { uint32_t vertexCount; uint32_t startVertex; } draw;
struct { uint32_t indexCount; uint32_t startIndex; } drawIndexed;
struct { uint32_t indexCount; uint32_t instanceCount; } drawInstanced;
struct { ViewId view; ShaderHandle shader; uint32_t depth; } submit;
};
// Default constructor required because union contains non-trivial types
Command() : type(CommandType::SetState) { std::memset(&setState, 0, sizeof(setState)); }
~Command() = default;
Command(const Command&) = default;
Command& operator=(const Command&) = default;
};
// ============================================================================
// Command Buffer - One per thread, write-only during recording
// ============================================================================
class RHICommandBuffer {
public:
RHICommandBuffer() = default;
// Non-copyable, movable
RHICommandBuffer(const RHICommandBuffer&) = delete;
RHICommandBuffer& operator=(const RHICommandBuffer&) = delete;
RHICommandBuffer(RHICommandBuffer&&) = default;
RHICommandBuffer& operator=(RHICommandBuffer&&) = default;
// Command recording
void setState(const RenderState& state);
void setTexture(uint8_t slot, TextureHandle tex, UniformHandle sampler);
void setUniform(UniformHandle uniform, const float* data, uint8_t numVec4s);
void setVertexBuffer(BufferHandle buffer, uint32_t offset = 0);
void setIndexBuffer(BufferHandle buffer, uint32_t offset = 0, bool is32Bit = false);
void setInstanceBuffer(BufferHandle buffer, uint32_t start, uint32_t count);
void setScissor(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void draw(uint32_t vertexCount, uint32_t startVertex = 0);
void drawIndexed(uint32_t indexCount, uint32_t startIndex = 0);
void drawInstanced(uint32_t indexCount, uint32_t instanceCount);
void submit(ViewId view, ShaderHandle shader, uint32_t depth = 0);
// Read-only access for execution
const std::vector<Command>& getCommands() const { return m_commands; }
void clear() { m_commands.clear(); }
size_t size() const { return m_commands.size(); }
private:
std::vector<Command> m_commands;
};
} // namespace grove::rhi