@@ -196,32 +196,6 @@ pub fn op_jupyter_create_png_from_texture(
196196 use deno_runtime:: deno_webgpu:: * ;
197197 use texture:: GPUTextureFormat ;
198198
199- // We only support the 8 bit per pixel formats with 4 channels
200- // as such a pixel has 4 bytes
201- const BYTES_PER_PIXEL : u32 = 4 ;
202-
203- let unpadded_bytes_per_row = texture. size . width * BYTES_PER_PIXEL ;
204- let padded_bytes_per_row_padding = ( wgpu_types:: COPY_BYTES_PER_ROW_ALIGNMENT
205- - ( unpadded_bytes_per_row % wgpu_types:: COPY_BYTES_PER_ROW_ALIGNMENT ) )
206- % wgpu_types:: COPY_BYTES_PER_ROW_ALIGNMENT ;
207- let padded_bytes_per_row =
208- unpadded_bytes_per_row + padded_bytes_per_row_padding;
209-
210- let ( buffer, maybe_err) = texture. instance . device_create_buffer (
211- texture. device_id ,
212- & wgpu_types:: BufferDescriptor {
213- label : None ,
214- size : ( padded_bytes_per_row * texture. size . height ) as _ ,
215- usage : wgpu_types:: BufferUsages :: MAP_READ
216- | wgpu_types:: BufferUsages :: COPY_DST ,
217- mapped_at_creation : false ,
218- } ,
219- None ,
220- ) ;
221- if let Some ( maybe_err) = maybe_err {
222- return Err ( JsErrorBox :: from_err :: < GPUError > ( maybe_err. into ( ) ) ) ;
223- }
224-
225199 let ( command_encoder, maybe_err) =
226200 texture. instance . device_create_command_encoder (
227201 texture. device_id ,
@@ -232,94 +206,14 @@ pub fn op_jupyter_create_png_from_texture(
232206 return Err ( JsErrorBox :: from_err :: < GPUError > ( maybe_err. into ( ) ) ) ;
233207 }
234208
235- texture
236- . instance
237- . command_encoder_copy_texture_to_buffer (
238- command_encoder,
239- & wgpu_types:: TexelCopyTextureInfo {
240- texture : texture. id ,
241- mip_level : 0 ,
242- origin : Default :: default ( ) ,
243- aspect : Default :: default ( ) ,
244- } ,
245- & wgpu_types:: TexelCopyBufferInfo {
246- buffer,
247- layout : wgpu_types:: TexelCopyBufferLayout {
248- offset : 0 ,
249- bytes_per_row : Some ( padded_bytes_per_row) ,
250- rows_per_image : None ,
251- } ,
252- } ,
253- & texture. size ,
254- )
255- . map_err ( |e| JsErrorBox :: from_err :: < GPUError > ( e. into ( ) ) ) ?;
256-
257- let ( command_buffer, maybe_err) = texture. instance . command_encoder_finish (
209+ let data = canvas:: copy_texture_to_vec (
210+ & texture. instance ,
211+ texture. device_id ,
212+ texture. queue_id ,
258213 command_encoder,
259- & wgpu_types:: CommandBufferDescriptor { label : None } ,
260- None ,
261- ) ;
262- if let Some ( ( _, maybe_err) ) = maybe_err {
263- return Err ( JsErrorBox :: from_err :: < GPUError > ( maybe_err. into ( ) ) ) ;
264- }
265-
266- let maybe_err = texture
267- . instance
268- . queue_submit ( texture. queue_id , & [ command_buffer] )
269- . err ( ) ;
270- if let Some ( ( _, maybe_err) ) = maybe_err {
271- return Err ( JsErrorBox :: from_err :: < GPUError > ( maybe_err. into ( ) ) ) ;
272- }
273-
274- let index = texture
275- . instance
276- . buffer_map_async (
277- buffer,
278- 0 ,
279- None ,
280- wgpu_core:: resource:: BufferMapOperation {
281- host : wgpu_core:: device:: HostMap :: Read ,
282- callback : None ,
283- } ,
284- )
285- . map_err ( |e| JsErrorBox :: from_err :: < GPUError > ( e. into ( ) ) ) ?;
286-
287- texture
288- . instance
289- . device_poll (
290- texture. device_id ,
291- wgpu_types:: PollType :: Wait {
292- submission_index : Some ( index) ,
293- timeout : None ,
294- } ,
295- )
296- . unwrap ( ) ;
297-
298- let ( slice_pointer, range_size) = texture
299- . instance
300- . buffer_get_mapped_range ( buffer, 0 , None )
301- . map_err ( |e| JsErrorBox :: from_err :: < GPUError > ( e. into ( ) ) ) ?;
302-
303- let data = {
304- // SAFETY: creating a slice from pointer and length provided by wgpu and
305- // then dropping it before unmapping
306- let slice = unsafe {
307- std:: slice:: from_raw_parts ( slice_pointer. as_ptr ( ) , range_size as usize )
308- } ;
309-
310- let mut unpadded =
311- Vec :: with_capacity ( ( unpadded_bytes_per_row * texture. size . height ) as _ ) ;
312-
313- for i in 0 ..texture. size . height {
314- unpadded. extend_from_slice (
315- & slice[ ( ( i * padded_bytes_per_row) as usize )
316- ..( ( ( i + 1 ) * padded_bytes_per_row) as usize ) ]
317- [ ..( unpadded_bytes_per_row as usize ) ] ,
318- ) ;
319- }
320-
321- unpadded
322- } ;
214+ texture. id ,
215+ & texture. size ,
216+ ) ?;
323217
324218 let color_type = match texture. format {
325219 GPUTextureFormat :: Rgba8unorm => ExtendedColorType :: Rgba8 ,
@@ -345,12 +239,6 @@ pub fn op_jupyter_create_png_from_texture(
345239 . write_image ( & data, texture. size . width , texture. size . height , color_type)
346240 . map_err ( |e| JsErrorBox :: type_error ( e. to_string ( ) ) ) ?;
347241
348- texture
349- . instance
350- . buffer_unmap ( buffer)
351- . map_err ( |e| JsErrorBox :: from_err :: < GPUError > ( e. into ( ) ) ) ?;
352- texture. instance . buffer_drop ( buffer) ;
353-
354242 Ok ( deno_runtime:: deno_web:: forgiving_base64_encode ( & out) )
355243}
356244
0 commit comments