Advertisement
Guest User

Final Script

a guest
Oct 4th, 2022
1,086
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. extends Node
  2.  
  3. var red_score := 0
  4. var blue_score := 0
  5.  
  6. var thread: Thread
  7. var semaphore: Semaphore
  8. var mutex: Mutex
  9. var exit := false
  10.  
  11. var paint_texture: ViewportTexture
  12.  
  13. var rd: RenderingDevice
  14. var shader
  15. var pipeline
  16. var buffer
  17.  
  18. var buffer_uniform
  19. var v_tex
  20. var samp
  21. var tex_uniform
  22.  
  23. var uniform_set
  24.  
  25. func _ready():
  26.     paint_texture = $'../DrawViewport'.get_texture()
  27.    
  28.     mutex = Mutex.new()
  29.     semaphore = Semaphore.new()
  30.     thread = Thread.new()
  31.     thread.start(_thread_calculate_score)
  32.    
  33.     # We will be using our own RenderingDevice to handle the compute commands
  34.     rd = RenderingServer.create_local_rendering_device()
  35.    
  36.     # Create shader and pipeline
  37.     var shader_file = load("res://compute.glsl")
  38.     var shader_spirv = shader_file.get_spirv()
  39.     shader = rd.shader_create_from_spirv(shader_spirv)
  40.     pipeline = rd.compute_pipeline_create(shader)
  41.    
  42.     var pb = PackedInt32Array([0,0])
  43.     var pbb = pb.to_byte_array()
  44.    
  45.     buffer = rd.storage_buffer_create(pbb.size(), pbb)
  46.    
  47.     buffer_uniform = RDUniform.new()
  48.     buffer_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER
  49.     buffer_uniform.binding = 0
  50.     buffer_uniform.add_id(buffer)
  51.    
  52.     var img = paint_texture.get_image()
  53.     var ta = img.get_data()
  54.    
  55.     var fmt = RDTextureFormat.new()
  56.     fmt.width = paint_texture.get_width()
  57.     fmt.height = paint_texture.get_height()
  58.     fmt.usage_bits = RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT | RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT
  59.     fmt.format = RenderingDevice.DATA_FORMAT_R8G8B8A8_SRGB
  60.    
  61.     v_tex = rd.texture_create(fmt, RDTextureView.new(), [ta])
  62.     var samp_state = RDSamplerState.new()
  63.     samp_state.unnormalized_uvw = true
  64.     samp = rd.sampler_create(samp_state)
  65.    
  66.     tex_uniform = RDUniform.new()
  67.     tex_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
  68.     tex_uniform.binding = 1
  69.     tex_uniform.add_id(samp)
  70.     tex_uniform.add_id(v_tex)
  71.    
  72.     uniform_set = rd.uniform_set_create([buffer_uniform, tex_uniform], shader, 0)
  73.    
  74. func recalculate_score():
  75.     await RenderingServer.frame_post_draw
  76.     semaphore.post()
  77.    
  78. func get_blue_score() -> int:
  79.     var result := blue_score
  80.    
  81.     return result
  82.    
  83. func get_red_score() -> int:
  84.     var result := red_score
  85.    
  86.     return result
  87.  
  88. func _thread_calculate_score():
  89.     while true:
  90.         semaphore.wait()
  91.        
  92.         mutex.lock()
  93.         var should_exit := exit
  94.         mutex.unlock()
  95.        
  96.         if should_exit:
  97.             break
  98.        
  99.         mutex.lock()
  100.         var image := paint_texture.get_image()
  101.         mutex.unlock()
  102.        
  103.         var size = image.get_size()
  104.         var blue_pixels := 0
  105.         var red_pixels := 0
  106.         var ta = image.get_data()
  107.        
  108.         rd.texture_update(v_tex, 0, ta)
  109.    
  110.         # Start compute list to start recording our compute commands
  111.         var compute_list = rd.compute_list_begin()
  112.         # Bind the pipeline, this tells the GPU what shader to use
  113.         rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
  114.         # Binds the uniform set with the data we want to give our shader
  115.         rd.compute_list_bind_uniform_set(compute_list, uniform_set, 0)
  116.         # Dispatch 1x1x1 (XxYxZ) work groups
  117.         rd.compute_list_dispatch(compute_list, 2048/8, 2048/8, 1)
  118.         #rd.compute_list_add_barrier(compute_list)
  119.         # Tell the GPU we are done with this compute task
  120.         rd.compute_list_end()
  121.  
  122.         # Force the GPU to start our commands
  123.         rd.submit()
  124.         # Force the CPU to wait for the GPU to finish with the recorded commands
  125.         rd.sync()
  126.  
  127.         mutex.lock()
  128.         # Now we can grab our data from the storage buffer
  129.         var byte_data = rd.buffer_get_data(buffer)
  130.         var output := byte_data.to_int32_array()
  131.        
  132.         print(output)
  133.         blue_score = floor(output[1]/1000)
  134.         red_score = floor(output[0]/1000)
  135.         var pb = PackedInt32Array([0,0])
  136.         var pbb = pb.to_byte_array()
  137.         rd.buffer_update(buffer, 0, pbb.size(), pbb)
  138.         mutex.unlock()
  139.  
  140. func _exit_tree():
  141.     mutex.lock()
  142.     exit = true
  143.     mutex.unlock()
  144.    
  145.     semaphore.post()
  146.     thread.wait_to_finish()
  147.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement