载入中...
搜索中...
未找到
ShaderResources.cpp
浏览该文件的文档.
2#include "graphics/Graphics.h"
3
4#include <algorithm>
5#include <bit>
6#include <cmath>
7#include <cstring>
8
9namespace eve::graphics {
10Result<void> Graphics::replaceMeshShaderResources(Shader&, const std::vector<uint32_t>&, const std::vector<uint32_t>&,
11 const ShaderResourceInputs&) {
13 DiagnosticCode::Unsupported, "Resource mesh programs are unavailable on this backend", "backend"));
14}
15
17 const auto invalid = [](const char* message) {
20 };
21 if (!image.width || !image.height || image.width > 32768 || image.height > 32768 || !image.layers ||
22 image.layers > 2048 || !image.depth || image.depth > 2048 || !image.mipLevels ||
23 image.mipLevels > static_cast<uint32_t>(std::bit_width(std::max({image.width, image.height, image.depth}))) ||
24 image.binding > 31)
25 return invalid("Invalid shader image dimensions, mip count or binding");
26 if (image.dimension != ShaderImageDimension::Image3D && image.depth != 1)
27 return invalid("Non-volume images require depth one");
28 switch (image.dimension) {
30 if (image.layers != 1) return invalid("A 2D image must have one layer");
31 break;
34 if (image.layers != 1 || image.width > 2048 || image.height > 2048)
35 return invalid("A volume requires one layer and at most 2048 texels per dimension");
36 break;
38 if (image.layers != 6 || image.width != image.height) return invalid("A cube image needs six square faces");
39 break;
40 default: return invalid("Unknown image dimension");
41 }
42 std::size_t block = 1, stride = 0;
43 switch (image.format) {
44 case ShaderImageFormat::R8: stride = 1; break;
46 case ShaderImageFormat::R16: stride = 2; break;
50 case ShaderImageFormat::BGRA8Srgb: stride = 4; break;
52 case ShaderImageFormat::RGBA16Float: stride = 8; break;
53 case ShaderImageFormat::RGBA32Float: stride = 16; break;
56 block = 4;
57 stride = 8;
58 break;
63 block = 4;
64 stride = 16;
65 break;
66 default: return invalid("Unknown image format");
67 }
68 if (image.dimension == ShaderImageDimension::Image3D && block != 1)
69 return invalid("Block-compressed volume images are unsupported");
70 if (!std::isfinite(image.sampler.maxAnisotropy) || image.sampler.maxAnisotropy < 1 ||
71 !std::isfinite(image.sampler.lodBias) || !std::isfinite(image.sampler.minLod) ||
72 !std::isfinite(image.sampler.maxLod) || image.sampler.minLod < 0 || image.sampler.maxLod < image.sampler.minLod)
73 return invalid("Invalid shader image sampler");
74 std::vector<ShaderImageRegion> result;
75 std::size_t offset = 0;
76 for (std::uint32_t layer = 0; layer < image.layers; ++layer) {
77 for (std::uint32_t mip = 0; mip < image.mipLevels; ++mip) {
78 const auto width = std::max(1u, image.width >> mip);
79 const auto height = std::max(1u, image.height >> mip);
80 const auto depth = std::max(1u, image.depth >> mip);
81 const uint64_t size =
82 uint64_t((width + block - 1) / block) * ((height + block - 1) / block) * stride * depth;
83 if (size > 1024ull * 1024 * 1024 || offset > 1024ull * 1024 * 1024 - size)
84 return invalid("Shader image exceeds 1 GiB upload limit");
85 result.push_back({layer, mip, width, height, offset, static_cast<size_t>(size), depth});
86 offset += static_cast<size_t>(size);
87 }
88 }
89 if (image.bytes.size() != offset) return invalid("Shader image payload size does not match its layout");
90 return Result<std::vector<ShaderImageRegion>>::success(std::move(result));
91}
93 auto bad = [](const char* message) {
96 };
97 if (bytes.size() % 64 || bytes.size() > 64ull * 1024 * 1024)
98 return bad("Instance matrices require complete 64-byte records, at most 64 MiB");
99 for (std::size_t offset = 0; offset < bytes.size(); offset += 64) {
100 float m[16];
101 std::memcpy(m, bytes.data() + offset, sizeof(m));
102 for (float value : m)
103 if (!std::isfinite(value)) return bad("Nonfinite instance transform");
104 if (m[3] != 0 || m[7] != 0 || m[11] != 0 || m[15] != 1) return bad("Instance transform must be affine");
105 const double determinant = double(m[0]) * (double(m[5]) * m[10] - double(m[9]) * m[6]) -
106 double(m[4]) * (double(m[1]) * m[10] - double(m[9]) * m[2]) +
107 double(m[8]) * (double(m[1]) * m[6] - double(m[5]) * m[2]);
108 if (!std::isfinite(determinant) || determinant == 0) return bad("Instance transform must be invertible");
109 }
110 return Result<std::uint32_t>::success(static_cast<std::uint32_t>(bytes.size() / 64));
111}
112} // namespace eve::graphics
double value
std::string message
vk::UniqueImage image
std::uint32_t height
std::uint32_t width
size_t offset
std::uint64_t bytes
TileLayer * layer
float size
Definition TreeMesh.cpp:156
std::uint32_t depth
float m[16]
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
virtual Result< void > replaceMeshShaderResources(Shader &shader, const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv, const ShaderResourceInputs &resources)
Replace a mesh program and its immutable set-1 resources atomically.
Custom GPU program.
Definition Shader.h:39
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
Result< std::uint32_t > shaderInstanceMatrixCount(std::span< const std::byte > bytes)
Validate packed instance records without GPU access; returns the record count.
Result< std::vector< ShaderImageRegion > > shaderImageRegions(const ShaderImageInput &image)
Validate layout, dimensions, sampler compatibility and exact payload size.
Synchronous borrowed input for one immutable shader image. @ownership The caller owns bytes; upload c...
Inputs for descriptor set 1 of a resource mesh program.