| 2323 | #endif |
| 2324 | |
| 2325 | Error RenderingDevice::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer) { |
| 2326 | ERR_RENDER_THREAD_GUARD_V(ERR_UNAVAILABLE); |
| 2327 | |
| 2328 | Texture *src_tex = texture_owner.get_or_null(p_from_texture); |
| 2329 | ERR_FAIL_NULL_V(src_tex, ERR_INVALID_PARAMETER); |
| 2330 | |
| 2331 | ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, |
| 2332 | "Source texture can't be copied while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to `RenderingDevice.FINAL_ACTION_CONTINUE`) to copy this texture."); |
| 2333 | ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER, |
| 2334 | "Source texture requires the `RenderingDevice.TEXTURE_USAGE_CAN_COPY_FROM_BIT` to be set to be retrieved."); |
| 2335 | |
| 2336 | uint32_t src_width, src_height, src_depth; |
| 2337 | get_image_format_required_size(src_tex->format, src_tex->width, src_tex->height, src_tex->depth, p_src_mipmap + 1, &src_width, &src_height, &src_depth); |
| 2338 | |
| 2339 | ERR_FAIL_COND_V(p_from.x < 0 || p_from.x + p_size.x > src_width, ERR_INVALID_PARAMETER); |
| 2340 | ERR_FAIL_COND_V(p_from.y < 0 || p_from.y + p_size.y > src_height, ERR_INVALID_PARAMETER); |
| 2341 | ERR_FAIL_COND_V(p_from.z < 0 || p_from.z + p_size.z > src_depth, ERR_INVALID_PARAMETER); |
| 2342 | ERR_FAIL_COND_V(p_src_mipmap >= src_tex->mipmaps, ERR_INVALID_PARAMETER); |
| 2343 | ERR_FAIL_COND_V(p_src_layer >= src_tex->layers, ERR_INVALID_PARAMETER); |
| 2344 | |
| 2345 | Texture *dst_tex = texture_owner.get_or_null(p_to_texture); |
| 2346 | ERR_FAIL_NULL_V(dst_tex, ERR_INVALID_PARAMETER); |
| 2347 | |
| 2348 | ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER, |
| 2349 | "Destination texture can't be copied while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to `RenderingDevice.FINAL_ACTION_CONTINUE`) to copy this texture."); |
| 2350 | ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER, |
| 2351 | "Destination texture requires the `RenderingDevice.TEXTURE_USAGE_CAN_COPY_TO_BIT` to be set to be retrieved."); |
| 2352 | |
| 2353 | uint32_t dst_width, dst_height, dst_depth; |
| 2354 | get_image_format_required_size(dst_tex->format, dst_tex->width, dst_tex->height, dst_tex->depth, p_dst_mipmap + 1, &dst_width, &dst_height, &dst_depth); |
| 2355 | |
| 2356 | ERR_FAIL_COND_V(p_to.x < 0 || p_to.x + p_size.x > dst_width, ERR_INVALID_PARAMETER); |
| 2357 | ERR_FAIL_COND_V(p_to.y < 0 || p_to.y + p_size.y > dst_height, ERR_INVALID_PARAMETER); |
| 2358 | ERR_FAIL_COND_V(p_to.z < 0 || p_to.z + p_size.z > dst_depth, ERR_INVALID_PARAMETER); |
| 2359 | ERR_FAIL_COND_V(p_dst_mipmap >= dst_tex->mipmaps, ERR_INVALID_PARAMETER); |
| 2360 | ERR_FAIL_COND_V(p_dst_layer >= dst_tex->layers, ERR_INVALID_PARAMETER); |
| 2361 | |
| 2362 | ERR_FAIL_COND_V_MSG(src_tex->read_aspect_flags != dst_tex->read_aspect_flags, ERR_INVALID_PARAMETER, |
| 2363 | "Source and destination texture must be of the same type (color or depth)."); |
| 2364 | |
| 2365 | // Clear the textures if the driver requires it during its first use. |
| 2366 | _texture_check_pending_clear(p_from_texture, src_tex); |
| 2367 | _texture_check_pending_clear(p_to_texture, dst_tex); |
| 2368 | |
| 2369 | _check_transfer_worker_texture(src_tex); |
| 2370 | _check_transfer_worker_texture(dst_tex); |
| 2371 | |
| 2372 | RDD::TextureCopyRegion copy_region; |
| 2373 | copy_region.src_subresources.aspect = src_tex->read_aspect_flags; |
| 2374 | copy_region.src_subresources.mipmap = p_src_mipmap; |
| 2375 | copy_region.src_subresources.base_layer = p_src_layer; |
| 2376 | copy_region.src_subresources.layer_count = 1; |
| 2377 | copy_region.src_offset = p_from; |
| 2378 | |
| 2379 | copy_region.dst_subresources.aspect = dst_tex->read_aspect_flags; |
| 2380 | copy_region.dst_subresources.mipmap = p_dst_mipmap; |
| 2381 | copy_region.dst_subresources.base_layer = p_dst_layer; |
| 2382 | copy_region.dst_subresources.layer_count = 1; |
no test coverage detected