载入中...
搜索中...
未找到
ShaderSystem.cpp
浏览该文件的文档.
2#include "gpgpu/Gpgpu.h"
3#include "gpgpu/GpuBuffer.h"
4
5#include "common/Exception.h"
6
7#include <algorithm>
8#include <cstring>
9
10namespace eve::gpgpu {
11
14 if (ownsShader_) {
15 delete shader_;
16 shader_ = nullptr;
17 ownsShader_ = false;
18 }
19}
20
21void ShaderSystem::setGpgpu(Gpgpu *gpu) { gpu_ = gpu; }
22
23void ShaderSystem::setShaderSource(const std::string &glsl) {
24 if (!gpu_) throw Exception("ShaderSystem.setShaderSource: Gpgpu is null");
25 ComputeShader *compiled = gpu_->newShader(glsl);
26 if (ownsShader_) delete shader_;
27 shader_ = compiled;
28 ownsShader_ = true;
29}
30
31void ShaderSystem::setShader(ComputeShader *shader, bool takeOwnership) {
32 if (ownsShader_ && shader_ != shader) {
33 delete shader_;
34 ownsShader_ = false;
35 }
36 shader_ = shader;
37 ownsShader_ = takeOwnership && shader != nullptr;
38}
39
40void ShaderSystem::setLocalSize(int localSize) {
41 localSize_ = localSize > 0 ? localSize : kDefaultLocalSize;
42}
43
44GpuBuffer *ShaderSystem::ensureBuffer(int binding, int floatCount) {
45 if (binding < 0 || binding >= kMaxBindings)
46 throw Exception("ShaderSystem.ensureBuffer: binding out of range");
47 if (!gpu_) throw Exception("ShaderSystem.ensureBuffer: Gpgpu is null");
48 if (floatCount <= 0) floatCount = 1;
49
50 const int bytes = floatCount * int(sizeof(float));
51 GpuBuffer *existing = buffers_[binding];
52 if (existing && existing->getSize() >= bytes) return existing;
53
54 GpuBuffer *created = gpu_->newBuffer(bytes, "storage");
55 if (ownsBuffer_[binding]) delete existing;
56 buffers_[binding] = created;
57 ownsBuffer_[binding] = true;
58 return created;
59}
60
62 if (binding < 0 || binding >= kMaxBindings) return nullptr;
63 return buffers_[binding];
64}
65
66void ShaderSystem::upload(int binding, const float *data, int floatCount) {
67 if (!data || floatCount <= 0) return;
68 GpuBuffer *buf = ensureBuffer(binding, floatCount);
69 buf->writeFloat32s(data, floatCount, 0);
70}
71
72void ShaderSystem::download(int binding, float *out, int floatCount) const {
73 if (!out || floatCount <= 0) return;
74 GpuBuffer *buf = getBuffer(binding);
75 if (!buf) throw Exception("ShaderSystem.download: binding has no buffer");
76 buf->readFloat32s(out, floatCount, 0);
77}
78
79void ShaderSystem::upload(int binding, const std::vector<float> &data) {
80 if (data.empty()) return;
81 upload(binding, data.data(), int(data.size()));
82}
83
84std::vector<float> ShaderSystem::download(int binding, int floatCount) const {
85 std::vector<float> out(size_t(std::max(0, floatCount)));
86 if (floatCount > 0) download(binding, out.data(), floatCount);
87 return out;
88}
89
90void ShaderSystem::setFloat(int index, float value) {
91 if (!shader_) return;
92 shader_->setFloat(index, value);
93}
94
95float ShaderSystem::getFloat(int index) const {
96 if (!shader_) return 0.f;
97 return shader_->getFloat(index);
98}
99
100void ShaderSystem::dispatch(int entityCount, float dt) {
101 if (!gpu_ || !shader_ || entityCount <= 0) return;
102
103 for (int i = 0; i < kMaxBindings; ++i) {
104 if (buffers_[i]) shader_->bindBuffer(i, buffers_[i]);
105 }
106
107 shader_->setFloat(0, dt);
108 shader_->setFloat(1, float(entityCount));
109
110 const int ls = localSize_ > 0 ? localSize_ : kDefaultLocalSize;
111 const int groups = (entityCount + ls - 1) / ls;
112 gpu_->dispatch(shader_, groups, 1, 1);
113}
114
116 for (int i = 0; i < kMaxBindings; ++i) {
117 if (ownsBuffer_[i]) {
118 delete buffers_[i];
119 ownsBuffer_[i] = false;
120 }
121 buffers_[i] = nullptr;
122 }
123}
124
125} // namespace eve::gpgpu
std::string value
Shader * shader
Light2D::Data * data
Backend-agnostic compute program. Bind storage buffers then dispatch via Gpgpu::dispatch....
virtual void setFloat(int index, float value)=0
virtual float getFloat(int index) const =0
virtual void bindBuffer(int binding, GpuBuffer *buffer)=0
Bind a storage buffer to set=0 binding. binding in [0, kMaxBindings).
GPGPU module — compute shaders + storage buffers via the active Graphics backend. Uses the graphics q...
Definition Gpgpu.h:20
ComputeShader * newShader(const std::string &source)
Compile compute source for the active backend (Vulkan: GLSL via glslc).
Definition Gpgpu.cpp:48
void dispatch(ComputeShader *shader, int groupsX, int groupsY=1, int groupsZ=1)
Record + submit a compute dispatch and wait for completion (sync). groups*: workgroup counts (not thr...
Definition Gpgpu.cpp:116
GpuBuffer * newBuffer(int byteSize, const std::string &usage="storage")
Allocate a GPU buffer. usage: "storage" (SSBO, device-local) | "staging" (host-visible transfer).
Definition Gpgpu.cpp:92
Backend-agnostic GPU buffer for compute (storage) or CPU staging transfers. Squirrel-owned; derived c...
Definition GpuBuffer.h:16
virtual void writeFloat32s(const float *data, int count, int startIndex=0)=0
Bulk float upload/download (one transfer). startIndex is in floats.
virtual int getSize() const =0
virtual void readFloat32s(float *out, int count, int startIndex=0) const =0
GpuBuffer * getBuffer(int binding) const
void upload(int binding, const float *data, int floatCount)
GpuBuffer * ensureBuffer(int binding, int floatCount)
void dispatch(int entityCount, float dt=0.f)
static constexpr int kMaxBindings
static constexpr int kDefaultLocalSize
void download(int binding, float *out, int floatCount) const
void setFloat(int index, float value)
float getFloat(int index) const
void setShaderSource(const std::string &glsl)
void setLocalSize(int localSize)
void setGpgpu(Gpgpu *gpu)
void setShader(ComputeShader *shader, bool takeOwnership=false)