16void ScreenSpaceDrawingMode::add_shgroups()
const
20 const ShaderParameters &sh_params = instance_.state.sh_params;
23 pass.shader_set(shader);
24 pass.push_constant(
"far_near_distances", sh_params.far_near);
25 pass.push_constant(
"shuffle", sh_params.shuffle);
26 pass.push_constant(
"draw_flags",
int32_t(sh_params.flags));
27 pass.push_constant(
"is_image_premultiplied", sh_params.use_premul_alpha);
28 pass.bind_texture(
"depth_tx", dtxl->
depth);
31 ResourceHandleRange handle = instance_.manager->resource_handle(image_mat);
32 for (
const TextureInfo &info : instance_.state.texture_infos) {
34 sub.push_constant(
"offset", info.offset());
35 sub.bind_texture(
"image_tx", info.texture);
36 sub.draw(info.batch, handle);
40void ScreenSpaceDrawingMode::add_depth_shgroups(
::Image *image,
ImageUser *image_user)
const
44 pass.shader_set(shader);
47 ResourceHandleRange handle = instance_.manager->resource_handle(image_mat);
51 tile_user = *image_user;
54 for (
const TextureInfo &info : instance_.state.texture_infos) {
56 const ImageTileWrapper image_tile(image_tile_ptr);
57 const int tile_x = image_tile.get_tile_x_offset();
58 const int tile_y = image_tile.get_tile_y_offset();
59 tile_user.
tile = image_tile.get_tile_number();
65 if (tile_buffer !=
nullptr) {
66 instance_.state.float_buffers.mark_used(tile_buffer);
68 float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1);
69 sub.push_constant(
"min_max_uv", min_max_uv);
70 sub.draw(info.batch, handle);
77void ScreenSpaceDrawingMode::update_textures(
::Image *image,
ImageUser *image_user)
const
79 State &
state = instance_.state;
80 PartialUpdateChecker<ImageTileData> checker(image, image_user,
state.partial_update.user);
81 PartialUpdateChecker<ImageTileData>::CollectResult changes = checker.collect_changes();
83 switch (changes.get_result_code()) {
84 case ePartialUpdateCollectResult::FullUpdateNeeded:
85 state.mark_all_texture_slots_dirty();
86 state.float_buffers.clear();
88 case ePartialUpdateCollectResult::NoChangesDetected:
90 case ePartialUpdateCollectResult::PartialChangesDetected:
92 if (
state.flags.do_tile_drawing) {
93 state.float_buffers.clear();
94 state.mark_all_texture_slots_dirty();
97 do_partial_update(changes);
101 do_full_update_for_dirty_textures(image_user);
104void ScreenSpaceDrawingMode::do_partial_update_float_buffer(
107 ImBuf *src = iterator.tile_data.tile_buffer;
119 rcti clipped_update_region;
121 &buffer_rect, &iterator.changed_region.region, &clipped_update_region);
129void ScreenSpaceDrawingMode::do_partial_update(
132 while (iterator.get_next_change() == ePartialUpdateIterResult::ChangeAvailable) {
134 if (iterator.tile_data.tile_buffer ==
nullptr) {
137 ImBuf *tile_buffer = instance_.state.float_buffers.cached_float_buffer(
138 iterator.tile_data.tile_buffer);
139 if (tile_buffer != iterator.tile_data.tile_buffer) {
140 do_partial_update_float_buffer(tile_buffer, iterator);
146 for (
const TextureInfo &info : instance_.state.texture_infos) {
148 if (info.need_full_update) {
151 gpu::Texture *
texture = info.texture;
155 ImageTileWrapper tile_accessor(iterator.tile_data.tile);
156 float tile_offset_x =
float(tile_accessor.get_tile_x_offset());
157 float tile_offset_y =
float(tile_accessor.get_tile_y_offset());
158 rcti *changed_region_in_texel_space = &iterator.changed_region.region;
159 rctf changed_region_in_uv_space;
161 &changed_region_in_uv_space,
162 float(changed_region_in_texel_space->
xmin) /
float(iterator.tile_data.tile_buffer->x) +
164 float(changed_region_in_texel_space->
xmax) /
float(iterator.tile_data.tile_buffer->x) +
166 float(changed_region_in_texel_space->
ymin) /
float(iterator.tile_data.tile_buffer->y) +
168 float(changed_region_in_texel_space->
ymax) /
float(iterator.tile_data.tile_buffer->y) +
170 rctf changed_overlapping_region_in_uv_space;
171 const bool region_overlap =
BLI_rctf_isect(&info.clipping_uv_bounds,
172 &changed_region_in_uv_space,
173 &changed_overlapping_region_in_uv_space);
174 if (!region_overlap) {
180 rcti gpu_texture_region_to_update;
182 &gpu_texture_region_to_update,
183 floor((changed_overlapping_region_in_uv_space.
xmin - info.clipping_uv_bounds.xmin) *
185 floor((changed_overlapping_region_in_uv_space.
xmax - info.clipping_uv_bounds.xmin) *
187 ceil((changed_overlapping_region_in_uv_space.
ymin - info.clipping_uv_bounds.ymin) *
189 ceil((changed_overlapping_region_in_uv_space.
ymax - info.clipping_uv_bounds.ymin) *
191 gpu_texture_region_to_update.
xmax =
min_ii(gpu_texture_region_to_update.
xmax,
192 info.clipping_bounds.xmax);
193 gpu_texture_region_to_update.
ymax =
min_ii(gpu_texture_region_to_update.
ymax,
194 info.clipping_bounds.ymax);
196 rcti tile_region_to_extract;
198 &tile_region_to_extract,
199 floor((changed_overlapping_region_in_uv_space.
xmin - tile_offset_x) * tile_width),
200 floor((changed_overlapping_region_in_uv_space.
xmax - tile_offset_x) * tile_width),
201 ceil((changed_overlapping_region_in_uv_space.
ymin - tile_offset_y) * tile_height),
202 ceil((changed_overlapping_region_in_uv_space.
ymax - tile_offset_y) * tile_height));
206 const int texture_region_width =
BLI_rcti_size_x(&gpu_texture_region_to_update);
207 const int texture_region_height =
BLI_rcti_size_y(&gpu_texture_region_to_update);
209 ImBuf extracted_buffer;
211 &extracted_buffer, texture_region_width, texture_region_height, 32,
IB_float_data);
214 for (
int y = gpu_texture_region_to_update.
ymin;
y < gpu_texture_region_to_update.
ymax;
y++) {
215 float yf =
y /
float(texture_height);
216 float v = info.clipping_uv_bounds.ymax * yf + info.clipping_uv_bounds.ymin * (1.0 - yf) -
218 for (
int x = gpu_texture_region_to_update.
xmin;
x < gpu_texture_region_to_update.
xmax;
x++)
220 float xf =
x /
float(texture_width);
221 float u = info.clipping_uv_bounds.xmax * xf + info.clipping_uv_bounds.xmin * (1.0 - xf) -
235 gpu_texture_region_to_update.
xmin,
236 gpu_texture_region_to_update.
ymin,
246void ScreenSpaceDrawingMode::do_full_update_for_dirty_textures(
const ImageUser *image_user)
const
248 for (TextureInfo &info : instance_.state.texture_infos) {
249 if (!info.need_full_update) {
252 do_full_update_gpu_texture(info, image_user);
256void ScreenSpaceDrawingMode::do_full_update_gpu_texture(
TextureInfo &info,
259 ImBuf texture_buffer;
265 tile_user = *image_user;
270 ::Image *image = instance_.state.image;
272 const ImageTileWrapper image_tile(image_tile_ptr);
273 tile_user.
tile = image_tile.get_tile_number();
276 if (tile_buffer !=
nullptr) {
277 do_full_update_texture_slot(info, texture_buffer, *tile_buffer, image_tile);
286void ScreenSpaceDrawingMode::do_full_update_texture_slot(
const TextureInfo &texture_info,
287 ImBuf &texture_buffer,
291 const int texture_width = texture_buffer.
x;
292 const int texture_height = texture_buffer.
y;
293 ImBuf *float_tile_buffer = instance_.state.float_buffers.cached_float_buffer(&tile_buffer);
302 BLI_rctf_init(&texture_area, 0.0, texture_width, 0.0, texture_height);
305 tile_buffer.
x * (texture_info.clipping_uv_bounds.xmin - image_tile.get_tile_x_offset()),
306 tile_buffer.
x * (texture_info.clipping_uv_bounds.xmax - image_tile.get_tile_x_offset()),
307 tile_buffer.
y * (texture_info.clipping_uv_bounds.ymin - image_tile.get_tile_y_offset()),
308 tile_buffer.
y * (texture_info.clipping_uv_bounds.ymax - image_tile.get_tile_y_offset()));
313 const rctf *crop_rect_ptr =
nullptr;
315 if (instance_.state.flags.do_tile_drawing) {
320 crop_rect_ptr = &crop_rect;
355 state.partial_update.ensure_image(image);
356 state.clear_need_full_update_flag();
357 state.float_buffers.reset_usage_flags();
366 state.update_image_usage(iuser);
370 update_textures(image, iuser);
373 state.update_batches();
374 if (!
state.flags.do_tile_drawing) {
375 add_depth_shgroups(image, iuser);
382 instance_.state.float_buffers.remove_unused_buffers();
387 float clear_depth = instance_.state.flags.do_tile_drawing ? 0.75 : 1.0f;
389 instance_.state.depth_fb.clear_depth(clear_depth);
390 instance_.manager->submit(instance_.state.depth_ps, instance_.state.view);
395 instance_.manager->submit(instance_.state.image_ps, instance_.state.view);
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
#define LISTBASE_FOREACH(type, var, list)
MINLINE int min_ii(int a, int b)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
void BLI_rctf_transform_calc_m3_pivot_min(const rctf *dst, const rctf *src, float matrix[3][3])
bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
struct ImageTile ImageTile
struct ImageUser ImageUser
#define GPU_ATTACHMENT_TEXTURE(_texture)
#define GPU_ATTACHMENT_NONE
void GPU_framebuffer_clear_color(blender::gpu::FrameBuffer *fb, const float clear_col[4])
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
void GPU_texture_update_sub(blender::gpu::Texture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
int GPU_texture_height(const blender::gpu::Texture *texture)
int GPU_texture_width(const blender::gpu::Texture *texture)
void GPU_texture_update(blender::gpu::Texture *texture, eGPUDataFormat data_format, const void *data)
void IMB_float_from_byte_ex(ImBuf *dst, const ImBuf *src, const rcti *region_to_update)
void IMB_transform(const ImBuf *src, ImBuf *dst, eIMBTransformMode mode, eIMBInterpolationFilterMode filter, const blender::float3x3 &transform_matrix, const rctf *src_crop)
Transform source image buffer onto destination image buffer using a transform matrix.
eIMBTransformMode
Transform modes to use for IMB_transform function.
@ IMB_TRANSFORM_MODE_WRAP_REPEAT
Wrap repeat the source buffer. Only supported in with nearest filtering.
@ IMB_TRANSFORM_MODE_CROP_SRC
Crop the source buffer.
void IMB_free_all_data(ImBuf *ibuf)
bool IMB_initImBuf(ImBuf *ibuf, unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
void IMB_gpu_clamp_half_float(ImBuf *image_buffer)
ATTR_WARN_UNUSED_RESULT const BMVert * v
void state_set(DRWState state, int clip_plane_count=0)
detail::PassBase< command::DrawCommandBuf > Sub
void update_bounds(const ARegion *region) override
Update the uv and region bounds of all texture_infos of instance_data.
void ensure_gpu_textures_allocation() override
void ensure_texture_infos() override
Ensure enough texture infos are allocated in instance_data.
void draw_finish() const override
void draw_viewport() const override
void begin_sync() const override
void image_sync(::Image *image, ::ImageUser *iuser) const override
static ShaderModule & module_get()
const DRWContext * DRW_context_get()
@ DRW_STATE_DEPTH_LESS_EQUAL
@ DRW_STATE_BLEND_ALPHA_PREMUL
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
detail::Pass< command::DrawCommandBuf > PassSimple
int tile_height(const AssetShelfSettings &settings)
int tile_width(const AssetShelfSettings &settings)
float4 interpolate_nearest_border_fl(const ImBuf *in, float u, float v)
CartesianBasis invert(const CartesianBasis &basis)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
MatBase< float, 3, 3 > float3x3
DefaultTextureList * viewport_texture_list_get() const
blender::gpu::Texture * depth
blender::gpu::Texture * color
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
static MatBase identity()