载入中...
搜索中...
未找到
GraphicsShaderReload.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <exception>
5#include <utility>
6
7#include "common/Diagnostic.h"
8#include "graphics/Shader.h"
9
10namespace eve::graphics::webgpu {
11namespace {
12
13} // namespace
14
15Result<void> Graphics::replaceShaderFromSpv(Shader &, const std::vector<uint32_t> &,
16 const std::vector<uint32_t> &) {
17 return Result<void>::failure(Diagnostic::error(DiagnosticCode::Unsupported, "SPIR-V shader replacement is unavailable on the WebGPU backend", "source", {},
18 "graphics.webgpu.shader_reload"));
19}
20
22 const std::string &fragWgsl) {
23 auto shaderIt = std::find_if(ownedShaders.begin(), ownedShaders.end(),
24 [&](const std::unique_ptr<Shader> &owned) {
25 return owned.get() == &shader;
26 });
27 if (shaderIt == ownedShaders.end() || !shader.gpuHandle)
28 return Result<void>::failure(Diagnostic::error(DiagnosticCode::StaleHandle, "shader is not a live resource owned by this Graphics instance", "shader", {},
29 "graphics.webgpu.shader_reload"));
30 if (fragWgsl.empty())
31 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "fragment WGSL must not be empty", "fragWgsl", {},
32 "graphics.webgpu.shader_reload"));
33
34 auto *current = static_cast<GpuShader *>(shader.gpuHandle);
35 auto gpuIt = std::find_if(ownedGpuShaders.begin(), ownedGpuShaders.end(),
36 [&](const std::unique_ptr<GpuShader> &owned) {
37 return owned.get() == current;
38 });
39 if (gpuIt == ownedGpuShaders.end())
40 return Result<void>::failure(Diagnostic::error(DiagnosticCode::StaleHandle, "shader GPU resource is no longer owned by this Graphics instance", "shader.gpuHandle", {},
41 "graphics.webgpu.shader_reload"));
42
43 GpuShader candidate;
44 candidate.isMesh3D = current->isMesh3D;
45 candidate.isHair3D = current->isHair3D;
46 candidate.pipelineLayout = current->pipelineLayout;
47 candidate.setLayout = current->setLayout;
48 candidate.wgslVert = vertWgsl.empty() ? current->wgslVert : vertWgsl;
49 candidate.wgslFrag = fragWgsl;
50 if (candidate.wgslVert.empty())
51 return Result<void>::failure(Diagnostic::error(DiagnosticCode::PreconditionViolation, "shader has no reusable default vertex WGSL", "vertWgsl", {},
52 "graphics.webgpu.shader_reload"));
53
54 try {
55 if (!candidate.isMesh3D) {
56 candidate.swapchainPipeline = createPipelineForShader(
57 &candidate, wgpu::TextureFormat(surfaceFormat), false, false, false, false,
58 false, tex2DPipelineLayout);
59 candidate.offscreenPipeline = createPipelineForShader(
60 &candidate, wgpu::TextureFormat::RGBA8Unorm, false, false, false, false,
61 false, tex2DPipelineLayout);
62 } else {
63 candidate.mesh3dPipeline = createPipelineForShader(
64 &candidate, static_cast<wgpu::TextureFormat>(sceneColorFormat), true, true,
65 candidate.isHair3D, false, false, mesh3dPipelineLayout);
66 if (!candidate.isHair3D)
67 candidate.mesh3dXrayPipeline = createPipelineForShader(
68 &candidate, static_cast<wgpu::TextureFormat>(sceneColorFormat), false, true,
69 false, false, false, mesh3dPipelineLayout);
70 }
71 } catch (const std::exception &error) {
72 return Result<void>::failure(Diagnostic::error(DiagnosticCode::Failed, std::string("failed to prepare replacement pipeline: ") + error.what(), "pipeline", {},
73 "graphics.webgpu.shader_reload"));
74 } catch (...) {
75 return Result<void>::failure(Diagnostic::error(DiagnosticCode::Failed, "failed to prepare replacement pipeline", "pipeline", {},
76 "graphics.webgpu.shader_reload"));
77 }
78
79 current->swapchainPipeline = std::move(candidate.swapchainPipeline);
80 current->offscreenPipeline = std::move(candidate.offscreenPipeline);
81 current->mesh3dPipeline = std::move(candidate.mesh3dPipeline);
82 current->mesh3dXrayPipeline = std::move(candidate.mesh3dXrayPipeline);
83 current->wgslVert = std::move(candidate.wgslVert);
84 current->wgslFrag = std::move(candidate.wgslFrag);
85 return Result<void>::success();
86}
87
89 const std::string &) {
90 return Result<void>::failure(Diagnostic::error(DiagnosticCode::Unsupported, "runtime GLSL replacement is unavailable on the WebGPU backend", "source", {},
91 "graphics.webgpu.shader_reload"));
92}
93
94} // namespace eve::graphics::webgpu
ActiveSource owned
Stable, structured diagnostics shared by engine modules.
std::string error
Definition Package.cpp:60
Shader * shader
double current
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Custom GPU program.
Definition Shader.h:39
Result< void > replaceShaderFromGlsl(Shader &shader, const std::string &vertGlsl, const std::string &fragGlsl) override
Replace shader from glsl.
Result< void > replaceShaderFromSpv(Shader &shader, const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv) override
Replace shader from spv.
Result< void > replaceShaderFromWgsl(Shader &shader, const std::string &vertWgsl, const std::string &fragWgsl) override
Replace shader from wgsl.
A compiled shader: one WebGPU pipeline + layout. Also holds the WGSL sources so custom shaders can be...
Definition Graphics.h:169
wgpu::RenderPipeline mesh3dPipeline
Definition Graphics.h:176
wgpu::RenderPipeline swapchainPipeline
Definition Graphics.h:170
wgpu::BindGroupLayout setLayout
Definition Graphics.h:181
wgpu::PipelineLayout pipelineLayout
Definition Graphics.h:180
wgpu::RenderPipeline mesh3dXrayPipeline
Definition Graphics.h:177
wgpu::RenderPipeline offscreenPipeline
Definition Graphics.h:171