-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCommandEncoder.hpp
More file actions
156 lines (127 loc) · 4.76 KB
/
CommandEncoder.hpp
File metadata and controls
156 lines (127 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma once
#include "gapi/ForwardDeclarations.hpp"
#include "gapi/CommandList.hpp"
#include "gapi/commands/Draw.hpp"
#include "math/ForwardDeclarations.hpp"
#include "render/Effect.hpp"
#include "render/EffectContext.hpp"
#include "common/NonCopyableMovable.hpp"
namespace RR::Render
{
class DeviceContext;
class RenderPassEncoder;
class CommandEncoder
{
public:
RenderPassEncoder BeginRenderPass(const GAPI::RenderPassDesc& renderPass);
EffectContext CreateEffectContext(Effect* effect) { return EffectContext(effect); }
void Finish()
{
ASSERT_MSG(state == State::Open, "CommandEncoder was not started");
state = State::Closed;
};
private:
enum class State : uint8_t
{
Open,
Closed,
RenderPass,
};
private:
friend class RR::Render::DeviceContext;
friend class PassEncoderBase;
friend class RenderPassEncoder;
explicit CommandEncoder(GAPI::CommandList&& commandlist) : commandList(eastl::move(commandlist)) { }
GAPI::CommandList& GetCommandList() { return commandList; }
void EndRenderPass()
{
ASSERT_MSG(state == State::RenderPass, "RenderPass was not started");
state = State::Open;
}
void Reset()
{
ASSERT_MSG(state == State::Closed, "CommandEncoder was not finished");
state = State::Open;
}
private:
State state = State::Open;
GAPI::CommandList commandList;
};
class PassEncoderBase : public Common::NonCopyable
{
protected:
PassEncoderBase(CommandEncoder& commandContext) : commandContext(&commandContext) { }
~PassEncoderBase()
{
ASSERT_MSG(!commandContext, "PassEncoder was not ended");
}
GAPI::CommandList& GetCommandList()
{
ASSERT(commandContext);
return commandContext->GetCommandList();
}
CommandEncoder& GetCommandEncoder()
{
ASSERT(commandContext);
return *commandContext;
}
void reset()
{
ASSERT(commandContext);
commandContext = nullptr;
}
private:
CommandEncoder* commandContext = nullptr;
};
class RenderPassEncoder final : private PassEncoderBase
{
public:
using Base = PassEncoderBase;
private:
struct GeometryManager
{
GAPI::Commands::GeometryLayout& flush(GAPI::CommandList& commandList);
void SetVertexBuffer(uint32_t slot, const GAPI::Buffer& buffer, uint32_t offset);
void SetIndexBuffer(const GAPI::Buffer& buffer);
void Reset()
{
indexBuffer = nullptr;
vertexBindings.clear();
currentLayout = nullptr;
dirty = false;
}
eastl::fixed_vector<GAPI::Commands::VertexBinding, 8> vertexBindings;
const GAPI::Buffer* indexBuffer = nullptr;
GAPI::Commands::GeometryLayout* currentLayout = nullptr;
bool dirty = false;
};
public:
void SetVertexLayout(const GAPI::VertexLayout* layout) { graphicsParams.SetVertexLayout(layout); }
void SetVertexBuffer(uint32_t slot, const GAPI::Buffer& buffer, uint32_t offset = 0) { geometryManager.SetVertexBuffer(slot, buffer, offset); }
void SetIndexBuffer(const GAPI::Buffer& buffer) { geometryManager.SetIndexBuffer(buffer); }
void Draw(Effect* effect, GAPI::PrimitiveTopology topology, uint32_t startVertex, uint32_t vertexCount, uint32_t instanceCount = 0);
void DrawIndexed(Effect* effect, GAPI::PrimitiveTopology topology, uint32_t startIndex, uint32_t indexCount, uint32_t instanceCount = 0);
void End();
private:
friend class Render::CommandEncoder;
RenderPassEncoder(CommandEncoder& commandContext, const GAPI::RenderPassDesc& renderPass) : PassEncoderBase(commandContext)
{
setRenderPass(renderPass);
}
static RenderPassEncoder Create(CommandEncoder& commandContext, const GAPI::RenderPassDesc& renderPass)
{
return RenderPassEncoder(commandContext, renderPass);
}
void setRenderPass(const GAPI::RenderPassDesc& renderPass);
GAPI::Commands::GeometryLayout& flushLayout() { return geometryManager.flush(GetCommandList()); }
private:
GraphicsParams graphicsParams;
GeometryManager geometryManager;
};
inline RenderPassEncoder CommandEncoder::BeginRenderPass(const GAPI::RenderPassDesc& renderPass)
{
ASSERT(state == State::Open);
state = State::RenderPass;
return RenderPassEncoder::Create(*this, renderPass);
}
}