xbintsc 0.5.32 → 0.5.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -7
- package/README.zh-CN.md +10 -8
- package/dist/scripts/check-version.d.ts +27 -0
- package/dist/scripts/check-version.js +71 -0
- package/dist/scripts/check-version.js.map +1 -0
- package/dist/scripts/package-platform.d.ts +58 -0
- package/dist/scripts/package-platform.js +142 -0
- package/dist/scripts/package-platform.js.map +1 -0
- package/dist/scripts/verify-platform-package.d.ts +34 -0
- package/dist/scripts/verify-platform-package.js +161 -0
- package/dist/scripts/verify-platform-package.js.map +1 -0
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/cli/main.js +3 -1
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/driver/runtime-lib.d.ts +29 -4
- package/dist/src/driver/runtime-lib.js +68 -10
- package/dist/src/driver/runtime-lib.js.map +1 -1
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/gui/index.js +18 -5
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/media/index.js +4 -3
- package/dist/src/extensions/media/index.js.map +1 -1
- package/dist/src/parser/context.d.ts +41 -0
- package/dist/src/parser/context.js +89 -4
- package/dist/src/parser/context.js.map +1 -1
- package/dist/src/parser/literals.js +6 -12
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/driver/platform-package.test.d.ts +1 -0
- package/dist/tests/driver/platform-package.test.js +49 -0
- package/dist/tests/driver/platform-package.test.js.map +1 -0
- package/dist/tests/driver/runtime-lib.test.js +51 -4
- package/dist/tests/driver/runtime-lib.test.js.map +1 -1
- package/dist/tests/e2e/gui-audio.test.d.ts +14 -0
- package/dist/tests/e2e/gui-audio.test.js +287 -0
- package/dist/tests/e2e/gui-audio.test.js.map +1 -0
- package/dist/tests/e2e/gui-browser.test.js +65 -0
- package/dist/tests/e2e/gui-browser.test.js.map +1 -1
- package/dist/tests/e2e/gui-canvas-args.test.d.ts +6 -0
- package/dist/tests/e2e/gui-canvas-args.test.js +217 -0
- package/dist/tests/e2e/gui-canvas-args.test.js.map +1 -0
- package/dist/tests/e2e/gui-canvas.test.js.map +1 -1
- package/dist/tests/e2e/gui-dom.test.js +215 -0
- package/dist/tests/e2e/gui-dom.test.js.map +1 -1
- package/dist/tests/e2e/gui-events.test.js +112 -0
- package/dist/tests/e2e/gui-events.test.js.map +1 -1
- package/dist/tests/e2e/gui-helpers.d.ts +7 -0
- package/dist/tests/e2e/gui-helpers.js +1 -0
- package/dist/tests/e2e/gui-helpers.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.js +78 -0
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-style.test.js +55 -0
- package/dist/tests/e2e/gui-style.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.js +258 -0
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl2-3d.test.d.ts +4 -0
- package/dist/tests/e2e/gui-webgl2-3d.test.js +264 -0
- package/dist/tests/e2e/gui-webgl2-3d.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-blit.test.d.ts +10 -0
- package/dist/tests/e2e/gui-webgl2-blit.test.js +262 -0
- package/dist/tests/e2e/gui-webgl2-blit.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-formats.test.d.ts +6 -0
- package/dist/tests/e2e/gui-webgl2-formats.test.js +395 -0
- package/dist/tests/e2e/gui-webgl2-formats.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-mrt.test.d.ts +4 -0
- package/dist/tests/e2e/gui-webgl2-mrt.test.js +105 -0
- package/dist/tests/e2e/gui-webgl2-mrt.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-ubo.test.d.ts +8 -0
- package/dist/tests/e2e/gui-webgl2-ubo.test.js +112 -0
- package/dist/tests/e2e/gui-webgl2-ubo.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2.test.js +45 -1
- package/dist/tests/e2e/gui-webgl2.test.js.map +1 -1
- package/dist/tests/extensions/gui-index.test.js +1 -0
- package/dist/tests/extensions/gui-index.test.js.map +1 -1
- package/dist/tests/extensions/media.test.js +1 -0
- package/dist/tests/extensions/media.test.js.map +1 -1
- package/dist/tests/parser/expressions.test.js +30 -0
- package/dist/tests/parser/expressions.test.js.map +1 -1
- package/dist/tests/platform-tarball.test.d.ts +1 -0
- package/dist/tests/platform-tarball.test.js +111 -0
- package/dist/tests/platform-tarball.test.js.map +1 -0
- package/dist/tests/version.test.js +6 -0
- package/dist/tests/version.test.js.map +1 -1
- package/doc/ai/contributing.md +11 -0
- package/doc/ai/extensions.md +7 -4
- package/doc/ai/troubleshooting.md +7 -5
- package/doc/ai/zh-CN/contributing.md +9 -0
- package/doc/ai/zh-CN/extensions.md +4 -2
- package/doc/ai/zh-CN/troubleshooting.md +5 -3
- package/doc/gui/api.md +99 -22
- package/doc/gui/build.md +11 -4
- package/doc/gui/canvas.md +49 -18
- package/doc/gui/dom.md +57 -7
- package/doc/gui/media.md +4 -0
- package/doc/gui/webgl.md +105 -46
- package/doc/gui.md +7 -3
- package/doc/npm-package.md +55 -27
- package/doc/requirements.md +6 -2
- package/doc/zh-CN/gui/api.md +84 -14
- package/doc/zh-CN/gui/build.md +7 -2
- package/doc/zh-CN/gui/canvas.md +44 -19
- package/doc/zh-CN/gui/dom.md +48 -4
- package/doc/zh-CN/gui/media.md +3 -0
- package/doc/zh-CN/gui/webgl.md +22 -16
- package/doc/zh-CN/gui.md +3 -2
- package/doc/zh-CN/npm-package.md +44 -23
- package/doc/zh-CN/requirements.md +4 -1
- package/package.json +17 -1
- package/runtime/ext_gui/audio.cpp +365 -153
- package/runtime/ext_gui/audio_buffer.cpp +166 -0
- package/runtime/ext_gui/audio_buffer.h +37 -0
- package/runtime/ext_gui/audio_decode.cpp +219 -0
- package/runtime/ext_gui/audio_decode.h +39 -0
- package/runtime/ext_gui/audio_device.cpp +87 -0
- package/runtime/ext_gui/audio_effects.cpp +163 -0
- package/runtime/ext_gui/audio_effects.h +25 -0
- package/runtime/ext_gui/audio_internal.h +30 -0
- package/runtime/ext_gui/audio_mixer.cpp +494 -0
- package/runtime/ext_gui/audio_mixer.h +238 -0
- package/runtime/ext_gui/audio_param.cpp +104 -0
- package/runtime/ext_gui/audio_param_object.cpp +155 -0
- package/runtime/ext_gui/browser.cpp +45 -50
- package/runtime/ext_gui/browser_abort.cpp +249 -0
- package/runtime/ext_gui/browser_dialogs.cpp +76 -0
- package/runtime/ext_gui/browser_media.cpp +176 -0
- package/runtime/ext_gui/browser_navigation.cpp +130 -0
- package/runtime/ext_gui/canvas.cpp +88 -30
- package/runtime/ext_gui/canvas.h +74 -9
- package/runtime/ext_gui/canvas_image_data.cpp +143 -0
- package/runtime/ext_gui/canvas_internal.h +8 -5
- package/runtime/ext_gui/canvas_pattern.cpp +90 -0
- package/runtime/ext_gui/canvas_raster.cpp +31 -9
- package/runtime/ext_gui/canvas_style.cpp +4 -2
- package/runtime/ext_gui/css_selector.cpp +21 -3
- package/runtime/ext_gui/dom.h +4 -0
- package/runtime/ext_gui/dom_api.cpp +1 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +120 -114
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +57 -2
- package/runtime/ext_gui/dom_api_canvas_image.cpp +239 -0
- package/runtime/ext_gui/dom_api_canvas_paths.cpp +179 -0
- package/runtime/ext_gui/dom_api_computed_style.cpp +124 -0
- package/runtime/ext_gui/dom_api_dataset.cpp +154 -0
- package/runtime/ext_gui/dom_api_document.cpp +58 -5
- package/runtime/ext_gui/dom_api_events.cpp +93 -17
- package/runtime/ext_gui/dom_api_internal.h +71 -2
- package/runtime/ext_gui/dom_api_mutation.cpp +159 -0
- package/runtime/ext_gui/dom_api_node.cpp +40 -19
- package/runtime/ext_gui/dom_api_node_read.cpp +37 -1
- package/runtime/ext_gui/dom_api_path2d.cpp +358 -0
- package/runtime/ext_gui/dom_api_proto.cpp +35 -0
- package/runtime/ext_gui/dom_api_style.cpp +223 -13
- package/runtime/ext_gui/dom_api_webgl.cpp +7 -0
- package/runtime/ext_gui/dom_api_webgl2.cpp +151 -36
- package/runtime/ext_gui/dom_api_webgl2_draw.cpp +3 -3
- package/runtime/ext_gui/dom_api_webgl_buffer.cpp +6 -2
- package/runtime/ext_gui/dom_api_webgl_compressed.cpp +167 -0
- package/runtime/ext_gui/dom_api_webgl_framebuffer.cpp +160 -0
- package/runtime/ext_gui/dom_api_webgl_shader.cpp +4 -4
- package/runtime/ext_gui/dom_api_webgl_source.cpp +161 -0
- package/runtime/ext_gui/dom_api_webgl_state.cpp +169 -23
- package/runtime/ext_gui/dom_api_webgl_texture.cpp +276 -236
- package/runtime/ext_gui/dom_api_webgl_ubo.cpp +81 -0
- package/runtime/ext_gui/gui.cpp +103 -14
- package/runtime/ext_gui/gui_engine.h +56 -4
- package/runtime/ext_gui/gui_events.cpp +80 -9
- package/runtime/ext_gui/image_bitmap.cpp +28 -0
- package/runtime/ext_gui/image_bitmap.h +26 -0
- package/runtime/ext_gui/image_bitmap_browser.cpp +136 -0
- package/runtime/ext_gui/listener_options.h +43 -0
- package/runtime/ext_gui/media.cpp +32 -0
- package/runtime/ext_gui/media.h +13 -0
- package/runtime/ext_gui/media_api.h +23 -0
- package/runtime/ext_gui/paint.cpp +28 -0
- package/runtime/ext_gui/paint.h +4 -0
- package/runtime/ext_gui/webgl.h +152 -18
- package/runtime/ext_gui/webgl_blit.cpp +95 -0
- package/runtime/ext_gui/webgl_buffer.cpp +178 -263
- package/runtime/ext_gui/webgl_buffer_objects.cpp +270 -0
- package/runtime/ext_gui/webgl_clear.cpp +142 -0
- package/runtime/ext_gui/webgl_compressed.cpp +180 -0
- package/runtime/ext_gui/webgl_context.cpp +241 -156
- package/runtime/ext_gui/webgl_draw.cpp +68 -3
- package/runtime/ext_gui/webgl_draw_buffers.cpp +75 -0
- package/runtime/ext_gui/webgl_glsl.h +40 -0
- package/runtime/ext_gui/webgl_glsl_compile.cpp +6 -0
- package/runtime/ext_gui/webgl_glsl_rewrite.cpp +18 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +20 -11
- package/runtime/ext_gui/webgl_glsl_scan_block.cpp +126 -0
- package/runtime/ext_gui/webgl_glsl_tokens.h +28 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +71 -19
- package/runtime/ext_gui/webgl_program_blocks.cpp +58 -0
- package/runtime/ext_gui/webgl_program_internal.h +6 -0
- package/runtime/ext_gui/webgl_shader.cpp +13 -1
- package/runtime/ext_gui/webgl_state.cpp +228 -0
- package/runtime/ext_gui/webgl_texture.cpp +144 -17
- package/runtime/ext_gui/webgl_texture_3d.cpp +215 -0
- package/runtime/ext_gui/webgl_uniform_block.h +31 -0
- package/runtime/ext_gui/webgl_webgl2.cpp +58 -5
- package/runtime/ext_gui/window.cpp +14 -65
- package/runtime/ext_gui/window_events.cpp +125 -0
- package/runtime/ext_media/decode_audio.cpp +308 -0
- package/runtime/ext_media/media_bridge.c +2 -0
- package/runtime/rt.h +43 -0
- package/runtime/rt_internal.h +4 -0
- package/runtime/xt_array_buffer.c +30 -0
- package/runtime/xt_builtins.c +0 -21
- package/runtime/xt_containers/access.inc +94 -2
- package/runtime/xt_containers/objects.inc +29 -31
- package/runtime/xt_typed_array/elements.inc +13 -0
- package/scripts/build-media.ts +14 -6
- package/scripts/build-runtime.ts +21 -16
- package/scripts/check-version.ts +39 -9
- package/scripts/package-platform.ts +183 -0
- package/scripts/set-platform-version.ts +62 -0
- package/scripts/verify-platform-package.ts +182 -0
- package/src/cli/main.ts +5 -1
- package/src/driver/runtime-lib.ts +73 -9
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/index.ts +18 -5
- package/src/extensions/media/index.ts +4 -3
- package/src/parser/context.ts +99 -4
- package/src/parser/literals.ts +6 -12
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* xbintsc GUI engine — WebGL
|
|
3
|
-
* and framebuffers.
|
|
2
|
+
* xbintsc GUI engine — WebGL texture objects and framebuffers.
|
|
4
3
|
*
|
|
5
4
|
* Uploads are recorded immediately: a copy pass cannot run inside a render
|
|
6
|
-
* pass, so a
|
|
7
|
-
*
|
|
5
|
+
* pass, so a texture update ends the open pass first. The next draw starts a
|
|
6
|
+
* new pass with `LOAD`, so the framebuffer keeps its contents. Buffer objects
|
|
7
|
+
* and vertex-attribute state live in `webgl_buffer_objects.cpp`.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#include "webgl.h"
|
|
@@ -39,6 +39,14 @@ bool uses_mipmaps(int gl_filter) {
|
|
|
39
39
|
gl_filter == GL_NEAREST_MIPMAP_LINEAR || gl_filter == GL_LINEAR_MIPMAP_LINEAR;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
bool is_depth_format(SDL_GPUTextureFormat format) {
|
|
43
|
+
return format == SDL_GPU_TEXTUREFORMAT_D16_UNORM ||
|
|
44
|
+
format == SDL_GPU_TEXTUREFORMAT_D24_UNORM ||
|
|
45
|
+
format == SDL_GPU_TEXTUREFORMAT_D32_FLOAT ||
|
|
46
|
+
format == SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT ||
|
|
47
|
+
format == SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
SDL_GPUSamplerAddressMode address_of(int wrap) {
|
|
43
51
|
switch (wrap) {
|
|
44
52
|
case GL_CLAMP_TO_EDGE:
|
|
@@ -50,248 +58,8 @@ SDL_GPUSamplerAddressMode address_of(int wrap) {
|
|
|
50
58
|
}
|
|
51
59
|
}
|
|
52
60
|
|
|
53
|
-
bool upload_transfer(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUBuffer *buffer,
|
|
54
|
-
const void *bytes, uint32_t size) {
|
|
55
|
-
if (size == 0) return true;
|
|
56
|
-
SDL_GPUTransferBufferCreateInfo info;
|
|
57
|
-
memset(&info, 0, sizeof(info));
|
|
58
|
-
info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
|
59
|
-
info.size = size;
|
|
60
|
-
SDL_GPUTransferBuffer *transfer = SDL_CreateGPUTransferBuffer(device, &info);
|
|
61
|
-
if (transfer == nullptr) return false;
|
|
62
|
-
void *mapped = SDL_MapGPUTransferBuffer(device, transfer, false);
|
|
63
|
-
if (mapped == nullptr) {
|
|
64
|
-
SDL_ReleaseGPUTransferBuffer(device, transfer);
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
memcpy(mapped, bytes, size);
|
|
68
|
-
SDL_UnmapGPUTransferBuffer(device, transfer);
|
|
69
|
-
SDL_GPUCopyPass *copy = SDL_BeginGPUCopyPass(cmd);
|
|
70
|
-
SDL_GPUTransferBufferLocation source;
|
|
71
|
-
memset(&source, 0, sizeof(source));
|
|
72
|
-
source.transfer_buffer = transfer;
|
|
73
|
-
SDL_GPUBufferRegion region;
|
|
74
|
-
memset(®ion, 0, sizeof(region));
|
|
75
|
-
region.buffer = buffer;
|
|
76
|
-
region.size = size;
|
|
77
|
-
SDL_UploadToGPUBuffer(copy, &source, ®ion, false);
|
|
78
|
-
SDL_EndGPUCopyPass(copy);
|
|
79
|
-
SDL_ReleaseGPUTransferBuffer(device, transfer);
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
61
|
} // namespace
|
|
84
62
|
|
|
85
|
-
/* -- buffers ------------------------------------------------------------- */
|
|
86
|
-
|
|
87
|
-
uint32_t WebGLContext::create_buffer() {
|
|
88
|
-
auto record = std::make_unique<WebGLBuffer>();
|
|
89
|
-
record->id = next_object_id_++;
|
|
90
|
-
const uint32_t id = record->id;
|
|
91
|
-
buffers_[id] = std::move(record);
|
|
92
|
-
return id;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
void WebGLContext::delete_buffer(uint32_t id) {
|
|
96
|
-
auto found = buffers_.find(id);
|
|
97
|
-
if (found == buffers_.end()) return;
|
|
98
|
-
if (bound_array_ == id) bound_array_ = 0;
|
|
99
|
-
if (bound_element_ == id) bound_element_ = 0;
|
|
100
|
-
for (WebGLAttribState &attrib : attribs_) {
|
|
101
|
-
if (attrib.buffer == id) attrib.buffer = 0;
|
|
102
|
-
}
|
|
103
|
-
if (found->second->gpu != nullptr && guidev::g_device != nullptr) {
|
|
104
|
-
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
105
|
-
SDL_ReleaseGPUBuffer(guidev::g_device, found->second->gpu);
|
|
106
|
-
}
|
|
107
|
-
buffers_.erase(found);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
void WebGLContext::bind_buffer(int target, uint32_t id) {
|
|
111
|
-
if (id != 0 && buffers_.find(id) == buffers_.end()) return;
|
|
112
|
-
if (target == GL_ARRAY_BUFFER) bound_array_ = id;
|
|
113
|
-
if (target == GL_ELEMENT_ARRAY_BUFFER) bound_element_ = id;
|
|
114
|
-
if (target == GL_COPY_READ_BUFFER) copy_read_buffer_ = id;
|
|
115
|
-
if (target == GL_COPY_WRITE_BUFFER) copy_write_buffer_ = id;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
uint32_t WebGLContext::buffer_for_target(int target) const {
|
|
119
|
-
if (target == GL_ELEMENT_ARRAY_BUFFER) return bound_element_;
|
|
120
|
-
if (target == GL_ARRAY_BUFFER) return bound_array_;
|
|
121
|
-
if (target == GL_COPY_READ_BUFFER) return copy_read_buffer_;
|
|
122
|
-
if (target == GL_COPY_WRITE_BUFFER) return copy_write_buffer_;
|
|
123
|
-
return 0;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
bool WebGLContext::copy_buffer_sub_data(int read_target, int write_target, uint32_t read_offset,
|
|
127
|
-
uint32_t write_offset, uint32_t size) {
|
|
128
|
-
WebGLBuffer *read_buffer = buffer(buffer_for_target(read_target));
|
|
129
|
-
WebGLBuffer *write_buffer = buffer(buffer_for_target(write_target));
|
|
130
|
-
if (read_buffer == nullptr || write_buffer == nullptr ||
|
|
131
|
-
read_offset + size > read_buffer->data.size() ||
|
|
132
|
-
write_offset + size > write_buffer->data.size()) {
|
|
133
|
-
set_error(GL_INVALID_VALUE);
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
if (size > 0) {
|
|
137
|
-
memmove(write_buffer->data.data() + write_offset,
|
|
138
|
-
read_buffer->data.data() + read_offset, size);
|
|
139
|
-
}
|
|
140
|
-
write_buffer->dirty = true;
|
|
141
|
-
return ensure_buffer_gpu(write_buffer) != nullptr || size == 0;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
bool WebGLContext::get_buffer_sub_data(int target, uint32_t offset, uint8_t *out,
|
|
145
|
-
uint32_t size) {
|
|
146
|
-
WebGLBuffer *record = buffer(buffer_for_target(target));
|
|
147
|
-
if (record == nullptr || offset + size > record->data.size()) {
|
|
148
|
-
set_error(GL_INVALID_VALUE);
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
if (size > 0) memcpy(out, record->data.data() + offset, size);
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
SDL_GPUBuffer *WebGLContext::ensure_buffer_gpu(WebGLBuffer *buffer) {
|
|
156
|
-
if (buffer == nullptr || guidev::g_device == nullptr) return nullptr;
|
|
157
|
-
if (buffer->data.empty()) return nullptr;
|
|
158
|
-
end_pass();
|
|
159
|
-
ensure_command();
|
|
160
|
-
if (cmd_ == nullptr) return nullptr;
|
|
161
|
-
const uint32_t size = (uint32_t)buffer->data.size();
|
|
162
|
-
if (buffer->gpu == nullptr || buffer->capacity < size) {
|
|
163
|
-
if (buffer->gpu != nullptr) {
|
|
164
|
-
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
165
|
-
SDL_ReleaseGPUBuffer(guidev::g_device, buffer->gpu);
|
|
166
|
-
}
|
|
167
|
-
SDL_GPUBufferCreateInfo info;
|
|
168
|
-
memset(&info, 0, sizeof(info));
|
|
169
|
-
info.usage = SDL_GPU_BUFFERUSAGE_VERTEX | SDL_GPU_BUFFERUSAGE_INDEX;
|
|
170
|
-
info.size = size;
|
|
171
|
-
buffer->gpu = SDL_CreateGPUBuffer(guidev::g_device, &info);
|
|
172
|
-
buffer->capacity = size;
|
|
173
|
-
if (buffer->gpu == nullptr) {
|
|
174
|
-
set_error(GL_OUT_OF_MEMORY);
|
|
175
|
-
return nullptr;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (buffer->dirty) {
|
|
179
|
-
/* Recreating the buffer above submitted the pending command buffer. */
|
|
180
|
-
ensure_command();
|
|
181
|
-
if (cmd_ == nullptr) return nullptr;
|
|
182
|
-
if (!upload_transfer(guidev::g_device, cmd_, buffer->gpu, buffer->data.data(), size)) {
|
|
183
|
-
set_error(GL_OUT_OF_MEMORY);
|
|
184
|
-
return nullptr;
|
|
185
|
-
}
|
|
186
|
-
buffer->dirty = false;
|
|
187
|
-
}
|
|
188
|
-
return buffer->gpu;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
bool WebGLContext::buffer_data(uint32_t id, const uint8_t *bytes, uint32_t size, int usage) {
|
|
192
|
-
(void)usage;
|
|
193
|
-
WebGLBuffer *record = buffer(id);
|
|
194
|
-
if (record == nullptr) {
|
|
195
|
-
set_error(GL_INVALID_OPERATION);
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
record->data.assign(size, 0);
|
|
199
|
-
if (bytes != nullptr && size > 0) memcpy(record->data.data(), bytes, size);
|
|
200
|
-
record->dirty = true;
|
|
201
|
-
return ensure_buffer_gpu(record) != nullptr || size == 0;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
bool WebGLContext::buffer_sub_data(uint32_t id, uint32_t offset, const uint8_t *bytes,
|
|
205
|
-
uint32_t size) {
|
|
206
|
-
WebGLBuffer *record = buffer(id);
|
|
207
|
-
if (record == nullptr || offset > record->data.size() ||
|
|
208
|
-
offset + size > record->data.size()) {
|
|
209
|
-
set_error(GL_INVALID_VALUE);
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
memcpy(record->data.data() + offset, bytes, size);
|
|
213
|
-
record->dirty = true;
|
|
214
|
-
return ensure_buffer_gpu(record) != nullptr;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
uint32_t WebGLContext::buffer_size(uint32_t id) {
|
|
218
|
-
WebGLBuffer *record = buffer(id);
|
|
219
|
-
return record != nullptr ? (uint32_t)record->data.size() : 0;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/* -- vertex attributes --------------------------------------------------- */
|
|
223
|
-
|
|
224
|
-
void WebGLContext::enable_attrib(int index, bool enabled) {
|
|
225
|
-
if (index < 0 || index >= kWebGLMaxAttribs) {
|
|
226
|
-
set_error(GL_INVALID_VALUE);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
attribs_[index].enabled = enabled;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
bool WebGLContext::attrib_enabled(int index) const {
|
|
233
|
-
return index >= 0 && index < kWebGLMaxAttribs && attribs_[index].enabled;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
void WebGLContext::attrib_pointer(int index, int size, int type, bool normalized, int stride,
|
|
237
|
-
int offset) {
|
|
238
|
-
if (index < 0 || index >= kWebGLMaxAttribs) {
|
|
239
|
-
set_error(GL_INVALID_VALUE);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
WebGLAttribState &attrib = attribs_[index];
|
|
243
|
-
attrib.buffer = bound_array_;
|
|
244
|
-
attrib.size = size;
|
|
245
|
-
attrib.type = type;
|
|
246
|
-
attrib.normalized = normalized;
|
|
247
|
-
attrib.integer = false;
|
|
248
|
-
attrib.stride = stride > 0 ? stride : 0;
|
|
249
|
-
attrib.offset = offset;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
void WebGLContext::attrib_ipointer(int index, int size, int type, int stride, int offset) {
|
|
253
|
-
if (index < 0 || index >= kWebGLMaxAttribs) {
|
|
254
|
-
set_error(GL_INVALID_VALUE);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
WebGLAttribState &attrib = attribs_[index];
|
|
258
|
-
attrib.buffer = bound_array_;
|
|
259
|
-
attrib.size = size;
|
|
260
|
-
attrib.type = type;
|
|
261
|
-
attrib.normalized = false;
|
|
262
|
-
attrib.integer = true;
|
|
263
|
-
attrib.stride = stride > 0 ? stride : 0;
|
|
264
|
-
attrib.offset = offset;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
void WebGLContext::attrib_divisor(int index, int divisor) {
|
|
268
|
-
if (index < 0 || index >= kWebGLMaxAttribs) {
|
|
269
|
-
set_error(GL_INVALID_VALUE);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
/* SDL 3.2's `instance_step_rate` is reserved and must be 0, so only the two
|
|
273
|
-
* rates WebGL programs use — per vertex (0) and per instance (1) — map onto
|
|
274
|
-
* the backend. A larger divisor is clamped. */
|
|
275
|
-
attribs_[index].divisor = divisor > 0 ? 1 : 0;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
void WebGLContext::attrib_value(int index, int components, const float *values) {
|
|
279
|
-
if (index < 0 || index >= kWebGLMaxAttribs) return;
|
|
280
|
-
for (int i = 0; i < 4; i++) attribs_[index].current[i] = i < components ? values[i] : 0.0f;
|
|
281
|
-
if (components < 4) attribs_[index].current[3] = 1.0f;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
void WebGLContext::attrib_state(int index, int *size, int *type, int *stride, bool *normalized,
|
|
285
|
-
float current[4]) const {
|
|
286
|
-
if (index < 0 || index >= kWebGLMaxAttribs) return;
|
|
287
|
-
const WebGLAttribState &attrib = attribs_[index];
|
|
288
|
-
*size = attrib.size;
|
|
289
|
-
*type = attrib.type;
|
|
290
|
-
*stride = attrib.stride;
|
|
291
|
-
*normalized = attrib.normalized;
|
|
292
|
-
for (int i = 0; i < 4; i++) current[i] = attrib.current[i];
|
|
293
|
-
}
|
|
294
|
-
|
|
295
63
|
/* -- textures ------------------------------------------------------------ */
|
|
296
64
|
|
|
297
65
|
uint32_t WebGLContext::create_texture() {
|
|
@@ -312,6 +80,29 @@ void WebGLContext::delete_texture(uint32_t id) {
|
|
|
312
80
|
for (uint32_t &bound : bound_textures_) {
|
|
313
81
|
if (bound == id) bound = 0;
|
|
314
82
|
}
|
|
83
|
+
for (uint32_t &bound : bound_cube_textures_) {
|
|
84
|
+
if (bound == id) bound = 0;
|
|
85
|
+
}
|
|
86
|
+
for (uint32_t &bound : bound_array_textures_) {
|
|
87
|
+
if (bound == id) bound = 0;
|
|
88
|
+
}
|
|
89
|
+
for (uint32_t &bound : bound_3d_textures_) {
|
|
90
|
+
if (bound == id) bound = 0;
|
|
91
|
+
}
|
|
92
|
+
for (auto &entry : framebuffers_) {
|
|
93
|
+
bool cleared = false;
|
|
94
|
+
for (uint32_t &color : entry.second->color_textures) {
|
|
95
|
+
if (color == id) {
|
|
96
|
+
color = 0;
|
|
97
|
+
cleared = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (cleared) {
|
|
101
|
+
entry.second->width = 0;
|
|
102
|
+
entry.second->height = 0;
|
|
103
|
+
}
|
|
104
|
+
if (entry.second->depth_texture == id) entry.second->depth_texture = 0;
|
|
105
|
+
}
|
|
315
106
|
if (guidev::g_device != nullptr) {
|
|
316
107
|
if (found->second->gpu != nullptr) {
|
|
317
108
|
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
@@ -326,11 +117,31 @@ void WebGLContext::delete_texture(uint32_t id) {
|
|
|
326
117
|
|
|
327
118
|
void WebGLContext::bind_texture(int target, uint32_t id) {
|
|
328
119
|
if (id != 0 && textures_.find(id) == textures_.end()) return;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (target
|
|
333
|
-
|
|
120
|
+
uint32_t *slot = nullptr;
|
|
121
|
+
if (target == GL_TEXTURE_2D) {
|
|
122
|
+
slot = &bound_textures_[active_unit_];
|
|
123
|
+
} else if (target == GL_TEXTURE_CUBE_MAP) {
|
|
124
|
+
slot = &bound_cube_textures_[active_unit_];
|
|
125
|
+
} else if (target == GL_TEXTURE_2D_ARRAY) {
|
|
126
|
+
slot = &bound_array_textures_[active_unit_];
|
|
127
|
+
} else if (target == GL_TEXTURE_3D) {
|
|
128
|
+
slot = &bound_3d_textures_[active_unit_];
|
|
129
|
+
} else {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
*slot = id;
|
|
133
|
+
active_texture_target_[active_unit_] = target;
|
|
134
|
+
if (id != 0) {
|
|
135
|
+
WebGLTexture *record = texture(id);
|
|
136
|
+
if (record != nullptr) {
|
|
137
|
+
if (!record->defined && record->gpu == nullptr) {
|
|
138
|
+
record->target = target;
|
|
139
|
+
} else if (record->target != target) {
|
|
140
|
+
*slot = 0;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
334
145
|
}
|
|
335
146
|
|
|
336
147
|
void WebGLContext::active_texture(int unit) {
|
|
@@ -369,26 +180,65 @@ int WebGLContext::tex_parameter_value(uint32_t id, int pname) {
|
|
|
369
180
|
SDL_GPUTexture *WebGLContext::ensure_texture_gpu(WebGLTexture *record, bool as_target) {
|
|
370
181
|
if (record == nullptr || guidev::g_device == nullptr) return nullptr;
|
|
371
182
|
if (record->width <= 0 || record->height <= 0) return record->gpu;
|
|
372
|
-
|
|
183
|
+
const bool depth = is_depth_format(record->format);
|
|
184
|
+
record->depth = depth;
|
|
185
|
+
/* Allocate sample *and* target usage up front: attaching a texture that was
|
|
186
|
+
* already uploaded must not recreate it (shadow maps upload or attach in
|
|
187
|
+
* either order). Compressed textures are sample-only; layered textures can
|
|
188
|
+
* still be colour targets (a single layer is selected at render time). */
|
|
189
|
+
const uint32_t wanted =
|
|
190
|
+
record->compressed
|
|
191
|
+
? SDL_GPU_TEXTUREUSAGE_SAMPLER
|
|
192
|
+
: (SDL_GPU_TEXTUREUSAGE_SAMPLER |
|
|
193
|
+
(depth ? SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET
|
|
194
|
+
: SDL_GPU_TEXTUREUSAGE_COLOR_TARGET));
|
|
195
|
+
if (record->gpu != nullptr && record->usage == wanted) {
|
|
196
|
+
if (as_target) {
|
|
197
|
+
if (depth) record->as_depth_target = true;
|
|
198
|
+
else if (!record->compressed) record->as_target = true;
|
|
199
|
+
}
|
|
200
|
+
return record->gpu;
|
|
201
|
+
}
|
|
373
202
|
if (record->gpu != nullptr) {
|
|
374
203
|
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
375
204
|
SDL_ReleaseGPUTexture(guidev::g_device, record->gpu);
|
|
376
205
|
record->gpu = nullptr;
|
|
377
206
|
}
|
|
378
|
-
record->as_target = as_target;
|
|
379
|
-
record->
|
|
207
|
+
record->as_target = as_target && !depth && !record->compressed;
|
|
208
|
+
record->as_depth_target = as_target && depth;
|
|
209
|
+
record->usage = wanted;
|
|
210
|
+
record->levels =
|
|
211
|
+
(depth || record->compressed) ? 1 : mip_levels_for(record->width, record->height);
|
|
212
|
+
SDL_GPUTextureType texture_type = SDL_GPU_TEXTURETYPE_2D;
|
|
213
|
+
int layers = 1;
|
|
214
|
+
if (record->target == GL_TEXTURE_CUBE_MAP) {
|
|
215
|
+
texture_type = SDL_GPU_TEXTURETYPE_CUBE;
|
|
216
|
+
layers = 6;
|
|
217
|
+
} else if (record->target == GL_TEXTURE_2D_ARRAY) {
|
|
218
|
+
texture_type = SDL_GPU_TEXTURETYPE_2D_ARRAY;
|
|
219
|
+
layers = record->layers > 0 ? record->layers : 1;
|
|
220
|
+
} else if (record->target == GL_TEXTURE_3D) {
|
|
221
|
+
texture_type = SDL_GPU_TEXTURETYPE_3D;
|
|
222
|
+
layers = record->layers > 0 ? record->layers : 1;
|
|
223
|
+
}
|
|
380
224
|
SDL_GPUTextureCreateInfo info;
|
|
381
225
|
memset(&info, 0, sizeof(info));
|
|
382
|
-
info.type =
|
|
226
|
+
info.type = texture_type;
|
|
383
227
|
info.format = record->format;
|
|
384
|
-
info.usage =
|
|
385
|
-
if (as_target) info.usage |= SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
|
|
228
|
+
info.usage = wanted;
|
|
386
229
|
info.width = (Uint32)record->width;
|
|
387
230
|
info.height = (Uint32)record->height;
|
|
388
|
-
info.layer_count_or_depth =
|
|
231
|
+
info.layer_count_or_depth = (Uint32)layers;
|
|
389
232
|
info.num_levels = (Uint32)record->levels;
|
|
390
233
|
info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
|
391
234
|
record->gpu = SDL_CreateGPUTexture(guidev::g_device, &info);
|
|
235
|
+
if (record->gpu == nullptr && depth) {
|
|
236
|
+
/* Some backends cannot sample a depth-stencil format; an attachment-only
|
|
237
|
+
* texture is still useful for depth-only rendering. */
|
|
238
|
+
info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET;
|
|
239
|
+
record->gpu = SDL_CreateGPUTexture(guidev::g_device, &info);
|
|
240
|
+
record->usage = info.usage;
|
|
241
|
+
}
|
|
392
242
|
if (record->gpu == nullptr) set_error(GL_OUT_OF_MEMORY);
|
|
393
243
|
return record->gpu;
|
|
394
244
|
}
|
|
@@ -407,6 +257,14 @@ SDL_GPUSampler *WebGLContext::sampler_for(WebGLTexture *record) {
|
|
|
407
257
|
info.address_mode_w = address_of(record->wrap_t);
|
|
408
258
|
info.min_lod = 0.0f;
|
|
409
259
|
info.max_lod = record->has_mipmaps ? 1000.0f : 0.0f;
|
|
260
|
+
if (record->depth) {
|
|
261
|
+
/* Depth formats are sampled unfiltered; a depth value has no meaning once
|
|
262
|
+
* interpolated across a texel boundary. */
|
|
263
|
+
info.min_filter = SDL_GPU_FILTER_NEAREST;
|
|
264
|
+
info.mag_filter = SDL_GPU_FILTER_NEAREST;
|
|
265
|
+
info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST;
|
|
266
|
+
info.max_lod = 0.0f;
|
|
267
|
+
}
|
|
410
268
|
record->sampler = SDL_CreateGPUSampler(guidev::g_device, &info);
|
|
411
269
|
return record->sampler;
|
|
412
270
|
}
|
|
@@ -416,6 +274,16 @@ int WebGLContext::texture_width(uint32_t id) {
|
|
|
416
274
|
return record != nullptr ? record->width : 0;
|
|
417
275
|
}
|
|
418
276
|
|
|
277
|
+
int WebGLContext::texture_height(uint32_t id) {
|
|
278
|
+
WebGLTexture *record = texture(id);
|
|
279
|
+
return record != nullptr ? record->height : 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
int WebGLContext::texture_format(uint32_t id) {
|
|
283
|
+
WebGLTexture *record = texture(id);
|
|
284
|
+
return record != nullptr ? (int)record->format : 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
419
287
|
/* -- framebuffers -------------------------------------------------------- */
|
|
420
288
|
|
|
421
289
|
uint32_t WebGLContext::create_framebuffer() {
|
|
@@ -429,7 +297,8 @@ uint32_t WebGLContext::create_framebuffer() {
|
|
|
429
297
|
void WebGLContext::delete_framebuffer(uint32_t id) {
|
|
430
298
|
auto found = framebuffers_.find(id);
|
|
431
299
|
if (found == framebuffers_.end()) return;
|
|
432
|
-
if (bound_framebuffer_ == id) bind_framebuffer(0);
|
|
300
|
+
if (bound_framebuffer_ == id) bind_framebuffer(GL_FRAMEBUFFER, 0);
|
|
301
|
+
if (read_framebuffer_ == id) read_framebuffer_ = 0;
|
|
433
302
|
if (found->second->depth != nullptr && found->second->depth_renderbuffer == 0 &&
|
|
434
303
|
guidev::g_device != nullptr) {
|
|
435
304
|
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
@@ -438,18 +307,47 @@ void WebGLContext::delete_framebuffer(uint32_t id) {
|
|
|
438
307
|
framebuffers_.erase(found);
|
|
439
308
|
}
|
|
440
309
|
|
|
441
|
-
void WebGLContext::bind_framebuffer(uint32_t id) {
|
|
310
|
+
void WebGLContext::bind_framebuffer(int target, uint32_t id) {
|
|
442
311
|
if (id != 0 && framebuffers_.find(id) == framebuffers_.end()) return;
|
|
312
|
+
if (target == GL_READ_FRAMEBUFFER) {
|
|
313
|
+
read_framebuffer_ = id;
|
|
314
|
+
read_buffer_ = id == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0;
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER) return;
|
|
443
318
|
if (id != bound_framebuffer_) end_pass();
|
|
444
319
|
bound_framebuffer_ = id;
|
|
320
|
+
if (target == GL_FRAMEBUFFER) read_framebuffer_ = id;
|
|
321
|
+
read_buffer_ = id == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0;
|
|
445
322
|
}
|
|
446
323
|
|
|
447
|
-
bool WebGLContext::framebuffer_texture(uint32_t framebuffer_id, uint32_t texture_id
|
|
324
|
+
bool WebGLContext::framebuffer_texture(uint32_t framebuffer_id, uint32_t texture_id,
|
|
325
|
+
int attachment) {
|
|
448
326
|
WebGLFramebuffer *record_framebuffer = framebuffer(framebuffer_id);
|
|
449
327
|
WebGLTexture *record = texture(texture_id);
|
|
450
328
|
if (record_framebuffer == nullptr) return false;
|
|
451
329
|
if (texture_id != 0 && record == nullptr) return false;
|
|
452
|
-
|
|
330
|
+
if (attachment == GL_DEPTH_ATTACHMENT || attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
|
|
331
|
+
record_framebuffer->depth_texture = texture_id;
|
|
332
|
+
record_framebuffer->depth_renderbuffer = 0;
|
|
333
|
+
if (record_framebuffer->depth != nullptr) {
|
|
334
|
+
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
335
|
+
SDL_ReleaseGPUTexture(guidev::g_device, record_framebuffer->depth);
|
|
336
|
+
record_framebuffer->depth = nullptr;
|
|
337
|
+
}
|
|
338
|
+
if (record != nullptr) {
|
|
339
|
+
record->as_depth_target = true;
|
|
340
|
+
ensure_texture_gpu(record, true);
|
|
341
|
+
if (record_framebuffer->width <= 0 || record_framebuffer->height <= 0) {
|
|
342
|
+
record_framebuffer->width = record->width;
|
|
343
|
+
record_framebuffer->height = record->height;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
const int color_index = attachment - GL_COLOR_ATTACHMENT0;
|
|
349
|
+
if (color_index < 0 || color_index >= kWebGLMaxDrawBuffers) return false;
|
|
350
|
+
record_framebuffer->color_textures[color_index] = texture_id;
|
|
453
351
|
if (record != nullptr) {
|
|
454
352
|
record_framebuffer->width = record->width;
|
|
455
353
|
record_framebuffer->height = record->height;
|
|
@@ -458,10 +356,25 @@ bool WebGLContext::framebuffer_texture(uint32_t framebuffer_id, uint32_t texture
|
|
|
458
356
|
return true;
|
|
459
357
|
}
|
|
460
358
|
|
|
359
|
+
bool WebGLContext::framebuffer_texture_layer(uint32_t framebuffer_id, uint32_t texture_id,
|
|
360
|
+
int attachment, int layer) {
|
|
361
|
+
if (!framebuffer_texture(framebuffer_id, texture_id, attachment)) return false;
|
|
362
|
+
const int index = attachment - GL_COLOR_ATTACHMENT0;
|
|
363
|
+
WebGLFramebuffer *record = framebuffer(framebuffer_id);
|
|
364
|
+
if (record != nullptr && index >= 0 && index < kWebGLMaxDrawBuffers) {
|
|
365
|
+
record->color_layers[index] = layer;
|
|
366
|
+
}
|
|
367
|
+
/* SDL_GPU 3.2 depth-stencil targets have no layer selector; the depth
|
|
368
|
+
* attachment still binds, without per-layer rendering. */
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
461
372
|
bool WebGLContext::framebuffer_status(uint32_t id) {
|
|
462
373
|
WebGLFramebuffer *framebuffer_ = framebuffer(id);
|
|
463
374
|
if (framebuffer_ == nullptr) return false;
|
|
464
|
-
|
|
375
|
+
bool attached = false;
|
|
376
|
+
for (uint32_t color : framebuffer_->color_textures) attached = attached || color != 0;
|
|
377
|
+
if (!attached) {
|
|
465
378
|
set_error(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
|
466
379
|
return false;
|
|
467
380
|
}
|
|
@@ -508,8 +421,10 @@ bool WebGLContext::renderbuffer_storage(uint32_t id, int width, int height, bool
|
|
|
508
421
|
SDL_GPUTextureCreateInfo info;
|
|
509
422
|
memset(&info, 0, sizeof(info));
|
|
510
423
|
info.type = SDL_GPU_TEXTURETYPE_2D;
|
|
511
|
-
|
|
512
|
-
|
|
424
|
+
/* Every depth target uses the same depth-stencil format so one pipeline
|
|
425
|
+
* works with the default framebuffer and with render-to-texture targets;
|
|
426
|
+
* `stencil` only records whether the page asked for a stencil attachment. */
|
|
427
|
+
info.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
|
|
513
428
|
info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET;
|
|
514
429
|
info.width = (Uint32)width;
|
|
515
430
|
info.height = (Uint32)height;
|