-
-
Notifications
You must be signed in to change notification settings - Fork 6
webgpu: captureToCanvasのバグ修正 #256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2746,10 +2746,11 @@ export class Context | |||||||||
| */ | ||||||||||
| async createImageBitmap (width: number, height: number): Promise<ImageBitmap> | ||||||||||
| { | ||||||||||
| // アトラステクスチャから現在の描画内容を取得 | ||||||||||
| const attachment = $getAtlasAttachmentObject(); | ||||||||||
| if (!attachment) { | ||||||||||
| throw new Error("[WebGPU] Atlas attachment not found"); | ||||||||||
| // メインアタッチメントから合成済み描画結果を取得 | ||||||||||
| // (drawArraysInstanced()がアトラスからメインアタッチメントへ合成済み) | ||||||||||
| const mainAttachment = this.$mainAttachmentObject; | ||||||||||
| if (!mainAttachment || !mainAttachment.texture) { | ||||||||||
| throw new Error("[WebGPU] Main attachment not found"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // 描画を完了 | ||||||||||
|
|
@@ -2769,17 +2770,13 @@ export class Context | |||||||||
| "usage": GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| // コマンドエンコーダーを作成 | ||||||||||
| const commandEncoder = this.device.createCommandEncoder(); | ||||||||||
|
|
||||||||||
| // アトラステクスチャからピクセルバッファにコピー | ||||||||||
| if (!attachment.texture) { | ||||||||||
| throw new Error("Attachment texture is null"); | ||||||||||
| } | ||||||||||
| // フレームのcommandEncoderにcopyコマンドを追加 | ||||||||||
| // 描画コマンドの後にコピーが実行されるため、正しい順序が保証される | ||||||||||
| this.ensureCommandEncoder(); | ||||||||||
|
|
||||||||||
| commandEncoder.copyTextureToBuffer( | ||||||||||
| this.commandEncoder!.copyTextureToBuffer( | ||||||||||
| { | ||||||||||
| "texture": attachment.texture.resource, | ||||||||||
| "texture": mainAttachment.texture.resource, | ||||||||||
| "mipLevel": 0, | ||||||||||
| "origin": { "x": 0, "y": 0, "z": 0 } | ||||||||||
| }, | ||||||||||
|
|
@@ -2795,23 +2792,36 @@ export class Context | |||||||||
| } | ||||||||||
| ); | ||||||||||
|
|
||||||||||
| // コマンドを送信 | ||||||||||
| this.device.queue.submit([commandEncoder.finish()]); | ||||||||||
| // endFrame()で描画コマンドとcopyコマンドを一括submit | ||||||||||
| // swap chain textureの参照もクリアされる | ||||||||||
| this.endFrame(); | ||||||||||
|
|
||||||||||
| // バッファをマップして読み込み | ||||||||||
| await pixelBuffer.mapAsync(GPUMapMode.READ); | ||||||||||
| const mappedRange = pixelBuffer.getMappedRange(); | ||||||||||
| const pixels = new Uint8Array(mappedRange); | ||||||||||
|
|
||||||||||
| // ピクセルデータをコピー(アライメントを考慮) | ||||||||||
| // メインアタッチメントはbgra8unormフォーマットのため、 | ||||||||||
| // ImageData(RGBA)用にB⇔Rチャンネルをスワップしつつコピー | ||||||||||
|
Comment on lines
+2804
to
+2805
|
||||||||||
| // メインアタッチメントはbgra8unormフォーマットのため、 | |
| // ImageData(RGBA)用にB⇔Rチャンネルをスワップしつつコピー | |
| // メインアタッチメントのフォーマットが bgra8unorm の場合は、 | |
| // ImageData(RGBA)用に B⇔R チャンネルをスワップしつつコピー(それ以外のフォーマットはそのままコピー) |
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change alters capture output semantics (source attachment + color channel order) and introduces new ordering/submission behavior via ensureCommandEncoder()+endFrame(). Context.test.ts exists but doesn't cover createImageBitmap(); adding a unit test that validates correct RGBA output (especially on BGRA preferredFormat) and that the copy command gets submitted would help prevent regressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createImageBitmap() now relies on endFrame() to submit the copyTextureToBuffer command, but endFrame() is a no-op when frameStarted is false. If this API is called before beginFrame()/drawArraysInstanced(), the copy will never be submitted and mapAsync() can hang. Consider ensuring the frame is started here (e.g., call beginFrame() when needed / set frameStarted) or submit a dedicated command buffer for the copy like the previous implementation, instead of depending on endFrame().