| 1574 | } |
| 1575 | |
| 1576 | Error RenderingDevice::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data) { |
| 1577 | ERR_RENDER_THREAD_GUARD_V(ERR_UNAVAILABLE); |
| 1578 | |
| 1579 | ERR_FAIL_COND_V_MSG(draw_list.active || compute_list.active, ERR_INVALID_PARAMETER, "Updating textures is forbidden during creation of a draw or compute list"); |
| 1580 | |
| 1581 | Texture *texture = texture_owner.get_or_null(p_texture); |
| 1582 | ERR_FAIL_NULL_V(texture, ERR_INVALID_PARAMETER); |
| 1583 | |
| 1584 | if (texture->owner != RID()) { |
| 1585 | p_texture = texture->owner; |
| 1586 | texture = texture_owner.get_or_null(texture->owner); |
| 1587 | ERR_FAIL_NULL_V(texture, ERR_BUG); // This is a bug. |
| 1588 | } |
| 1589 | |
| 1590 | ERR_FAIL_COND_V_MSG(texture->bound, ERR_CANT_ACQUIRE_RESOURCE, |
| 1591 | "Texture can't be updated 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 update this texture."); |
| 1592 | |
| 1593 | ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT), ERR_INVALID_PARAMETER, "Texture requires the `RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT` to be set to be updatable."); |
| 1594 | |
| 1595 | uint32_t layer_count = _texture_layer_count(texture); |
| 1596 | ERR_FAIL_COND_V(p_layer >= layer_count, ERR_INVALID_PARAMETER); |
| 1597 | |
| 1598 | uint32_t width, height; |
| 1599 | uint32_t tight_mip_size = get_image_format_required_size(texture->format, texture->width, texture->height, texture->depth, texture->mipmaps, &width, &height); |
| 1600 | uint32_t required_size = tight_mip_size; |
| 1601 | uint32_t required_align = _texture_alignment(texture); |
| 1602 | |
| 1603 | ERR_FAIL_COND_V_MSG(required_size != (uint32_t)p_data.size(), ERR_INVALID_PARAMETER, |
| 1604 | "Required size for texture update (" + itos(required_size) + ") does not match data supplied size (" + itos(p_data.size()) + ")."); |
| 1605 | |
| 1606 | // Clear the texture if the driver requires it during its first use. |
| 1607 | _texture_check_pending_clear(p_texture, texture); |
| 1608 | |
| 1609 | _check_transfer_worker_texture(texture); |
| 1610 | |
| 1611 | uint32_t block_w, block_h; |
| 1612 | get_compressed_image_format_block_dimensions(texture->format, block_w, block_h); |
| 1613 | |
| 1614 | uint32_t pixel_size = get_image_format_pixel_size(texture->format); |
| 1615 | uint32_t pixel_rshift = get_compressed_image_format_pixel_rshift(texture->format); |
| 1616 | uint32_t block_size = get_compressed_image_format_block_byte_size(texture->format); |
| 1617 | |
| 1618 | uint32_t region_size = texture_upload_region_size_px; |
| 1619 | |
| 1620 | const uint8_t *read_ptr = p_data.ptr(); |
| 1621 | |
| 1622 | thread_local LocalVector<RDG::RecordedBufferToTextureCopy> command_buffer_to_texture_copies_vector; |
| 1623 | command_buffer_to_texture_copies_vector.clear(); |
| 1624 | |
| 1625 | // Indicate the texture will get modified for the shared texture fallback. |
| 1626 | _texture_update_shared_fallback(p_texture, texture, true); |
| 1627 | |
| 1628 | uint32_t mipmap_offset = 0; |
| 1629 | |
| 1630 | uint32_t logic_width = texture->width; |
| 1631 | uint32_t logic_height = texture->height; |
| 1632 | |
| 1633 | for (uint32_t mm_i = 0; mm_i < texture->mipmaps; mm_i++) { |
no test coverage detected