RNA: support compiling rna files as C++ code #108290
|
@ -2446,6 +2446,14 @@ def draw_pause(self, context):
|
|||
layout.prop(cscene, "preview_pause", icon='PLAY' if cscene.preview_pause else 'PAUSE', text="")
|
||||
|
||||
|
||||
def draw_make_links(self, context):
|
||||
if context.engine == "CYCLES":
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
layout.operator_menu_enum("object.light_linking_receivers_link", "link_state")
|
||||
layout.operator_menu_enum("object.light_linking_blockers_link", "link_state")
|
||||
|
||||
|
||||
def get_panels():
|
||||
exclude_panels = {
|
||||
'DATA_PT_camera_dof',
|
||||
|
@ -2584,6 +2592,7 @@ def register():
|
|||
|
||||
bpy.types.RENDER_PT_context.append(draw_device)
|
||||
bpy.types.VIEW3D_HT_header.append(draw_pause)
|
||||
bpy.types.VIEW3D_MT_make_links.append(draw_make_links)
|
||||
|
||||
for panel in get_panels():
|
||||
panel.COMPAT_ENGINES.add('CYCLES')
|
||||
|
@ -2597,6 +2606,7 @@ def unregister():
|
|||
|
||||
bpy.types.RENDER_PT_context.remove(draw_device)
|
||||
bpy.types.VIEW3D_HT_header.remove(draw_pause)
|
||||
bpy.types.VIEW3D_MT_make_links.remove(draw_make_links)
|
||||
|
||||
for panel in get_panels():
|
||||
if 'CYCLES' in panel.COMPAT_ENGINES:
|
||||
|
|
|
@ -49,7 +49,7 @@ ccl_device int shadow_linking_pick_mesh_intersection(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* Only record primitives that potentially have emission.
|
||||
* TODO: optimize with a dedicated ray visiblity flag, which could then also be
|
||||
* TODO: optimize with a dedicated ray visibility flag, which could then also be
|
||||
* used once lights are in the BVH as geometry? */
|
||||
const int shader = intersection_get_shader(kg, ¤t_isect);
|
||||
const int shader_flags = kernel_data_fetch(shaders, shader).flags;
|
||||
|
|
|
@ -483,12 +483,7 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg,
|
|||
if (!hit)
|
||||
break;
|
||||
|
||||
// TODO: Is the fetch needed here? The shade_surface simply reads isect->object.
|
||||
int hit_object = (projection_isect.object == OBJECT_NONE) ?
|
||||
kernel_data_fetch(prim_object, projection_isect.prim) :
|
||||
projection_isect.object;
|
||||
|
||||
if (hit_object == mv.object) {
|
||||
if (projection_isect.object == mv.object) {
|
||||
projection_success = true;
|
||||
break;
|
||||
}
|
||||
|
@ -778,9 +773,8 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
|
|||
/* Initialize throughput and evaluate receiver bsdf * |n.wo|. */
|
||||
surface_shader_bsdf_eval(kg, state, sd, wo, throughput, ls->shader);
|
||||
|
||||
/* Update light sample with new position / direct.ion
|
||||
* and keep pdf in vertex area measure */
|
||||
light_sample_update_position(kg, ls, vertices[vertex_count - 1].p);
|
||||
/* Update light sample with new position / direction and keep pdf in vertex area measure. */
|
||||
light_sample_update(kg, ls, vertices[vertex_count - 1].p);
|
||||
|
||||
/* Save state path bounce info in case a light path node is used in the refractive interface or
|
||||
* light shader graph. */
|
||||
|
|
|
@ -140,7 +140,9 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
|
|||
#endif
|
||||
|
||||
#ifdef __LIGHT_LINKING__
|
||||
if (!light_link_light_match(kg, light_link_receiver_forward(kg, state), lamp)) {
|
||||
if (!light_link_light_match(kg, light_link_receiver_forward(kg, state), lamp) &&
|
||||
!(path_flag & PATH_RAY_CAMERA))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "kernel/integrator/path_state.h"
|
||||
#include "kernel/integrator/shade_surface.h"
|
||||
|
||||
#include "kernel/light/distant.h"
|
||||
#include "kernel/light/light.h"
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
#include "kernel/integrator/shade_surface.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "kernel/film/denoising_passes.h"
|
||||
#include "kernel/film/light_passes.h"
|
||||
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
#include "kernel/integrator/mnee.h"
|
||||
|
||||
#include "kernel/integrator/guiding.h"
|
||||
|
@ -17,8 +19,6 @@
|
|||
#include "kernel/integrator/subsurface.h"
|
||||
#include "kernel/integrator/volume_stack.h"
|
||||
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_forceinline void integrate_surface_shader_setup(KernelGlobals kg,
|
||||
|
@ -113,14 +113,16 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
|
|||
ccl_global float *ccl_restrict
|
||||
render_buffer)
|
||||
{
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
|
||||
#ifdef __LIGHT_LINKING__
|
||||
if (!light_link_object_match(kg, light_link_receiver_forward(kg, state), sd->object)) {
|
||||
if (!light_link_object_match(kg, light_link_receiver_forward(kg, state), sd->object) &&
|
||||
!(path_flag & PATH_RAY_CAMERA))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
|
||||
#ifdef __SHADOW_LINKING__
|
||||
/* Indirect emission of shadow-linked emissive surfaces is done via shadow rays to dedicated
|
||||
* light sources. */
|
||||
|
@ -284,8 +286,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
|||
|
||||
const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
|
||||
|
||||
#ifdef __MNEE__
|
||||
int mnee_vertex_count = 0;
|
||||
#ifdef __MNEE__
|
||||
IF_KERNEL_FEATURE(MNEE)
|
||||
{
|
||||
if (ls.lamp != LAMP_NONE) {
|
||||
|
|
|
@ -347,9 +347,9 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight,
|
|||
return true;
|
||||
}
|
||||
|
||||
ccl_device_forceinline void area_light_update_position(const ccl_global KernelLight *klight,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
ccl_device_forceinline void area_light_mnee_sample_update(const ccl_global KernelLight *klight,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
{
|
||||
if (klight->area.tan_half_spread == 0) {
|
||||
/* Update position on the light to keep the direction fixed. */
|
||||
|
|
|
@ -311,7 +311,7 @@ ccl_device_forceinline int lights_intersect_impl(KernelGlobals kg,
|
|||
|
||||
#ifdef __LIGHT_LINKING__
|
||||
/* Light linking. */
|
||||
if (!light_link_light_match(kg, receiver_forward, lamp)) {
|
||||
if (!light_link_light_match(kg, receiver_forward, lamp) && !(path_flag & PATH_RAY_CAMERA)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
@ -484,23 +484,4 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Update light sample for changed new position, for MNEE. */
|
||||
|
||||
ccl_device_forceinline void light_update_position(KernelGlobals kg,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
{
|
||||
const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
|
||||
|
||||
if (ls->type == LIGHT_POINT) {
|
||||
point_light_update_position(klight, ls, P);
|
||||
}
|
||||
else if (ls->type == LIGHT_SPOT) {
|
||||
spot_light_update_position(klight, ls, P);
|
||||
}
|
||||
else if (ls->type == LIGHT_AREA) {
|
||||
area_light_update_position(klight, ls, P);
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -29,9 +29,6 @@ ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight,
|
|||
ls->Ng = -ls->D;
|
||||
|
||||
ls->eval_fac = M_1_PI_F * 0.25f * klight->spot.invarea;
|
||||
if (!in_volume_segment && ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float2 uv = map_to_sphere(ls->Ng);
|
||||
ls->u = uv.x;
|
||||
|
@ -40,9 +37,9 @@ ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight,
|
|||
return true;
|
||||
}
|
||||
|
||||
ccl_device_forceinline void point_light_update_position(const ccl_global KernelLight *klight,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
ccl_device_forceinline void point_light_mnee_sample_update(const ccl_global KernelLight *klight,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
{
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
ls->Ng = -ls->D;
|
||||
|
@ -53,6 +50,7 @@ ccl_device_forceinline void point_light_update_position(const ccl_global KernelL
|
|||
|
||||
float invarea = klight->spot.invarea;
|
||||
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
ls->pdf = invarea;
|
||||
}
|
||||
|
||||
|
@ -89,10 +87,6 @@ ccl_device_inline bool point_light_sample_from_intersection(
|
|||
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
|
||||
ls->pdf = invarea;
|
||||
|
||||
if (ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float2 uv = map_to_sphere(ls->Ng);
|
||||
ls->u = uv.x;
|
||||
ls->v = uv.y;
|
||||
|
|
|
@ -366,15 +366,26 @@ ccl_device bool light_sample_from_position(KernelGlobals kg,
|
|||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline void light_sample_update_position(KernelGlobals kg,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
/* Update light sample with new shading point position for MNEE. The position on the light is fixed
|
||||
* except for directional light. */
|
||||
ccl_device_forceinline void light_sample_update(KernelGlobals kg,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
{
|
||||
/* Update light sample for new shading point position, while keeping
|
||||
* position on the light fixed. */
|
||||
const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
|
||||
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
light_update_position(kg, ls, P);
|
||||
if (ls->type == LIGHT_POINT) {
|
||||
point_light_mnee_sample_update(klight, ls, P);
|
||||
}
|
||||
else if (ls->type == LIGHT_SPOT) {
|
||||
spot_light_mnee_sample_update(klight, ls, P);
|
||||
}
|
||||
else if (ls->type == LIGHT_AREA) {
|
||||
area_light_mnee_sample_update(klight, ls, P);
|
||||
}
|
||||
else {
|
||||
/* Keep previous values. */
|
||||
}
|
||||
|
||||
/* Re-apply already computed selection pdf. */
|
||||
ls->pdf *= ls->pdf_selection;
|
||||
|
|
|
@ -58,9 +58,9 @@ ccl_device_inline bool spot_light_sample(const ccl_global KernelLight *klight,
|
|||
return true;
|
||||
}
|
||||
|
||||
ccl_device_forceinline void spot_light_update_position(const ccl_global KernelLight *klight,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
ccl_device_forceinline void spot_light_mnee_sample_update(const ccl_global KernelLight *klight,
|
||||
ccl_private LightSample *ls,
|
||||
const float3 P)
|
||||
{
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
ls->Ng = -ls->D;
|
||||
|
@ -71,6 +71,7 @@ ccl_device_forceinline void spot_light_update_position(const ccl_global KernelLi
|
|||
|
||||
float invarea = klight->spot.invarea;
|
||||
ls->eval_fac = (0.25f * M_1_PI_F) * invarea;
|
||||
/* NOTE : preserve pdf in area measure. */
|
||||
ls->pdf = invarea;
|
||||
|
||||
/* spot light attenuation */
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
# define HAVE_MALLOC_STATS
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <malloc_np.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
# undef USE_MALLOC_USABLE_SIZE
|
||||
#elif defined(__APPLE__)
|
||||
# include <malloc/malloc.h>
|
||||
# define malloc_usable_size malloc_size
|
||||
|
|
|
@ -362,7 +362,14 @@ def load():
|
|||
use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu,
|
||||
use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie,
|
||||
use_gizmo_drag=(is_select_left and kc_prefs.gizmo_action == 'DRAG'),
|
||||
use_fallback_tool=True if is_select_left else (kc_prefs.rmb_action == 'FALLBACK_TOOL'),
|
||||
use_fallback_tool=True,
|
||||
use_fallback_tool_select_handled=(
|
||||
# LMB doesn't need additional selection fallback key-map items.
|
||||
False if is_select_left else
|
||||
# RMB is select and RMB must trigger the fallback tool.
|
||||
# Otherwise LMB activates the fallback tool and RMB always tweak-selects.
|
||||
(kc_prefs.rmb_action != 'FALLBACK_TOOL')
|
||||
),
|
||||
use_tweak_select_passthrough=(show_developer_ui and kc_prefs.use_tweak_select_passthrough),
|
||||
use_tweak_tool_lmb_interaction=(
|
||||
False if is_select_left else
|
||||
|
|
|
@ -52,6 +52,8 @@ class Params:
|
|||
"use_gizmo_drag",
|
||||
# Use the fallback tool instead of tweak for RMB select.
|
||||
"use_fallback_tool",
|
||||
# Selection actions are already accounted for, no need to add additional selection keys.
|
||||
"use_fallback_tool_select_handled",
|
||||
# Use pie menu for tab by default (swap 'Tab/Ctrl-Tab').
|
||||
"use_v3d_tab_menu",
|
||||
# Use extended pie menu for shading.
|
||||
|
@ -78,7 +80,7 @@ class Params:
|
|||
# The fallback tool is activated on the same button as selection.
|
||||
# Shorthand for: `(True if (select_mouse == 'LEFT') else self.use_fallback_tool)`
|
||||
"use_fallback_tool_select_mouse",
|
||||
# Shorthand for: `('CLICK' if self.use_fallback_tool and select_mouse == 'RIGHT' else self.select_mouse_value)`.
|
||||
# Shorthand for: `(self.select_mouse_value if self.use_fallback_tool_select_handled else 'CLICK')`.
|
||||
"select_mouse_value_fallback",
|
||||
# Shorthand for: `{"type": params.select_mouse, "value": 'CLICK_DRAG'}`.
|
||||
"select_tweak_event",
|
||||
|
@ -110,6 +112,7 @@ class Params:
|
|||
use_select_all_toggle=False,
|
||||
use_gizmo_drag=True,
|
||||
use_fallback_tool=False,
|
||||
use_fallback_tool_select_handled=True,
|
||||
use_tweak_select_passthrough=False,
|
||||
use_tweak_tool_lmb_interaction=False,
|
||||
use_v3d_tab_menu=False,
|
||||
|
@ -204,9 +207,17 @@ class Params:
|
|||
self.use_fallback_tool = use_fallback_tool
|
||||
|
||||
# Convenience variables:
|
||||
self.use_fallback_tool_select_mouse = True if (select_mouse == 'LEFT') else self.use_fallback_tool
|
||||
self.use_fallback_tool_select_handled = (
|
||||
True if (select_mouse == 'LEFT') else
|
||||
use_fallback_tool_select_handled
|
||||
)
|
||||
self.use_fallback_tool_select_mouse = (
|
||||
True if (select_mouse == 'LEFT') else
|
||||
(not self.use_fallback_tool_select_handled)
|
||||
)
|
||||
self.select_mouse_value_fallback = (
|
||||
'CLICK' if (self.use_fallback_tool and select_mouse == 'RIGHT') else self.select_mouse_value
|
||||
self.select_mouse_value if self.use_fallback_tool_select_handled else
|
||||
'CLICK'
|
||||
)
|
||||
self.select_tweak_event = {"type": self.select_mouse, "value": 'CLICK_DRAG'}
|
||||
self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS'
|
||||
|
@ -3571,7 +3582,7 @@ def km_grease_pencil(params):
|
|||
return keymap
|
||||
|
||||
|
||||
def _grease_pencil_selection(params, use_select_mouse=True):
|
||||
def _grease_pencil_selection(params, *, use_select_mouse=True):
|
||||
return [
|
||||
# Select all
|
||||
*_template_items_select_actions(params, "gpencil.select_all"),
|
||||
|
@ -3952,7 +3963,7 @@ def km_grease_pencil_stroke_sculpt_mode(params):
|
|||
|
||||
items.extend([
|
||||
# Selection
|
||||
*_grease_pencil_selection(params, use_select_mouse=(params.use_fallback_tool_select_mouse == False)),
|
||||
*_grease_pencil_selection(params, use_select_mouse=(not params.use_fallback_tool_select_mouse)),
|
||||
|
||||
# Brush strength
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True},
|
||||
|
@ -4303,7 +4314,7 @@ def km_grease_pencil_stroke_vertex_mode(params):
|
|||
|
||||
items.extend([
|
||||
# Selection
|
||||
*_grease_pencil_selection(params, use_select_mouse=(params.use_fallback_tool_select_mouse == False)),
|
||||
*_grease_pencil_selection(params, use_select_mouse=(not params.use_fallback_tool_select_mouse)),
|
||||
# Brush strength
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True},
|
||||
{"properties": [
|
||||
|
@ -6647,7 +6658,7 @@ def km_image_editor_tool_uv_select(params, *, fallback):
|
|||
{"items": [
|
||||
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
|
||||
params, "uv.select", "uv.cursor_set", fallback=fallback)),
|
||||
*([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else
|
||||
*([] if params.use_fallback_tool_select_handled else
|
||||
_template_uv_select(
|
||||
type=params.select_mouse,
|
||||
value=params.select_mouse_value,
|
||||
|
@ -6878,7 +6889,7 @@ def km_3d_view_tool_select(params, *, fallback):
|
|||
{"items": [
|
||||
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
|
||||
params, "view3d.select", "view3d.cursor3d", operator_props=operator_props, fallback=fallback)),
|
||||
*([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else
|
||||
*([] if params.use_fallback_tool_select_handled else
|
||||
_template_view3d_select(
|
||||
type=params.select_mouse,
|
||||
value=params.select_mouse_value,
|
||||
|
@ -7823,7 +7834,7 @@ def km_3d_view_tool_edit_gpencil_select(params, *, fallback):
|
|||
{"items": [
|
||||
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
|
||||
params, "gpencil.select", "view3d.cursor3d", fallback=fallback)),
|
||||
*([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else
|
||||
*([] if params.use_fallback_tool_select_handled else
|
||||
_template_view3d_gpencil_select(
|
||||
type=params.select_mouse,
|
||||
value=params.select_mouse_value,
|
||||
|
@ -8006,7 +8017,7 @@ def km_sequencer_editor_tool_generic_select(params, *, fallback):
|
|||
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
|
||||
params, "sequencer.select", "sequencer.cursor_set", cursor_prioritize=True, fallback=fallback)),
|
||||
|
||||
*([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else
|
||||
*([] if params.use_fallback_tool_select_handled else
|
||||
_template_sequencer_preview_select(
|
||||
type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)),
|
||||
# Ignored for preview.
|
||||
|
|
|
@ -3046,10 +3046,6 @@ class VIEW3D_MT_make_links(Menu):
|
|||
layout.operator("object.data_transfer")
|
||||
layout.operator("object.datalayout_transfer")
|
||||
|
||||
layout.separator()
|
||||
layout.operator_menu_enum("object.light_linking_receivers_link", "link_state")
|
||||
layout.operator_menu_enum("object.light_linking_blockers_link", "link_state")
|
||||
|
||||
|
||||
class VIEW3D_MT_brush_paint_modes(Menu):
|
||||
bl_label = "Enabled Modes"
|
||||
|
|
|
@ -28,6 +28,9 @@ typedef enum LightLinkingType {
|
|||
LIGHT_LINKING_BLOCKER,
|
||||
} LightLinkingType;
|
||||
|
||||
/* Free object's light_linking if it is not needed to hold any of collections. */
|
||||
void BKE_light_linking_free_if_empty(struct Object *object);
|
||||
|
||||
/* Get a collection of the given light linking type of the given object. */
|
||||
struct Collection *BKE_light_linking_collection_get(const struct Object *object,
|
||||
LightLinkingType link_type);
|
||||
|
|
|
@ -25,6 +25,15 @@
|
|||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
void BKE_light_linking_free_if_empty(Object *object)
|
||||
{
|
||||
if (object->light_linking->receiver_collection == nullptr &&
|
||||
object->light_linking->blocker_collection == nullptr)
|
||||
{
|
||||
MEM_SAFE_FREE(object->light_linking);
|
||||
}
|
||||
}
|
||||
|
||||
Collection *BKE_light_linking_collection_get(const Object *object,
|
||||
const LightLinkingType link_type)
|
||||
{
|
||||
|
@ -108,12 +117,7 @@ void BKE_light_linking_collection_assign_only(struct Object *object,
|
|||
id_us_plus(&new_collection->id);
|
||||
}
|
||||
|
||||
/* Free if empty. */
|
||||
if (object->light_linking->receiver_collection == nullptr &&
|
||||
object->light_linking->blocker_collection == nullptr)
|
||||
{
|
||||
MEM_SAFE_FREE(object->light_linking);
|
||||
}
|
||||
BKE_light_linking_free_if_empty(object);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,8 +186,11 @@ void BKE_light_linking_add_receiver_to_collection(Main *bmain,
|
|||
CollectionLightLinking *collection_light_linking = nullptr;
|
||||
|
||||
if (id_type == ID_OB) {
|
||||
collection_light_linking = light_linking_collection_add_object(
|
||||
bmain, collection, reinterpret_cast<Object *>(receiver));
|
||||
Object *object = reinterpret_cast<Object *>(receiver);
|
||||
if (!OB_TYPE_IS_GEOMETRY(object->type)) {
|
||||
return;
|
||||
}
|
||||
collection_light_linking = light_linking_collection_add_object(bmain, collection, object);
|
||||
}
|
||||
else if (id_type == ID_GR) {
|
||||
collection_light_linking = light_linking_collection_add_collection(
|
||||
|
@ -240,6 +247,10 @@ void BKE_light_linking_link_receiver_to_emitter(Main *bmain,
|
|||
const LightLinkingType link_type,
|
||||
const eCollectionLightLinkingState link_state)
|
||||
{
|
||||
if (!OB_TYPE_IS_GEOMETRY(receiver->type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection *collection = BKE_light_linking_collection_get(emitter, link_type);
|
||||
|
||||
if (!collection) {
|
||||
|
|
|
@ -1444,6 +1444,16 @@ static void sculptsession_free_pbvh(Object *object)
|
|||
ss->pbvh = nullptr;
|
||||
}
|
||||
|
||||
ss->vert_to_poly_offsets = {};
|
||||
ss->vert_to_poly_indices = {};
|
||||
ss->pmap = {};
|
||||
ss->edge_to_poly_offsets = {};
|
||||
ss->edge_to_poly_indices = {};
|
||||
ss->epmap = {};
|
||||
ss->vert_to_edge_offsets = {};
|
||||
ss->vert_to_edge_indices = {};
|
||||
ss->vemap = {};
|
||||
|
||||
MEM_SAFE_FREE(ss->preview_vert_list);
|
||||
ss->preview_vert_count = 0;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace blender::index_mask {
|
|||
* - The second most-significant bit is not used for indices so that #max_segment_size itself can
|
||||
* be stored in the #int16_t.
|
||||
* - The maximum number of indices in a segment is 16384, which is generally enough to make the
|
||||
* overhead per segment negilible when processing large index masks.
|
||||
* overhead per segment negligible when processing large index masks.
|
||||
* - A power of two is used for #max_segment_size, because that allows for faster construction of
|
||||
* index masks for index ranges.
|
||||
*/
|
||||
|
@ -335,7 +335,7 @@ class IndexMask : private IndexMaskData {
|
|||
*/
|
||||
void to_bits(MutableBitSpan r_bits) const;
|
||||
/**
|
||||
* Set the bools at indies inthe mask to true and all others to false.
|
||||
* Set the bools at indies in the mask to true and all others to false.
|
||||
*/
|
||||
void to_bools(MutableSpan<bool> r_bools) const;
|
||||
/**
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
*
|
||||
* Ideally this could be could be even closer to Python's enumerate(). We might get that in the
|
||||
* future with newer C++ versions.
|
||||
*
|
||||
* One other important feature is the as_span method. This method returns a Span<int64_t>
|
||||
* that contains the interval as individual numbers.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -325,22 +322,11 @@ class IndexRange {
|
|||
return IndexRange(start_ + n, size_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get read-only access to a memory buffer that contains the range as actual numbers.
|
||||
*/
|
||||
Span<int64_t> as_span() const;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
|
||||
{
|
||||
stream << "[" << range.start() << ", " << range.one_after_last() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::atomic<int64_t> s_current_array_size;
|
||||
static std::atomic<int64_t *> s_current_array;
|
||||
|
||||
Span<int64_t> as_span_internal() const;
|
||||
};
|
||||
|
||||
struct AlignedIndexRanges {
|
||||
|
|
|
@ -766,16 +766,4 @@ template<typename T> class MutableSpan {
|
|||
}
|
||||
};
|
||||
|
||||
/** This is defined here, because in `BLI_index_range.hh` `Span` is not yet defined. */
|
||||
inline Span<int64_t> IndexRange::as_span() const
|
||||
{
|
||||
const int64_t min_required_size = start_ + size_;
|
||||
const int64_t current_array_size = s_current_array_size.load(std::memory_order_acquire);
|
||||
const int64_t *current_array = s_current_array.load(std::memory_order_acquire);
|
||||
if (min_required_size <= current_array_size) {
|
||||
return Span<int64_t>(current_array + start_, size_);
|
||||
}
|
||||
return this->as_span_internal();
|
||||
}
|
||||
|
||||
} /* namespace blender */
|
||||
|
|
|
@ -10,40 +10,6 @@
|
|||
|
||||
namespace blender {
|
||||
|
||||
static RawVector<RawArray<int64_t, 0>> arrays;
|
||||
static std::mutex current_array_mutex;
|
||||
std::atomic<int64_t> IndexRange::s_current_array_size = 0;
|
||||
std::atomic<int64_t *> IndexRange::s_current_array = nullptr;
|
||||
|
||||
Span<int64_t> IndexRange::as_span_internal() const
|
||||
{
|
||||
int64_t min_required_size = start_ + size_;
|
||||
|
||||
std::lock_guard<std::mutex> lock(current_array_mutex);
|
||||
|
||||
/* Double checked lock. */
|
||||
if (min_required_size <= s_current_array_size) {
|
||||
return Span<int64_t>(s_current_array + start_, size_);
|
||||
}
|
||||
|
||||
/* Isolate, because a mutex is locked. */
|
||||
threading::isolate_task([&]() {
|
||||
int64_t new_size = std::max<int64_t>(1000, power_of_2_max_u(min_required_size));
|
||||
RawArray<int64_t, 0> new_array(new_size);
|
||||
threading::parallel_for(IndexRange(new_size), 4096, [&](const IndexRange range) {
|
||||
for (const int64_t i : range) {
|
||||
new_array[i] = i;
|
||||
}
|
||||
});
|
||||
arrays.append(std::move(new_array));
|
||||
|
||||
s_current_array.store(arrays.last().data(), std::memory_order_release);
|
||||
s_current_array_size.store(new_size, std::memory_order_release);
|
||||
});
|
||||
|
||||
return Span<int64_t>(s_current_array + start_, size_);
|
||||
}
|
||||
|
||||
AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment)
|
||||
{
|
||||
BLI_assert(is_power_of_2_i(alignment));
|
||||
|
|
|
@ -219,17 +219,6 @@ TEST(index_range, TakeBackLargeN)
|
|||
EXPECT_EQ(slice.size(), 4);
|
||||
}
|
||||
|
||||
TEST(index_range, AsSpan)
|
||||
{
|
||||
IndexRange range = IndexRange(4, 6);
|
||||
Span<int64_t> span = range.as_span();
|
||||
EXPECT_EQ(span.size(), 6);
|
||||
EXPECT_EQ(span[0], 4);
|
||||
EXPECT_EQ(span[1], 5);
|
||||
EXPECT_EQ(span[2], 6);
|
||||
EXPECT_EQ(span[3], 7);
|
||||
}
|
||||
|
||||
TEST(index_range, constexpr_)
|
||||
{
|
||||
constexpr IndexRange range = IndexRange(1, 1);
|
||||
|
|
|
@ -3984,7 +3984,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
|
||||
/* In case the current scene is a liboverride, while the ID pointer itself remains valid,
|
||||
* above update of liboverrides will have completely invalidated its old content, so the
|
||||
* current viewlayer needs to be searched for again. */
|
||||
* current view-layer needs to be searched for again. */
|
||||
if (bfd->cur_view_layer != nullptr) {
|
||||
bfd->cur_view_layer = BKE_view_layer_find(bfd->curscene, cur_view_layer_name.c_str());
|
||||
}
|
||||
|
|
|
@ -483,11 +483,18 @@ void Cache::eval_runtime_data(Object &object_eval) const
|
|||
runtime.shadow_set_membership = EmitterSetMembership::SET_MEMBERSHIP_ALL;
|
||||
}
|
||||
|
||||
const bool need_runtime = (memcmp(&runtime, &runtime_no_links, sizeof(runtime)) != 0);
|
||||
|
||||
/* Assign, allocating light linking on demand if needed. */
|
||||
if (object_eval.light_linking) {
|
||||
object_eval.light_linking->runtime = runtime;
|
||||
if (!need_runtime) {
|
||||
/* Note that this will only remove lazily allocated light_linking on the evaluated object,
|
||||
* as an empty light_linking is not allowed on the original object. */
|
||||
BKE_light_linking_free_if_empty(&object_eval);
|
||||
}
|
||||
}
|
||||
else if (memcmp(&runtime, &runtime_no_links, sizeof(runtime)) != 0) {
|
||||
else if (need_runtime) {
|
||||
object_eval.light_linking = MEM_cnew<LightLinking>(__func__);
|
||||
object_eval.light_linking->runtime = runtime;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ class EmitterData {
|
|||
static constexpr int MAX_COLLECTION_ID = 63;
|
||||
|
||||
/* Mask of a light linking collection this emitter uses in its configuration.
|
||||
* A single bit is set in this bitfield which corresponds to an identifier of a light linking
|
||||
* A single bit is set in this bit-field which corresponds to an identifier of a light linking
|
||||
* collection in the scene. */
|
||||
uint64_t collection_mask = 0;
|
||||
|
||||
|
@ -121,7 +121,7 @@ class EmitterDataMap {
|
|||
}
|
||||
|
||||
private:
|
||||
/* Get linked collection depending on whether this is emitter information os for light or shadow
|
||||
/* Get linked collection depending on whether this is emitter information for light or shadow
|
||||
* linking. */
|
||||
/* TODO(sergey): Check whether template specialization is preferred here. */
|
||||
inline const Collection *get_collection(const Object &emitter) const
|
||||
|
|
|
@ -32,9 +32,6 @@ void ObjectRuntimeBackup::init_from_object(Object *object)
|
|||
if (object->light_linking) {
|
||||
light_linking_runtime = object->light_linking->runtime;
|
||||
}
|
||||
else {
|
||||
memset(&light_linking_runtime, 0, sizeof(light_linking_runtime));
|
||||
}
|
||||
BKE_object_runtime_reset(object);
|
||||
/* Keep bbox (for now at least). */
|
||||
object->runtime.bb = runtime.bb;
|
||||
|
@ -128,8 +125,13 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
|
|||
}
|
||||
}
|
||||
|
||||
if (object->light_linking) {
|
||||
object->light_linking->runtime = light_linking_runtime;
|
||||
if (light_linking_runtime) {
|
||||
/* Lazily allocate light linking on the evaluated object for the cases when the object is only
|
||||
* a receiver or a blocker and does not need its own LightLinking on the original object. */
|
||||
if (!object->light_linking) {
|
||||
object->light_linking = MEM_cnew<LightLinking>(__func__);
|
||||
}
|
||||
object->light_linking->runtime = *light_linking_runtime;
|
||||
}
|
||||
|
||||
object->base_flag = base_flag;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "BLI_session_uuid.h"
|
||||
|
||||
#include "intern/depsgraph_type.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_modifier.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_pose.h"
|
||||
|
||||
|
@ -39,7 +40,7 @@ class ObjectRuntimeBackup {
|
|||
void restore_pose_channel_runtime_data(Object *object);
|
||||
|
||||
Object_Runtime runtime;
|
||||
LightLinkingRuntime light_linking_runtime;
|
||||
optional<LightLinkingRuntime> light_linking_runtime;
|
||||
short base_flag;
|
||||
unsigned short base_local_view_bits;
|
||||
Map<SessionUUID, ModifierDataBackup> modifier_runtime_data;
|
||||
|
|
|
@ -300,7 +300,7 @@ GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void)
|
|||
{
|
||||
if (e_data.probe_filter_visibility_sh == nullptr) {
|
||||
e_data.probe_filter_visibility_sh = DRW_shader_create_from_info_name(
|
||||
"eevee_legacy_probe_filter_visiblity");
|
||||
"eevee_legacy_probe_filter_visibility");
|
||||
}
|
||||
return e_data.probe_filter_visibility_sh;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_probe_filter_diffuse_hl2)
|
|||
.auto_resource_location(true);
|
||||
|
||||
/* EEVEE_shaders_probe_filter_visibility_sh_get */
|
||||
GPU_SHADER_CREATE_INFO(eevee_legacy_probe_filter_visiblity)
|
||||
GPU_SHADER_CREATE_INFO(eevee_legacy_probe_filter_visibility)
|
||||
.define("IRRADIANCE_HL2")
|
||||
.additional_info("eevee_legacy_irradiance_lib")
|
||||
.additional_info("draw_fullscreen")
|
||||
|
|
|
@ -203,7 +203,7 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
|
|||
matpass.sub_pass = nullptr;
|
||||
}
|
||||
else {
|
||||
ShaderKey shader_key(matpass.gpumat, geometry_type, pipeline_type);
|
||||
ShaderKey shader_key(matpass.gpumat, geometry_type, pipeline_type, blender_mat->blend_flag);
|
||||
|
||||
PassMain::Sub *shader_sub = shader_map_.lookup_or_add_cb(shader_key, [&]() {
|
||||
/* First time encountering this shader. Create a sub that will contain materials using it. */
|
||||
|
|
|
@ -108,7 +108,7 @@ static inline eMaterialGeometry to_material_geometry(const Object *ob)
|
|||
|
||||
/** Unique key to identify each material in the hash-map. */
|
||||
struct MaterialKey {
|
||||
Material *mat;
|
||||
::Material *mat;
|
||||
uint64_t options;
|
||||
|
||||
MaterialKey(::Material *mat_, eMaterialGeometry geometry, eMaterialPipeline surface_pipeline)
|
||||
|
@ -145,10 +145,14 @@ struct ShaderKey {
|
|||
GPUShader *shader;
|
||||
uint64_t options;
|
||||
|
||||
ShaderKey(GPUMaterial *gpumat, eMaterialGeometry geometry, eMaterialPipeline pipeline)
|
||||
ShaderKey(GPUMaterial *gpumat,
|
||||
eMaterialGeometry geometry,
|
||||
eMaterialPipeline pipeline,
|
||||
char blend_flags)
|
||||
{
|
||||
shader = GPU_material_get_shader(gpumat);
|
||||
options = shader_uuid_from_material_type(pipeline, geometry);
|
||||
options = blend_flags;
|
||||
options = (options << 6u) | shader_uuid_from_material_type(pipeline, geometry);
|
||||
options = (options << 16u) | shader_closure_bits_from_flag(gpumat);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,9 @@ namespace blender::draw::overlay {
|
|||
|
||||
class Background {
|
||||
private:
|
||||
const SelectionType selection_type_;
|
||||
|
||||
PassSimple bg_ps_ = {"Background"};
|
||||
|
||||
public:
|
||||
Background(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
void begin_sync(Resources &res, const State &state)
|
||||
{
|
||||
DRWState pass_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_BACKGROUND;
|
||||
|
|
|
@ -17,8 +17,6 @@ namespace blender::draw::overlay {
|
|||
|
||||
class Grid {
|
||||
private:
|
||||
const SelectionType selection_type_;
|
||||
|
||||
UniformBuffer<OVERLAY_GridData> data_;
|
||||
|
||||
PassSimple grid_ps_ = {"grid_ps_"};
|
||||
|
@ -32,8 +30,6 @@ class Grid {
|
|||
bool enabled_ = false;
|
||||
|
||||
public:
|
||||
Grid(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
void begin_sync(Resources &res, const State &state, const View &view)
|
||||
{
|
||||
this->update_ubo(state, view);
|
||||
|
|
|
@ -33,11 +33,11 @@ class Instance {
|
|||
State state;
|
||||
|
||||
/** Overlay types. */
|
||||
Background background = {selection_type_};
|
||||
Prepass prepass = {selection_type_};
|
||||
Background background;
|
||||
Prepass prepass;
|
||||
Metaballs metaballs = {selection_type_};
|
||||
Empties empties = {selection_type_};
|
||||
Grid grid = {selection_type_};
|
||||
Grid grid;
|
||||
|
||||
Instance(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
|
|
|
@ -15,14 +15,10 @@ namespace blender::draw::overlay {
|
|||
|
||||
class Prepass {
|
||||
private:
|
||||
const SelectionType selection_type_;
|
||||
|
||||
PassMain prepass_ps_ = {"prepass"};
|
||||
PassMain prepass_in_front_ps_ = {"prepass_in_front"};
|
||||
|
||||
public:
|
||||
Prepass(const SelectionType selection_type) : selection_type_(selection_type){};
|
||||
|
||||
void begin_sync(Resources &res, const State &state)
|
||||
{
|
||||
auto init_pass = [&](PassMain &pass) {
|
||||
|
|
|
@ -15,8 +15,9 @@ ShaderModule::ShaderPtr ShaderModule::selectable_shader(const char *create_info_
|
|||
/* TODO: This is what it should be like with all variations defined with create infos. */
|
||||
// std::string create_info_name = base_create_info;
|
||||
// create_info_name += SelectEngineT::shader_suffix;
|
||||
// create_info_name += ClippingEnabled ? "_clipped" : "";
|
||||
// create_info_name += clipping_enabled_ ? "_clipped" : "";
|
||||
// this->shader_ = GPU_shader_create_from_info_name(create_info_name.c_str());
|
||||
UNUSED_VARS(clipping_enabled_);
|
||||
|
||||
/* WORKAROUND: ... but for now, we have to patch the create info used by the old engine. */
|
||||
gpu::shader::ShaderCreateInfo info = *reinterpret_cast<const gpu::shader::ShaderCreateInfo *>(
|
||||
|
|
|
@ -122,10 +122,11 @@ void DofPass::init(const SceneState &scene_state)
|
|||
int2 half_res = scene_state.resolution / 2;
|
||||
half_res = {max_ii(half_res.x, 1), max_ii(half_res.y, 1)};
|
||||
|
||||
source_tx_.ensure_2d(GPU_RGBA16F, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3);
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
|
||||
source_tx_.ensure_2d(GPU_RGBA16F, half_res, usage, nullptr, 3);
|
||||
source_tx_.ensure_mip_views();
|
||||
source_tx_.filter_mode(true);
|
||||
coc_halfres_tx_.ensure_2d(GPU_RG8, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3);
|
||||
coc_halfres_tx_.ensure_2d(GPU_RG8, half_res, usage, nullptr, 3);
|
||||
coc_halfres_tx_.ensure_mip_views();
|
||||
coc_halfres_tx_.filter_mode(true);
|
||||
|
||||
|
|
|
@ -1180,7 +1180,7 @@ static void vertex_paint_init_session(Depsgraph *depsgraph,
|
|||
BKE_sculpt_toolsettings_data_ensure(scene);
|
||||
|
||||
BLI_assert(ob->sculpt == nullptr);
|
||||
ob->sculpt = (SculptSession *)MEM_callocN(sizeof(SculptSession), "sculpt session");
|
||||
ob->sculpt = MEM_new<SculptSession>(__func__);
|
||||
ob->sculpt->mode_type = object_mode;
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, true);
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ static void SCULPT_dynamic_topology_disable_ex(
|
|||
CustomData_free_layer_named(&me->pdata, ".sculpt_face_set", me->totpoly);
|
||||
me->face_sets_color_default = 1;
|
||||
|
||||
/* Sync the visibility to vertices manually as the pmap is still not initialized. */
|
||||
/* Sync the visibility to vertices manually as the `pmap` is still not initialized. */
|
||||
bool *hide_vert = (bool *)CustomData_get_layer_named_for_write(
|
||||
&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert);
|
||||
if (hide_vert != nullptr) {
|
||||
|
|
|
@ -3405,9 +3405,6 @@ static void draw_background_color(const SpaceNode &snode)
|
|||
|
||||
void node_draw_space(const bContext &C, ARegion ®ion)
|
||||
{
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
wmWindow *win = CTX_wm_window(&C);
|
||||
SpaceNode &snode = *CTX_wm_space_node(&C);
|
||||
View2D &v2d = region.v2d;
|
||||
|
|
|
@ -1155,6 +1155,7 @@ void ED_spacetype_node()
|
|||
art->cursor = node_cursor;
|
||||
art->event_cursor = true;
|
||||
art->clip_gizmo_events_by_ui = true;
|
||||
art->lock = 1;
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
|
|
|
@ -418,10 +418,6 @@ static void update_visible_columns(ListBase &columns, DataSource &data_source)
|
|||
|
||||
static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
|
||||
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
|
||||
sspreadsheet->runtime->cache.set_all_unused();
|
||||
spreadsheet_update_context(C);
|
||||
|
@ -518,9 +514,6 @@ static void spreadsheet_header_region_init(wmWindowManager * /*wm*/, ARegion *re
|
|||
|
||||
static void spreadsheet_header_region_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
spreadsheet_update_context(C);
|
||||
ED_region_header(C, region);
|
||||
}
|
||||
|
@ -574,9 +567,6 @@ static void spreadsheet_footer_region_init(wmWindowManager * /*wm*/, ARegion *re
|
|||
|
||||
static void spreadsheet_footer_region_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
|
||||
SpaceSpreadsheet_Runtime *runtime = sspreadsheet->runtime;
|
||||
std::stringstream ss;
|
||||
|
@ -641,9 +631,6 @@ static void spreadsheet_dataset_region_listener(const wmRegionListenerParams *pa
|
|||
|
||||
static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
spreadsheet_update_context(C);
|
||||
ED_region_panels(C, region);
|
||||
}
|
||||
|
@ -736,6 +723,7 @@ void ED_spacetype_spreadsheet()
|
|||
art = MEM_cnew<ARegionType>("spacetype spreadsheet region");
|
||||
art->regionid = RGN_TYPE_WINDOW;
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
|
||||
art->lock = 1;
|
||||
|
||||
art->init = spreadsheet_main_region_init;
|
||||
art->draw = spreadsheet_main_region_draw;
|
||||
|
@ -748,6 +736,7 @@ void ED_spacetype_spreadsheet()
|
|||
art->prefsizey = HEADERY;
|
||||
art->keymapflag = 0;
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
|
||||
art->lock = 1;
|
||||
|
||||
art->init = spreadsheet_header_region_init;
|
||||
art->draw = spreadsheet_header_region_draw;
|
||||
|
@ -761,6 +750,7 @@ void ED_spacetype_spreadsheet()
|
|||
art->prefsizey = HEADERY;
|
||||
art->keymapflag = 0;
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
|
||||
art->lock = 1;
|
||||
|
||||
art->init = spreadsheet_footer_region_init;
|
||||
art->draw = spreadsheet_footer_region_draw;
|
||||
|
@ -773,6 +763,7 @@ void ED_spacetype_spreadsheet()
|
|||
art->regionid = RGN_TYPE_UI;
|
||||
art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
|
||||
art->lock = 1;
|
||||
|
||||
art->init = spreadsheet_sidebar_init;
|
||||
art->layout = ED_region_panels_layout;
|
||||
|
@ -788,6 +779,7 @@ void ED_spacetype_spreadsheet()
|
|||
art->regionid = RGN_TYPE_TOOLS;
|
||||
art->prefsizex = 150 + V2D_SCROLL_WIDTH;
|
||||
art->keymapflag = ED_KEYMAP_UI;
|
||||
art->lock = 1;
|
||||
art->init = ED_region_panels_init;
|
||||
art->draw = spreadsheet_dataset_region_draw;
|
||||
art->listener = spreadsheet_dataset_region_listener;
|
||||
|
|
|
@ -768,6 +768,7 @@ void applyMouseInput(struct TransInfo *t,
|
|||
const int mval[2],
|
||||
float output[3]);
|
||||
void transform_input_update(TransInfo *t, const float fac);
|
||||
void transform_input_virtual_mval_reset(TransInfo *t);
|
||||
|
||||
void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
|
||||
void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]);
|
||||
|
|
|
@ -494,4 +494,18 @@ void transform_input_update(TransInfo *t, const float fac)
|
|||
}
|
||||
}
|
||||
|
||||
void transform_input_virtual_mval_reset(TransInfo *t)
|
||||
{
|
||||
MouseInput *mi = &t->mouse;
|
||||
if (ELEM(mi->apply, InputAngle, InputAngleSpring)) {
|
||||
struct InputAngle_Data *data = mi->data;
|
||||
data->angle = 0.0;
|
||||
data->mval_prev[0] = mi->imval[0];
|
||||
data->mval_prev[1] = mi->imval[1];
|
||||
}
|
||||
else {
|
||||
memset(&mi->virtual_mval, 0, sizeof(mi->virtual_mval));
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -420,28 +420,42 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
t->context = NULL;
|
||||
|
||||
/* Allow navigation while transforming. */
|
||||
if (t->vod && (exit_code & OPERATOR_PASS_THROUGH) && ED_view3d_navigation_do(C, t->vod, event)) {
|
||||
if (t->vod && (exit_code & OPERATOR_PASS_THROUGH)) {
|
||||
RegionView3D *rv3d = t->region->regiondata;
|
||||
if (rv3d->rflag & RV3D_NAVIGATING) {
|
||||
/* Do not update transform while navigating. This can be distracting. */
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
const bool is_navigating = (rv3d->rflag & RV3D_NAVIGATING) != 0;
|
||||
if (ED_view3d_navigation_do(C, t->vod, event)) {
|
||||
if (!is_navigating) {
|
||||
/* Navigation has started. */
|
||||
|
||||
if (t->modifiers & MOD_PRECISION) {
|
||||
/* WORKAROUND: Remove precision modification, it may have be unintentionally enabled. */
|
||||
t->modifiers &= ~MOD_PRECISION;
|
||||
t->mouse.precision = false;
|
||||
transform_input_virtual_mval_reset(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv3d->rflag & RV3D_NAVIGATING) {
|
||||
/* Navigation is running. */
|
||||
|
||||
/* Do not update transform while navigating. This can be distracting. */
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
{
|
||||
/* Navigation has ended. */
|
||||
|
||||
/* Make sure `t->mval` is up to date before calling #transformViewUpdate. */
|
||||
copy_v2_v2_int(t->mval, event->mval);
|
||||
|
||||
/* Call before #applyMouseInput. */
|
||||
tranformViewUpdate(t);
|
||||
|
||||
/* Mouse input is outdated. */
|
||||
applyMouseInput(t, &t->mouse, t->mval, t->values);
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->modifiers & MOD_PRECISION) {
|
||||
/* Remove Precision modifier, it may have be unintentionally enabled. */
|
||||
t->modifiers &= ~MOD_PRECISION;
|
||||
t->mouse.precision = 0;
|
||||
}
|
||||
|
||||
/* Make sure `t->mval` is up to date before calling #transformViewUpdate. */
|
||||
copy_v2_v2_int(t->mval, event->mval);
|
||||
|
||||
/* Call before #applyMouseInput. */
|
||||
tranformViewUpdate(t);
|
||||
|
||||
/* Mouse input is outdated. */
|
||||
applyMouseInput(t, &t->mouse, t->mval, t->values);
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
}
|
||||
|
||||
transformApply(C, t);
|
||||
|
|
|
@ -413,7 +413,8 @@ void split_edges(Mesh &mesh,
|
|||
});
|
||||
|
||||
/* Used for transferring attributes. */
|
||||
Vector<int> new_to_old_edges_map(IndexRange(new_edges.size()).as_span());
|
||||
Vector<int> new_to_old_edges_map(new_edges.size());
|
||||
std::iota(new_to_old_edges_map.begin(), new_to_old_edges_map.end(), 0);
|
||||
|
||||
/* Step 1: Split the edges. */
|
||||
|
||||
|
|
|
@ -1079,7 +1079,7 @@ typedef struct GPUPixelBuffer GPUPixelBuffer;
|
|||
/**
|
||||
* Creates a #GPUPixelBuffer object with \a byte_size worth of storage.
|
||||
*/
|
||||
GPUPixelBuffer *GPU_pixel_buffer_create(uint byte_size);
|
||||
GPUPixelBuffer *GPU_pixel_buffer_create(size_t byte_size);
|
||||
|
||||
/**
|
||||
* Free a #GPUPixelBuffer object.
|
||||
|
@ -1104,7 +1104,7 @@ void GPU_pixel_buffer_unmap(GPUPixelBuffer *pixel_buf);
|
|||
/**
|
||||
* Return size in bytes of the \a pix_buf .
|
||||
*/
|
||||
uint GPU_pixel_buffer_size(GPUPixelBuffer *pixel_buf);
|
||||
size_t GPU_pixel_buffer_size(GPUPixelBuffer *pixel_buf);
|
||||
|
||||
/**
|
||||
* Return the native handle of the \a pix_buf to use for graphic interoperability registration.
|
||||
|
|
|
@ -956,7 +956,7 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size)
|
|||
* Pixel buffer utility functions.
|
||||
* \{ */
|
||||
|
||||
GPUPixelBuffer *GPU_pixel_buffer_create(uint size)
|
||||
GPUPixelBuffer *GPU_pixel_buffer_create(size_t size)
|
||||
{
|
||||
/* Ensure buffer satisfies the alignment of 256 bytes for copying
|
||||
* data between buffers and textures. As specified in:
|
||||
|
@ -985,7 +985,7 @@ void GPU_pixel_buffer_unmap(GPUPixelBuffer *pix_buf)
|
|||
reinterpret_cast<PixelBuffer *>(pix_buf)->unmap();
|
||||
}
|
||||
|
||||
uint GPU_pixel_buffer_size(GPUPixelBuffer *pix_buf)
|
||||
size_t GPU_pixel_buffer_size(GPUPixelBuffer *pix_buf)
|
||||
{
|
||||
return reinterpret_cast<PixelBuffer *>(pix_buf)->get_size();
|
||||
}
|
||||
|
|
|
@ -336,16 +336,16 @@ static inline const Texture *unwrap(const GPUTexture *vert)
|
|||
/* GPU pixel Buffer. */
|
||||
class PixelBuffer {
|
||||
protected:
|
||||
uint size_ = 0;
|
||||
size_t size_ = 0;
|
||||
|
||||
public:
|
||||
PixelBuffer(uint size) : size_(size){};
|
||||
PixelBuffer(size_t size) : size_(size){};
|
||||
virtual ~PixelBuffer(){};
|
||||
|
||||
virtual void *map() = 0;
|
||||
virtual void unmap() = 0;
|
||||
virtual int64_t get_native_handle() = 0;
|
||||
virtual uint get_size() = 0;
|
||||
virtual size_t get_size() = 0;
|
||||
};
|
||||
|
||||
/* Syntactic sugar. */
|
||||
|
|
|
@ -828,7 +828,9 @@ void MTLComputeState::bind_compute_sampler(MTLSamplerBinding &sampler_binding,
|
|||
}
|
||||
}
|
||||
|
||||
void MTLRenderPassState::bind_vertex_buffer(id<MTLBuffer> buffer, uint buffer_offset, uint index)
|
||||
void MTLRenderPassState::bind_vertex_buffer(id<MTLBuffer> buffer,
|
||||
uint64_t buffer_offset,
|
||||
uint index)
|
||||
{
|
||||
BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS);
|
||||
BLI_assert(buffer_offset >= 0);
|
||||
|
@ -858,7 +860,9 @@ void MTLRenderPassState::bind_vertex_buffer(id<MTLBuffer> buffer, uint buffer_of
|
|||
}
|
||||
}
|
||||
|
||||
void MTLRenderPassState::bind_fragment_buffer(id<MTLBuffer> buffer, uint buffer_offset, uint index)
|
||||
void MTLRenderPassState::bind_fragment_buffer(id<MTLBuffer> buffer,
|
||||
uint64_t buffer_offset,
|
||||
uint index)
|
||||
{
|
||||
BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS);
|
||||
BLI_assert(buffer_offset >= 0);
|
||||
|
@ -889,7 +893,7 @@ void MTLRenderPassState::bind_fragment_buffer(id<MTLBuffer> buffer, uint buffer_
|
|||
}
|
||||
|
||||
void MTLComputeState::bind_compute_buffer(id<MTLBuffer> buffer,
|
||||
uint buffer_offset,
|
||||
uint64_t buffer_offset,
|
||||
uint index,
|
||||
bool writeable)
|
||||
{
|
||||
|
@ -924,7 +928,7 @@ void MTLComputeState::bind_compute_buffer(id<MTLBuffer> buffer,
|
|||
}
|
||||
}
|
||||
|
||||
void MTLRenderPassState::bind_vertex_bytes(void *bytes, uint length, uint index)
|
||||
void MTLRenderPassState::bind_vertex_bytes(void *bytes, uint64_t length, uint index)
|
||||
{
|
||||
/* Bytes always updated as source data may have changed. */
|
||||
BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS);
|
||||
|
@ -949,7 +953,7 @@ void MTLRenderPassState::bind_vertex_bytes(void *bytes, uint length, uint index)
|
|||
this->cached_vertex_buffer_bindings[index].offset = -1;
|
||||
}
|
||||
|
||||
void MTLRenderPassState::bind_fragment_bytes(void *bytes, uint length, uint index)
|
||||
void MTLRenderPassState::bind_fragment_bytes(void *bytes, uint64_t length, uint index)
|
||||
{
|
||||
/* Bytes always updated as source data may have changed. */
|
||||
BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS);
|
||||
|
@ -974,7 +978,7 @@ void MTLRenderPassState::bind_fragment_bytes(void *bytes, uint length, uint inde
|
|||
this->cached_fragment_buffer_bindings[index].offset = -1;
|
||||
}
|
||||
|
||||
void MTLComputeState::bind_compute_bytes(void *bytes, uint length, uint index)
|
||||
void MTLComputeState::bind_compute_bytes(void *bytes, uint64_t length, uint index)
|
||||
{
|
||||
/* Bytes always updated as source data may have changed. */
|
||||
BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS);
|
||||
|
|
|
@ -86,7 +86,7 @@ struct BufferBindingCached {
|
|||
* or an MTLBuffer. */
|
||||
bool is_bytes;
|
||||
id<MTLBuffer> metal_buffer;
|
||||
int offset;
|
||||
uint64_t offset;
|
||||
};
|
||||
|
||||
/* Caching of CommandEncoder textures bindings. */
|
||||
|
@ -144,10 +144,10 @@ class MTLRenderPassState {
|
|||
uint slot);
|
||||
|
||||
/* Buffer binding (RenderCommandEncoder). */
|
||||
void bind_vertex_buffer(id<MTLBuffer> buffer, uint buffer_offset, uint index);
|
||||
void bind_fragment_buffer(id<MTLBuffer> buffer, uint buffer_offset, uint index);
|
||||
void bind_vertex_bytes(void *bytes, uint length, uint index);
|
||||
void bind_fragment_bytes(void *bytes, uint length, uint index);
|
||||
void bind_vertex_buffer(id<MTLBuffer> buffer, uint64_t buffer_offset, uint index);
|
||||
void bind_fragment_buffer(id<MTLBuffer> buffer, uint64_t buffer_offset, uint index);
|
||||
void bind_vertex_bytes(void *bytes, uint64_t length, uint index);
|
||||
void bind_fragment_bytes(void *bytes, uint64_t length, uint index);
|
||||
};
|
||||
|
||||
/* Metal Context Compute Pass State -- Used to track active ComputeCommandEncoder state. */
|
||||
|
@ -182,10 +182,10 @@ class MTLComputeState {
|
|||
uint slot);
|
||||
/* Buffer binding (ComputeCommandEncoder). */
|
||||
void bind_compute_buffer(id<MTLBuffer> buffer,
|
||||
uint buffer_offset,
|
||||
uint64_t buffer_offset,
|
||||
uint index,
|
||||
bool writeable = false);
|
||||
void bind_compute_bytes(void *bytes, uint length, uint index);
|
||||
void bind_compute_bytes(void *bytes, uint64_t length, uint index);
|
||||
};
|
||||
|
||||
/* Depth Stencil State */
|
||||
|
|
|
@ -1148,7 +1148,7 @@ bool MTLContext::ensure_buffer_bindings(
|
|||
/* buffer(N) index of where to bind the UBO. */
|
||||
const uint32_t buffer_index = ubo.buffer_index;
|
||||
id<MTLBuffer> ubo_buffer = nil;
|
||||
int ubo_size = 0;
|
||||
size_t ubo_size = 0;
|
||||
|
||||
bool bind_dummy_buffer = false;
|
||||
if (this->pipeline_state.ubo_bindings[ubo_location].bound) {
|
||||
|
@ -1196,7 +1196,7 @@ bool MTLContext::ensure_buffer_bindings(
|
|||
if (ubo_size < expected_size) {
|
||||
MTL_LOG_UBO_ERROR(
|
||||
"[Error][UBO] UBO (UBO Name: %s) bound at location: %d (buffer[[%d]]) with size "
|
||||
"%d (Expected size "
|
||||
"%lu (Expected size "
|
||||
"%d) (Shader Name: %s) is too small -- binding NULL buffer. This is likely an "
|
||||
"over-binding, which is not used, but we need this to avoid validation "
|
||||
"issues\n",
|
||||
|
@ -1270,7 +1270,7 @@ bool MTLContext::ensure_buffer_bindings(
|
|||
/* buffer(N) index of where to bind the SSBO. */
|
||||
const uint32_t buffer_index = ssbo.buffer_index;
|
||||
id<MTLBuffer> ssbo_buffer = nil;
|
||||
int ssbo_size = 0;
|
||||
size_t ssbo_size = 0;
|
||||
UNUSED_VARS_NDEBUG(ssbo_size);
|
||||
|
||||
if (this->pipeline_state.ssbo_bindings[ssbo_location].bound) {
|
||||
|
@ -1378,7 +1378,7 @@ bool MTLContext::ensure_buffer_bindings(
|
|||
/* buffer(N) index of where to bind the UBO. */
|
||||
const uint32_t buffer_index = ubo.buffer_index;
|
||||
id<MTLBuffer> ubo_buffer = nil;
|
||||
int ubo_size = 0;
|
||||
size_t ubo_size = 0;
|
||||
|
||||
bool bind_dummy_buffer = false;
|
||||
if (this->pipeline_state.ubo_bindings[ubo_location].bound) {
|
||||
|
@ -1700,12 +1700,12 @@ void MTLContext::ensure_texture_bindings(
|
|||
}
|
||||
else {
|
||||
/* Populate argument buffer with current global sampler bindings. */
|
||||
int size = [argument_encoder encodedLength];
|
||||
int alignment = max_uu([argument_encoder alignment], 256);
|
||||
int size_align_delta = (size % alignment);
|
||||
int aligned_alloc_size = ((alignment > 1) && (size_align_delta > 0)) ?
|
||||
size + (alignment - (size % alignment)) :
|
||||
size;
|
||||
size_t size = [argument_encoder encodedLength];
|
||||
size_t alignment = max_uu([argument_encoder alignment], 256);
|
||||
size_t size_align_delta = (size % alignment);
|
||||
size_t aligned_alloc_size = ((alignment > 1) && (size_align_delta > 0)) ?
|
||||
size + (alignment - (size % alignment)) :
|
||||
size;
|
||||
|
||||
/* Allocate buffer to store encoded sampler arguments. */
|
||||
encoder_buffer = MTLContext::get_global_memory_manager()->allocate(aligned_alloc_size,
|
||||
|
@ -1921,12 +1921,12 @@ void MTLContext::ensure_texture_bindings(
|
|||
}
|
||||
else {
|
||||
/* Populate argument buffer with current global sampler bindings. */
|
||||
int size = [argument_encoder encodedLength];
|
||||
int alignment = max_uu([argument_encoder alignment], 256);
|
||||
int size_align_delta = (size % alignment);
|
||||
int aligned_alloc_size = ((alignment > 1) && (size_align_delta > 0)) ?
|
||||
size + (alignment - (size % alignment)) :
|
||||
size;
|
||||
size_t size = [argument_encoder encodedLength];
|
||||
size_t alignment = max_uu([argument_encoder alignment], 256);
|
||||
size_t size_align_delta = (size % alignment);
|
||||
size_t aligned_alloc_size = ((alignment > 1) && (size_align_delta > 0)) ?
|
||||
size + (alignment - (size % alignment)) :
|
||||
size;
|
||||
|
||||
/* Allocate buffer to store encoded sampler arguments. */
|
||||
encoder_buffer = MTLContext::get_global_memory_manager()->allocate(aligned_alloc_size,
|
||||
|
|
|
@ -494,7 +494,7 @@ void MTLFrameBuffer::read(eGPUFrameBufferBits planes,
|
|||
if (tex) {
|
||||
size_t sample_len = area[2] * area[3];
|
||||
size_t sample_size = to_bytesize(tex->format_, format);
|
||||
int debug_data_size = sample_len * sample_size;
|
||||
size_t debug_data_size = sample_len * sample_size;
|
||||
tex->read_internal(0,
|
||||
area[0],
|
||||
area[1],
|
||||
|
@ -523,7 +523,7 @@ void MTLFrameBuffer::read(eGPUFrameBufferBits planes,
|
|||
if (tex) {
|
||||
size_t sample_len = area[2] * area[3];
|
||||
size_t sample_size = to_bytesize(tex->format_, format);
|
||||
int debug_data_size = sample_len * sample_size * channel_len;
|
||||
size_t debug_data_size = sample_len * sample_size * channel_len;
|
||||
tex->read_internal(0,
|
||||
area[0],
|
||||
area[1],
|
||||
|
|
|
@ -322,7 +322,7 @@ void MTLImmediate::end()
|
|||
@autoreleasepool {
|
||||
|
||||
id<MTLBuffer> index_buffer_mtl = nil;
|
||||
uint32_t index_buffer_offset = 0;
|
||||
uint64_t index_buffer_offset = 0;
|
||||
|
||||
/* Region of scratch buffer used for topology emulation element data.
|
||||
* NOTE(Metal): We do not need to manually flush as the entire scratch
|
||||
|
|
|
@ -777,7 +777,7 @@ MTLTemporaryBuffer MTLCircularBuffer::allocate_range_aligned(uint64_t alloc_size
|
|||
|
||||
/* Ensure alignment of an allocation is aligned to compatible offset boundaries. */
|
||||
BLI_assert(alignment > 0);
|
||||
alignment = max_ulul(alignment, 256);
|
||||
alignment = max_uu(alignment, 256);
|
||||
|
||||
/* Align current offset and allocation size to desired alignment */
|
||||
uint64_t aligned_current_offset = ceil_to_multiple_ul(current_offset_, alignment);
|
||||
|
|
|
@ -71,7 +71,7 @@ class MTLStorageBuf : public StorageBuf {
|
|||
void init();
|
||||
|
||||
id<MTLBuffer> get_metal_buffer();
|
||||
int get_size();
|
||||
size_t get_size();
|
||||
const char *get_name()
|
||||
{
|
||||
return name_;
|
||||
|
|
|
@ -296,7 +296,7 @@ id<MTLBuffer> MTLStorageBuf::get_metal_buffer()
|
|||
return source_buffer->get_metal_buffer();
|
||||
}
|
||||
|
||||
int MTLStorageBuf::get_size()
|
||||
size_t MTLStorageBuf::get_size()
|
||||
{
|
||||
BLI_assert(this);
|
||||
return size_in_bytes_;
|
||||
|
|
|
@ -184,7 +184,7 @@ class MTLTexture : public Texture {
|
|||
|
||||
/* Texture Storage. */
|
||||
id<MTLBuffer> texture_buffer_ = nil;
|
||||
uint aligned_w_ = 0;
|
||||
size_t aligned_w_ = 0;
|
||||
|
||||
/* Blit Frame-buffer. */
|
||||
GPUFrameBuffer *blit_fb_ = nullptr;
|
||||
|
@ -313,7 +313,7 @@ class MTLTexture : public Texture {
|
|||
int depth,
|
||||
eGPUDataFormat desired_output_format,
|
||||
int num_output_components,
|
||||
int debug_data_size,
|
||||
size_t debug_data_size,
|
||||
void *r_data);
|
||||
void bake_mip_swizzle_view();
|
||||
|
||||
|
@ -452,7 +452,7 @@ class MTLPixelBuffer : public PixelBuffer {
|
|||
void *map() override;
|
||||
void unmap() override;
|
||||
int64_t get_native_handle() override;
|
||||
uint get_size() override;
|
||||
size_t get_size() override;
|
||||
|
||||
id<MTLBuffer> get_metal_buffer();
|
||||
|
||||
|
@ -461,7 +461,7 @@ class MTLPixelBuffer : public PixelBuffer {
|
|||
|
||||
/* Utility */
|
||||
MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format);
|
||||
int get_mtl_format_bytesize(MTLPixelFormat tex_format);
|
||||
size_t get_mtl_format_bytesize(MTLPixelFormat tex_format);
|
||||
int get_mtl_format_num_components(MTLPixelFormat tex_format);
|
||||
bool mtl_format_supports_blending(MTLPixelFormat format);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ gpu::MTLTexture::MTLTexture(const char *name,
|
|||
BLI_assert(metal_texture != nil);
|
||||
BLI_assert(type == GPU_TEXTURE_2D);
|
||||
type_ = type;
|
||||
init_2D(metal_texture.width, metal_texture.height, 0, 1, format);
|
||||
init_2D((int)metal_texture.width, (int)metal_texture.height, 0, 1, format);
|
||||
|
||||
/* Assign MTLTexture. */
|
||||
texture_ = metal_texture;
|
||||
|
@ -181,7 +181,7 @@ void gpu::MTLTexture::bake_mip_swizzle_view()
|
|||
MTLTextureType texture_view_texture_type = to_metal_type(type_);
|
||||
|
||||
int range_len = min_ii((mip_texture_max_level_ - mip_texture_base_level_) + 1,
|
||||
texture_.mipmapLevelCount - mip_texture_base_level_);
|
||||
(int)texture_.mipmapLevelCount - mip_texture_base_level_);
|
||||
BLI_assert(range_len > 0);
|
||||
BLI_assert(mip_texture_base_level_ < texture_.mipmapLevelCount);
|
||||
BLI_assert(mip_texture_base_layer_ < num_slices);
|
||||
|
@ -194,7 +194,7 @@ void gpu::MTLTexture::bake_mip_swizzle_view()
|
|||
MTL_LOG_INFO(
|
||||
"Updating texture view - MIP TEXTURE BASE LEVEL: %d, MAX LEVEL: %d (Range len: %d)\n",
|
||||
mip_texture_base_level_,
|
||||
min_ii(mip_texture_max_level_, texture_.mipmapLevelCount),
|
||||
min_ii(mip_texture_max_level_, (int)texture_.mipmapLevelCount),
|
||||
range_len);
|
||||
mip_swizzle_view_.label = [texture_ label];
|
||||
texture_view_dirty_flags_ = TEXTURE_VIEW_NOT_DIRTY;
|
||||
|
@ -493,25 +493,26 @@ void gpu::MTLTexture::update_sub(
|
|||
@autoreleasepool {
|
||||
/* Determine totalsize of INPUT Data. */
|
||||
int num_channels = to_component_len(format_);
|
||||
int input_bytes_per_pixel = to_bytesize(format_, type);
|
||||
int totalsize = 0;
|
||||
size_t input_bytes_per_pixel = to_bytesize(format_, type);
|
||||
size_t totalsize = 0;
|
||||
|
||||
/* If unpack row length is used, size of input data uses the unpack row length, rather than the
|
||||
* image length. */
|
||||
int expected_update_w = ((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
size_t expected_update_w = ((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
|
||||
/* Ensure calculated total size isn't larger than remaining image data size */
|
||||
switch (this->dimensions_count()) {
|
||||
case 1:
|
||||
totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1);
|
||||
totalsize = input_bytes_per_pixel * max_ulul(expected_update_w, 1);
|
||||
break;
|
||||
case 2:
|
||||
totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1) * extent[1];
|
||||
totalsize = input_bytes_per_pixel * max_ulul(expected_update_w, 1) * (size_t)extent[1];
|
||||
break;
|
||||
case 3:
|
||||
totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1) * extent[1] * extent[2];
|
||||
totalsize = input_bytes_per_pixel * max_ulul(expected_update_w, 1) * (size_t)extent[1] *
|
||||
(size_t)extent[2];
|
||||
break;
|
||||
default:
|
||||
BLI_assert(false);
|
||||
|
@ -543,7 +544,7 @@ void gpu::MTLTexture::update_sub(
|
|||
|
||||
/* Determine expected destination data size. */
|
||||
MTLPixelFormat destination_format = gpu_texture_format_to_metal(format_);
|
||||
int expected_dst_bytes_per_pixel = get_mtl_format_bytesize(destination_format);
|
||||
size_t expected_dst_bytes_per_pixel = get_mtl_format_bytesize(destination_format);
|
||||
int destination_num_channels = get_mtl_format_num_components(destination_format);
|
||||
|
||||
/* Prepare specialization struct (For texture update routine). */
|
||||
|
@ -588,8 +589,8 @@ void gpu::MTLTexture::update_sub(
|
|||
/* Debug and verification. */
|
||||
if (!can_use_direct_blit) {
|
||||
MTL_LOG_WARNING(
|
||||
"gpu::MTLTexture::update_sub supplied bpp is %d bytes (%d components per "
|
||||
"pixel), but backing texture bpp is %d bytes (%d components per pixel) "
|
||||
"gpu::MTLTexture::update_sub supplied bpp is %lu bytes (%d components per "
|
||||
"pixel), but backing texture bpp is %lu bytes (%d components per pixel) "
|
||||
"(TODO(Metal): Channel Conversion needed) (w: %d, h: %d, d: %d)\n",
|
||||
input_bytes_per_pixel,
|
||||
num_channels,
|
||||
|
@ -708,15 +709,15 @@ void gpu::MTLTexture::update_sub(
|
|||
case GPU_TEXTURE_1D_ARRAY: {
|
||||
if (can_use_direct_blit) {
|
||||
/* Use Blit based update. */
|
||||
int bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
int bytes_per_image = bytes_per_row;
|
||||
size_t bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
size_t bytes_per_image = bytes_per_row;
|
||||
int max_array_index = ((type_ == GPU_TEXTURE_1D_ARRAY) ? extent[1] : 1);
|
||||
for (int array_index = 0; array_index < max_array_index; array_index++) {
|
||||
|
||||
int buffer_array_offset = (bytes_per_image * array_index);
|
||||
size_t buffer_array_offset = (bytes_per_image * (size_t)array_index);
|
||||
[blit_encoder
|
||||
copyFromBuffer:staging_buffer
|
||||
sourceOffset:buffer_array_offset
|
||||
|
@ -780,13 +781,13 @@ void gpu::MTLTexture::update_sub(
|
|||
case GPU_TEXTURE_2D_ARRAY: {
|
||||
if (can_use_direct_blit) {
|
||||
/* Use Blit encoder update. */
|
||||
int bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
int bytes_per_image = bytes_per_row * extent[1];
|
||||
size_t bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
size_t bytes_per_image = bytes_per_row * extent[1];
|
||||
|
||||
int texture_array_relative_offset = 0;
|
||||
size_t texture_array_relative_offset = 0;
|
||||
int base_slice = (type_ == GPU_TEXTURE_2D_ARRAY) ? offset[2] : 0;
|
||||
int final_slice = base_slice + ((type_ == GPU_TEXTURE_2D_ARRAY) ? extent[2] : 1);
|
||||
|
||||
|
@ -861,11 +862,11 @@ void gpu::MTLTexture::update_sub(
|
|||
/* 3D */
|
||||
case GPU_TEXTURE_3D: {
|
||||
if (can_use_direct_blit) {
|
||||
int bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
int bytes_per_image = bytes_per_row * extent[1];
|
||||
size_t bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
size_t bytes_per_image = bytes_per_row * extent[1];
|
||||
[blit_encoder copyFromBuffer:staging_buffer
|
||||
sourceOffset:0
|
||||
sourceBytesPerRow:bytes_per_row
|
||||
|
@ -902,13 +903,12 @@ void gpu::MTLTexture::update_sub(
|
|||
/* CUBE */
|
||||
case GPU_TEXTURE_CUBE: {
|
||||
if (can_use_direct_blit) {
|
||||
int bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
int bytes_per_image = bytes_per_row * extent[1];
|
||||
|
||||
int texture_array_relative_offset = 0;
|
||||
size_t bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
size_t bytes_per_image = bytes_per_row * extent[1];
|
||||
size_t texture_array_relative_offset = 0;
|
||||
|
||||
/* Iterate over all cube faces in range (offset[2], offset[2] + extent[2]). */
|
||||
for (int i = 0; i < extent[2]; i++) {
|
||||
|
@ -938,14 +938,14 @@ void gpu::MTLTexture::update_sub(
|
|||
case GPU_TEXTURE_CUBE_ARRAY: {
|
||||
if (can_use_direct_blit) {
|
||||
|
||||
int bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
int bytes_per_image = bytes_per_row * extent[1];
|
||||
size_t bytes_per_row = expected_dst_bytes_per_pixel *
|
||||
((ctx->pipeline_state.unpack_row_length == 0) ?
|
||||
extent[0] :
|
||||
ctx->pipeline_state.unpack_row_length);
|
||||
size_t bytes_per_image = bytes_per_row * extent[1];
|
||||
|
||||
/* Upload to all faces between offset[2] (which is zero in most cases) AND extent[2]. */
|
||||
int texture_array_relative_offset = 0;
|
||||
size_t texture_array_relative_offset = 0;
|
||||
for (int i = 0; i < extent[2]; i++) {
|
||||
int face_index = offset[2] + i;
|
||||
[blit_encoder copyFromBuffer:staging_buffer
|
||||
|
@ -1112,9 +1112,9 @@ void MTLTexture::update_sub(int offset[3],
|
|||
/* Calculate dimensions. */
|
||||
int num_image_channels = to_component_len(format_);
|
||||
|
||||
uint bits_per_pixel = num_image_channels * to_bytesize(format);
|
||||
uint bytes_per_row = bits_per_pixel * extent[0];
|
||||
uint bytes_per_image = bytes_per_row * extent[1];
|
||||
size_t bits_per_pixel = num_image_channels * to_bytesize(format);
|
||||
size_t bytes_per_row = bits_per_pixel * extent[0];
|
||||
size_t bytes_per_image = bytes_per_row * extent[1];
|
||||
|
||||
/* Currently only required for 2D textures. */
|
||||
if (type_ == GPU_TEXTURE_2D) {
|
||||
|
@ -1414,7 +1414,7 @@ void gpu::MTLTexture::read_internal(int mip,
|
|||
int depth,
|
||||
eGPUDataFormat desired_output_format,
|
||||
int num_output_components,
|
||||
int debug_data_size,
|
||||
size_t debug_data_size,
|
||||
void *r_data)
|
||||
{
|
||||
/* Verify textures are baked. */
|
||||
|
@ -1429,10 +1429,10 @@ void gpu::MTLTexture::read_internal(int mip,
|
|||
/* Calculate Desired output size. */
|
||||
int num_channels = to_component_len(format_);
|
||||
BLI_assert(num_output_components <= num_channels);
|
||||
uint desired_output_bpp = num_output_components * to_bytesize(desired_output_format);
|
||||
size_t desired_output_bpp = num_output_components * to_bytesize(desired_output_format);
|
||||
|
||||
/* Calculate Metal data output for trivial copy. */
|
||||
uint image_bpp = get_mtl_format_bytesize(texture_.pixelFormat);
|
||||
size_t image_bpp = get_mtl_format_bytesize(texture_.pixelFormat);
|
||||
uint image_components = get_mtl_format_num_components(texture_.pixelFormat);
|
||||
bool is_depth_format = (format_flag_ & GPU_FORMAT_DEPTH);
|
||||
|
||||
|
@ -1470,9 +1470,9 @@ void gpu::MTLTexture::read_internal(int mip,
|
|||
}
|
||||
|
||||
/* Determine size of output data. */
|
||||
uint bytes_per_row = desired_output_bpp * width;
|
||||
uint bytes_per_image = bytes_per_row * height;
|
||||
uint total_bytes = bytes_per_image * depth;
|
||||
size_t bytes_per_row = desired_output_bpp * width;
|
||||
size_t bytes_per_image = bytes_per_row * height;
|
||||
size_t total_bytes = bytes_per_image * depth;
|
||||
|
||||
if (can_use_simple_read) {
|
||||
/* DEBUG check that if direct copy is being used, then both the expected output size matches
|
||||
|
@ -1589,7 +1589,7 @@ void gpu::MTLTexture::read_internal(int mip,
|
|||
}
|
||||
int base_slice = z_off;
|
||||
int final_slice = base_slice + depth;
|
||||
int texture_array_relative_offset = 0;
|
||||
size_t texture_array_relative_offset = 0;
|
||||
|
||||
for (int array_slice = base_slice; array_slice < final_slice; array_slice++) {
|
||||
[enc copyFromTexture:read_texture
|
||||
|
@ -1639,7 +1639,7 @@ void gpu::MTLTexture::read_internal(int mip,
|
|||
}
|
||||
int base_slice = z_off;
|
||||
int final_slice = base_slice + depth;
|
||||
int texture_array_relative_offset = 0;
|
||||
size_t texture_array_relative_offset = 0;
|
||||
|
||||
for (int array_slice = base_slice; array_slice < final_slice; array_slice++) {
|
||||
[enc copyFromTexture:read_texture
|
||||
|
@ -1686,12 +1686,12 @@ void gpu::MTLTexture::read_internal(int mip,
|
|||
|
||||
/* Copy data from Shared Memory into ptr. */
|
||||
memcpy(r_data, destination_buffer_host_ptr, total_bytes);
|
||||
MTL_LOG_INFO("gpu::MTLTexture::read_internal success! %d bytes read\n", total_bytes);
|
||||
MTL_LOG_INFO("gpu::MTLTexture::read_internal success! %lu bytes read\n", total_bytes);
|
||||
}
|
||||
else {
|
||||
MTL_LOG_WARNING(
|
||||
"[Warning] gpu::MTLTexture::read_internal not yet supported for this config -- data "
|
||||
"format different (src %d bytes, dst %d bytes) (src format: %d, dst format: %d), or "
|
||||
"format different (src %lu bytes, dst %lu bytes) (src format: %d, dst format: %d), or "
|
||||
"varying component counts (src %d, dst %d)\n",
|
||||
image_bpp,
|
||||
desired_output_bpp,
|
||||
|
@ -1752,8 +1752,8 @@ bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo)
|
|||
|
||||
/* Verify Texture and vertex buffer alignment. */
|
||||
const GPUVertFormat *format = GPU_vertbuf_get_format(vbo);
|
||||
int bytes_per_pixel = get_mtl_format_bytesize(mtl_format);
|
||||
int bytes_per_row = bytes_per_pixel * w_;
|
||||
size_t bytes_per_pixel = get_mtl_format_bytesize(mtl_format);
|
||||
size_t bytes_per_row = bytes_per_pixel * w_;
|
||||
|
||||
MTLContext *mtl_ctx = MTLContext::get();
|
||||
uint32_t align_requirement = static_cast<uint32_t>(
|
||||
|
@ -1815,7 +1815,7 @@ bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo)
|
|||
texture_ = [source_buffer
|
||||
newTextureWithDescriptor:texture_descriptor_
|
||||
offset:0
|
||||
bytesPerRow:ceil_to_multiple_u(bytes_per_row, align_requirement)];
|
||||
bytesPerRow:ceil_to_multiple_ul(bytes_per_row, align_requirement)];
|
||||
aligned_w_ = bytes_per_row / bytes_per_pixel;
|
||||
|
||||
BLI_assert(texture_);
|
||||
|
@ -2190,7 +2190,7 @@ int64_t MTLPixelBuffer::get_native_handle()
|
|||
return reinterpret_cast<int64_t>(buffer_);
|
||||
}
|
||||
|
||||
uint MTLPixelBuffer::get_size()
|
||||
size_t MTLPixelBuffer::get_size()
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format)
|
|||
return MTLPixelFormatRGBA8Unorm;
|
||||
}
|
||||
|
||||
int get_mtl_format_bytesize(MTLPixelFormat tex_format)
|
||||
size_t get_mtl_format_bytesize(MTLPixelFormat tex_format)
|
||||
{
|
||||
switch (tex_format) {
|
||||
case MTLPixelFormatRGBA8Uint:
|
||||
|
|
|
@ -47,7 +47,7 @@ class MTLUniformBuf : public UniformBuf {
|
|||
void clear_to_zero() override;
|
||||
|
||||
id<MTLBuffer> get_metal_buffer();
|
||||
int get_size();
|
||||
size_t get_size();
|
||||
const char *get_name()
|
||||
{
|
||||
return name_;
|
||||
|
|
|
@ -190,7 +190,7 @@ id<MTLBuffer> MTLUniformBuf::get_metal_buffer()
|
|||
return nil;
|
||||
}
|
||||
|
||||
int MTLUniformBuf::get_size()
|
||||
size_t MTLUniformBuf::get_size()
|
||||
{
|
||||
BLI_assert(this);
|
||||
return size_in_bytes_;
|
||||
|
|
|
@ -75,7 +75,7 @@ void MTLVertBuf::duplicate_data(VertBuf *dst_)
|
|||
BLI_assert(dst->vbo_ == nullptr);
|
||||
|
||||
/* Allocate VBO for destination vertbuf. */
|
||||
uint length = src->vbo_->get_size();
|
||||
uint64_t length = src->vbo_->get_size();
|
||||
dst->vbo_ = MTLContext::get_global_memory_manager()->allocate(
|
||||
length, (dst->get_usage_type() != GPU_USAGE_DEVICE_ONLY));
|
||||
dst->alloc_size_ = length;
|
||||
|
@ -225,7 +225,7 @@ void MTLVertBuf::bind()
|
|||
sourceOffset:0
|
||||
toBuffer:copy_new_buffer
|
||||
destinationOffset:0
|
||||
size:min_ii([copy_new_buffer length], [copy_prev_buffer length])];
|
||||
size:min_ulul([copy_new_buffer length], [copy_prev_buffer length])];
|
||||
|
||||
/* Flush newly copied data back to host-side buffer, if one exists.
|
||||
* Ensures data and cache coherency for managed MTLBuffers. */
|
||||
|
@ -274,7 +274,7 @@ void MTLVertBuf::update_sub(uint start, uint len, const void *data)
|
|||
[scratch_allocation.metal_buffer
|
||||
didModifyRange:NSMakeRange(scratch_allocation.buffer_offset, len)];
|
||||
id<MTLBuffer> data_buffer = scratch_allocation.metal_buffer;
|
||||
uint data_buffer_offset = scratch_allocation.buffer_offset;
|
||||
uint64_t data_buffer_offset = scratch_allocation.buffer_offset;
|
||||
|
||||
BLI_assert(vbo_ != nullptr && data != nullptr);
|
||||
BLI_assert((start + len) <= vbo_->get_size());
|
||||
|
|
|
@ -891,7 +891,7 @@ int64_t GLPixelBuffer::get_native_handle()
|
|||
return int64_t(gl_id_);
|
||||
}
|
||||
|
||||
uint GLPixelBuffer::get_size()
|
||||
size_t GLPixelBuffer::get_size()
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ class GLPixelBuffer : public PixelBuffer {
|
|||
void *map() override;
|
||||
void unmap() override;
|
||||
int64_t get_native_handle() override;
|
||||
uint get_size() override;
|
||||
size_t get_size() override;
|
||||
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("GLPixelBuffer")
|
||||
};
|
||||
|
|
|
@ -26,29 +26,53 @@
|
|||
|
||||
namespace blender::gpu {
|
||||
|
||||
void VKBackend::init_platform()
|
||||
static eGPUOSType determine_os_type()
|
||||
{
|
||||
BLI_assert(!GPG.initialized);
|
||||
#ifdef _WIN32
|
||||
return GPU_OS_WIN;
|
||||
#elif defined(__APPLE__)
|
||||
return GPU_OS_MAC;
|
||||
#else
|
||||
return GPU_OS_UNIX;
|
||||
#endif
|
||||
}
|
||||
|
||||
eGPUDeviceType device = GPU_DEVICE_ANY;
|
||||
eGPUOSType os = GPU_OS_ANY;
|
||||
void VKBackend::platform_init()
|
||||
{
|
||||
GPG.init(GPU_DEVICE_ANY,
|
||||
determine_os_type(),
|
||||
GPU_DRIVER_ANY,
|
||||
GPU_SUPPORT_LEVEL_SUPPORTED,
|
||||
GPU_BACKEND_VULKAN,
|
||||
"",
|
||||
"",
|
||||
"");
|
||||
}
|
||||
|
||||
void VKBackend::platform_init(const VKDevice &device)
|
||||
{
|
||||
const VkPhysicalDeviceProperties &properties = device.physical_device_properties_get();
|
||||
|
||||
eGPUDeviceType device_type = device.device_type();
|
||||
eGPUOSType os = determine_os_type();
|
||||
eGPUDriverType driver = GPU_DRIVER_ANY;
|
||||
eGPUSupportLevel support_level = GPU_SUPPORT_LEVEL_SUPPORTED;
|
||||
|
||||
#ifdef _WIN32
|
||||
os = GPU_OS_WIN;
|
||||
#elif defined(__APPLE__)
|
||||
os = GPU_OS_MAC;
|
||||
#else
|
||||
os = GPU_OS_UNIX;
|
||||
#endif
|
||||
std::string vendor_name = device.vendor_name();
|
||||
std::string driver_version = device.driver_version();
|
||||
|
||||
GPG.init(device, os, driver, support_level, GPU_BACKEND_VULKAN, "", "", "");
|
||||
GPG.init(device_type,
|
||||
os,
|
||||
driver,
|
||||
support_level,
|
||||
GPU_BACKEND_VULKAN,
|
||||
vendor_name.c_str(),
|
||||
properties.deviceName,
|
||||
driver_version.c_str());
|
||||
}
|
||||
|
||||
void VKBackend::platform_exit()
|
||||
{
|
||||
BLI_assert(GPG.initialized);
|
||||
GPG.clear();
|
||||
}
|
||||
|
||||
|
@ -147,10 +171,10 @@ shaderc::Compiler &VKBackend::get_shaderc_compiler()
|
|||
return shaderc_compiler_;
|
||||
}
|
||||
|
||||
void VKBackend::capabilities_init()
|
||||
void VKBackend::capabilities_init(const VKDevice &device)
|
||||
{
|
||||
const VkPhysicalDeviceLimits &limits =
|
||||
VKBackend::get().device_get().physical_device_limits_get();
|
||||
const VkPhysicalDeviceProperties &properties = device.physical_device_properties_get();
|
||||
const VkPhysicalDeviceLimits &limits = properties.limits;
|
||||
|
||||
/* Reset all capabilities from previous context. */
|
||||
GCaps = {};
|
||||
|
|
|
@ -36,7 +36,7 @@ class VKBackend : public GPUBackend {
|
|||
public:
|
||||
VKBackend()
|
||||
{
|
||||
VKBackend::init_platform();
|
||||
platform_init();
|
||||
}
|
||||
|
||||
virtual ~VKBackend()
|
||||
|
@ -76,8 +76,6 @@ class VKBackend : public GPUBackend {
|
|||
|
||||
shaderc::Compiler &get_shaderc_compiler();
|
||||
|
||||
static void capabilities_init();
|
||||
|
||||
static VKBackend &get()
|
||||
{
|
||||
return *static_cast<VKBackend *>(GPUBackend::get());
|
||||
|
@ -88,8 +86,11 @@ class VKBackend : public GPUBackend {
|
|||
return device_;
|
||||
}
|
||||
|
||||
static void platform_init(const VKDevice &device);
|
||||
static void capabilities_init(const VKDevice &device);
|
||||
|
||||
private:
|
||||
static void init_platform();
|
||||
static void platform_init();
|
||||
static void platform_exit();
|
||||
|
||||
/* These classes are allowed to modify the global device. */
|
||||
|
|
|
@ -24,7 +24,7 @@ void VKDevice::deinit()
|
|||
vk_device_ = VK_NULL_HANDLE;
|
||||
vk_queue_family_ = 0;
|
||||
vk_queue_ = VK_NULL_HANDLE;
|
||||
vk_physical_device_limits_ = {};
|
||||
vk_physical_device_properties_ = {};
|
||||
}
|
||||
|
||||
bool VKDevice::is_initialized() const
|
||||
|
@ -42,8 +42,9 @@ void VKDevice::init(void *ghost_context)
|
|||
&vk_queue_family_,
|
||||
&vk_queue_);
|
||||
|
||||
init_physical_device_limits();
|
||||
init_capabilities();
|
||||
init_physical_device_properties();
|
||||
VKBackend::platform_init(*this);
|
||||
VKBackend::capabilities_init(*this);
|
||||
init_debug_callbacks();
|
||||
init_memory_allocator();
|
||||
init_descriptor_pools();
|
||||
|
@ -57,17 +58,10 @@ void VKDevice::init_debug_callbacks()
|
|||
debugging_tools_.init(vk_instance_);
|
||||
}
|
||||
|
||||
void VKDevice::init_physical_device_limits()
|
||||
void VKDevice::init_physical_device_properties()
|
||||
{
|
||||
BLI_assert(vk_physical_device_ != VK_NULL_HANDLE);
|
||||
VkPhysicalDeviceProperties properties = {};
|
||||
vkGetPhysicalDeviceProperties(vk_physical_device_, &properties);
|
||||
vk_physical_device_limits_ = properties.limits;
|
||||
}
|
||||
|
||||
void VKDevice::init_capabilities()
|
||||
{
|
||||
VKBackend::capabilities_init();
|
||||
vkGetPhysicalDeviceProperties(vk_physical_device_, &vk_physical_device_properties_);
|
||||
}
|
||||
|
||||
void VKDevice::init_memory_allocator()
|
||||
|
@ -87,4 +81,98 @@ void VKDevice::init_descriptor_pools()
|
|||
descriptor_pools_.init(vk_device_);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Platform/driver/device information
|
||||
* \{ */
|
||||
|
||||
constexpr int32_t PCI_ID_NVIDIA = 0x10de;
|
||||
constexpr int32_t PCI_ID_INTEL = 0x8086;
|
||||
constexpr int32_t PCI_ID_AMD = 0x1022;
|
||||
|
||||
eGPUDeviceType VKDevice::device_type() const
|
||||
{
|
||||
/* According to the vulkan specifications:
|
||||
*
|
||||
* If the vendor has a PCI vendor ID, the low 16 bits of vendorID must contain that PCI vendor
|
||||
* ID, and the remaining bits must be set to zero. Otherwise, the value returned must be a valid
|
||||
* Khronos vendor ID.
|
||||
*/
|
||||
switch (vk_physical_device_properties_.vendorID) {
|
||||
case PCI_ID_NVIDIA:
|
||||
return GPU_DEVICE_NVIDIA;
|
||||
case PCI_ID_INTEL:
|
||||
return GPU_DEVICE_INTEL;
|
||||
case PCI_ID_AMD:
|
||||
return GPU_DEVICE_ATI;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GPU_DEVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
eGPUDriverType VKDevice::driver_type() const
|
||||
{
|
||||
/* It is unclear how to determine the driver type, but it is required to extract the correct
|
||||
* driver version. */
|
||||
return GPU_DRIVER_ANY;
|
||||
}
|
||||
|
||||
std::string VKDevice::vendor_name() const
|
||||
{
|
||||
/* Below 0x10000 are the PCI vendor IDs (https://pcisig.com/membership/member-companies) */
|
||||
if (vk_physical_device_properties_.vendorID < 0x10000) {
|
||||
switch (vk_physical_device_properties_.vendorID) {
|
||||
case 0x1022:
|
||||
return "Advanced Micro Devices";
|
||||
case 0x10DE:
|
||||
return "NVIDIA Corporation";
|
||||
case 0x8086:
|
||||
return "Intel Corporation";
|
||||
default:
|
||||
return std::to_string(vk_physical_device_properties_.vendorID);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* above 0x10000 should be vkVendorIDs
|
||||
* NOTE: When debug_messaging landed we can use something similar to
|
||||
* vk::to_string(vk::VendorId(properties.vendorID));
|
||||
*/
|
||||
return std::to_string(vk_physical_device_properties_.vendorID);
|
||||
}
|
||||
}
|
||||
|
||||
std::string VKDevice::driver_version() const
|
||||
{
|
||||
/*
|
||||
* NOTE: this depends on the driver type and is currently incorrect. Idea is to use a default per
|
||||
* OS.
|
||||
*/
|
||||
const uint32_t driver_version = vk_physical_device_properties_.driverVersion;
|
||||
switch (vk_physical_device_properties_.vendorID) {
|
||||
case PCI_ID_NVIDIA:
|
||||
return std::to_string((driver_version >> 22) & 0x3FF) + "." +
|
||||
std::to_string((driver_version >> 14) & 0xFF) + "." +
|
||||
std::to_string((driver_version >> 6) & 0xFF) + "." +
|
||||
std::to_string(driver_version & 0x3F);
|
||||
case PCI_ID_INTEL: {
|
||||
const uint32_t major = VK_VERSION_MAJOR(driver_version);
|
||||
/* When using Mesa driver we should use VK_VERSION_*. */
|
||||
if (major > 30) {
|
||||
return std::to_string((driver_version >> 14) & 0x3FFFF) + "." +
|
||||
std::to_string((driver_version & 0x3FFF));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return std::to_string(VK_VERSION_MAJOR(driver_version)) + "." +
|
||||
std::to_string(VK_VERSION_MINOR(driver_version)) + "." +
|
||||
std::to_string(VK_VERSION_PATCH(driver_version));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -29,7 +29,7 @@ class VKDevice : public NonCopyable {
|
|||
VKDescriptorPools descriptor_pools_;
|
||||
|
||||
/** Limits of the device linked to this context. */
|
||||
VkPhysicalDeviceLimits vk_physical_device_limits_;
|
||||
VkPhysicalDeviceProperties vk_physical_device_properties_ = {};
|
||||
|
||||
/** Functions of vk_ext_debugutils for this device/instance. */
|
||||
debug::VKDebuggingTools debugging_tools_;
|
||||
|
@ -40,9 +40,9 @@ class VKDevice : public NonCopyable {
|
|||
return vk_physical_device_;
|
||||
}
|
||||
|
||||
const VkPhysicalDeviceLimits &physical_device_limits_get() const
|
||||
const VkPhysicalDeviceProperties &physical_device_properties_get() const
|
||||
{
|
||||
return vk_physical_device_limits_;
|
||||
return vk_physical_device_properties_;
|
||||
}
|
||||
|
||||
VkInstance instance_get() const
|
||||
|
@ -89,9 +89,13 @@ class VKDevice : public NonCopyable {
|
|||
void init(void *ghost_context);
|
||||
void deinit();
|
||||
|
||||
eGPUDeviceType device_type() const;
|
||||
eGPUDriverType driver_type() const;
|
||||
std::string vendor_name() const;
|
||||
std::string driver_version() const;
|
||||
|
||||
private:
|
||||
void init_physical_device_limits();
|
||||
void init_capabilities();
|
||||
void init_physical_device_properties();
|
||||
void init_debug_callbacks();
|
||||
void init_memory_allocator();
|
||||
void init_descriptor_pools();
|
||||
|
|
|
@ -36,7 +36,7 @@ int64_t VKPixelBuffer::get_native_handle()
|
|||
return int64_t(buffer_.vk_handle());
|
||||
}
|
||||
|
||||
uint VKPixelBuffer::get_size()
|
||||
size_t VKPixelBuffer::get_size()
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class VKPixelBuffer : public PixelBuffer {
|
|||
void *map() override;
|
||||
void unmap() override;
|
||||
int64_t get_native_handle() override;
|
||||
uint get_size() override;
|
||||
size_t get_size() override;
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -48,15 +48,16 @@ uint32_t struct_size(Span<shader::ShaderCreateInfo::PushConst> push_constants)
|
|||
}
|
||||
|
||||
VKPushConstants::StorageType VKPushConstants::Layout::determine_storage_type(
|
||||
const shader::ShaderCreateInfo &info, const VkPhysicalDeviceLimits &vk_physical_device_limits)
|
||||
const shader::ShaderCreateInfo &info, const VKDevice &device)
|
||||
{
|
||||
if (info.push_constants_.is_empty()) {
|
||||
return StorageType::NONE;
|
||||
}
|
||||
|
||||
uint32_t max_push_constants_size =
|
||||
device.physical_device_properties_get().limits.maxPushConstantsSize;
|
||||
uint32_t size = struct_size<Std430>(info.push_constants_);
|
||||
return size <= vk_physical_device_limits.maxPushConstantsSize ? STORAGE_TYPE_DEFAULT :
|
||||
STORAGE_TYPE_FALLBACK;
|
||||
return size <= max_push_constants_size ? STORAGE_TYPE_DEFAULT : STORAGE_TYPE_FALLBACK;
|
||||
}
|
||||
|
||||
template<typename LayoutT>
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace blender::gpu {
|
|||
class VKShaderInterface;
|
||||
class VKUniformBuffer;
|
||||
class VKContext;
|
||||
class VKDevice;
|
||||
|
||||
/**
|
||||
* Container to store push constants in a buffer.
|
||||
|
@ -88,17 +89,16 @@ class VKPushConstants : VKResourceTracker<VKUniformBuffer> {
|
|||
public:
|
||||
/**
|
||||
* Return the desired storage type that can fit the push constants of the given shader create
|
||||
* info, matching the device limits.
|
||||
* info, matching the limits of the given device.
|
||||
*
|
||||
* Returns:
|
||||
* - StorageType::NONE: No push constants are needed.
|
||||
* - StorageType::PUSH_CONSTANTS: Regular vulkan push constants can be used.
|
||||
* - StorageType::UNIFORM_BUFFER: The push constants don't fit in the limits of the given
|
||||
* device. A uniform buffer should be used as a fallback method.
|
||||
* device. A uniform buffer should be used as a fallback method.
|
||||
*/
|
||||
static StorageType determine_storage_type(
|
||||
const shader::ShaderCreateInfo &info,
|
||||
const VkPhysicalDeviceLimits &vk_physical_device_limits);
|
||||
static StorageType determine_storage_type(const shader::ShaderCreateInfo &info,
|
||||
const VKDevice &device);
|
||||
|
||||
/**
|
||||
* Initialize the push constants of the given shader create info with the
|
||||
|
|
|
@ -50,7 +50,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
size_t names_size = info.interface_names_size_;
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
const VKPushConstants::StorageType push_constants_storage_type =
|
||||
VKPushConstants::Layout::determine_storage_type(info, device.physical_device_limits_get());
|
||||
VKPushConstants::Layout::determine_storage_type(info, device);
|
||||
if (push_constants_storage_type == VKPushConstants::StorageType::UNIFORM_BUFFER) {
|
||||
ubo_len_++;
|
||||
names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1;
|
||||
|
|
|
@ -289,7 +289,7 @@ typedef struct LightLinkingRuntime {
|
|||
typedef struct LightLinking {
|
||||
/* Collections which contains objects (possibly via nested collection indirection) which defines
|
||||
* the light linking relation: such as whether objects are included or excluded from being lit by
|
||||
* this emitter (receiver_collection), oe whether they block light from this emitter
|
||||
* this emitter (receiver_collection), or whether they block light from this emitter
|
||||
* (blocker_collection).
|
||||
*
|
||||
* If the collection is a null pointer then all objects from the current scene are receiving
|
||||
|
|
|
@ -5908,7 +5908,7 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
|
|||
# endif
|
||||
|
||||
# ifdef WITH_OPENJPEG
|
||||
/* Jpeg 2000 */
|
||||
/* JPEG 2000 */
|
||||
prop = RNA_def_property(srna, "use_jpeg2k_ycc", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "jp2_flag", R_IMF_JP2_FLAG_YCC);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
|
@ -41,28 +41,30 @@ extern "C" {
|
|||
/* External Engine */
|
||||
|
||||
/** #RenderEngineType.flag */
|
||||
#define RE_INTERNAL 1
|
||||
/* #define RE_FLAG_DEPRECATED 2 */
|
||||
#define RE_USE_PREVIEW 4
|
||||
#define RE_USE_POSTPROCESS 8
|
||||
#define RE_USE_EEVEE_VIEWPORT 16
|
||||
/* #define RE_USE_SAVE_BUFFERS_DEPRECATED 32 */
|
||||
#define RE_USE_SHADING_NODES_CUSTOM 64
|
||||
#define RE_USE_SPHERICAL_STEREO 128
|
||||
#define RE_USE_STEREO_VIEWPORT 256
|
||||
#define RE_USE_GPU_CONTEXT 512
|
||||
#define RE_USE_CUSTOM_FREESTYLE 1024
|
||||
#define RE_USE_NO_IMAGE_SAVE 2048
|
||||
#define RE_USE_ALEMBIC_PROCEDURAL 4096
|
||||
enum RenderEngineTypeFlag {
|
||||
RE_INTERNAL = (1 << 0),
|
||||
RE_USE_PREVIEW = (1 << 1),
|
||||
RE_USE_POSTPROCESS = (1 << 2),
|
||||
RE_USE_EEVEE_VIEWPORT = (1 << 3),
|
||||
RE_USE_SHADING_NODES_CUSTOM = (1 << 4),
|
||||
RE_USE_SPHERICAL_STEREO = (1 << 5),
|
||||
RE_USE_STEREO_VIEWPORT = (1 << 6),
|
||||
RE_USE_GPU_CONTEXT = (1 << 7),
|
||||
RE_USE_CUSTOM_FREESTYLE = (1 << 8),
|
||||
RE_USE_NO_IMAGE_SAVE = (1 << 9),
|
||||
RE_USE_ALEMBIC_PROCEDURAL = (1 << 10),
|
||||
};
|
||||
|
||||
/** #RenderEngine.flag */
|
||||
#define RE_ENGINE_ANIMATION 1
|
||||
#define RE_ENGINE_PREVIEW 2
|
||||
#define RE_ENGINE_DO_DRAW 4
|
||||
#define RE_ENGINE_DO_UPDATE 8
|
||||
#define RE_ENGINE_RENDERING 16
|
||||
#define RE_ENGINE_HIGHLIGHT_TILES 32
|
||||
#define RE_ENGINE_CAN_DRAW 64
|
||||
enum RenderEngineFlag {
|
||||
RE_ENGINE_ANIMATION = (1 << 0),
|
||||
RE_ENGINE_PREVIEW = (1 << 1),
|
||||
RE_ENGINE_DO_DRAW = (1 << 2),
|
||||
RE_ENGINE_DO_UPDATE = (1 << 3),
|
||||
RE_ENGINE_RENDERING = (1 << 4),
|
||||
RE_ENGINE_HIGHLIGHT_TILES = (1 << 5),
|
||||
RE_ENGINE_CAN_DRAW = (1 << 6),
|
||||
};
|
||||
|
||||
extern ListBase R_engines;
|
||||
|
||||
|
|
|
@ -1129,6 +1129,11 @@ static RenderView *duplicate_render_view(RenderView *rview)
|
|||
{
|
||||
RenderView *new_rview = MEM_cnew<RenderView>("new render view", *rview);
|
||||
|
||||
/* Reset buffers, they are not supposed to be shallow-coped. */
|
||||
new_rview->combined_buffer = {};
|
||||
new_rview->z_buffer = {};
|
||||
new_rview->byte_buffer = {};
|
||||
|
||||
if (rview->combined_buffer.data != nullptr) {
|
||||
RE_RenderBuffer_assign_data(&new_rview->combined_buffer,
|
||||
static_cast<float *>(MEM_dupallocN(rview->combined_buffer.data)));
|
||||
|
@ -1162,13 +1167,23 @@ RenderResult *RE_DuplicateRenderResult(RenderResult *rr)
|
|||
BLI_addtail(&new_rr->views, new_rview);
|
||||
}
|
||||
|
||||
RE_RenderBuffer_assign_data(&new_rr->combined_buffer,
|
||||
static_cast<float *>(MEM_dupallocN(rr->combined_buffer.data)));
|
||||
RE_RenderBuffer_assign_data(&new_rr->z_buffer,
|
||||
static_cast<float *>(MEM_dupallocN(rr->z_buffer.data)));
|
||||
/* Reset buffers, they are not supposed to be shallow-coped. */
|
||||
new_rr->combined_buffer = {};
|
||||
new_rr->z_buffer = {};
|
||||
new_rr->byte_buffer = {};
|
||||
|
||||
RE_RenderByteBuffer_assign_data(&new_rr->byte_buffer,
|
||||
static_cast<uint8_t *>(MEM_dupallocN(rr->byte_buffer.data)));
|
||||
if (rr->combined_buffer.data) {
|
||||
RE_RenderBuffer_assign_data(&new_rr->combined_buffer,
|
||||
static_cast<float *>(MEM_dupallocN(rr->combined_buffer.data)));
|
||||
}
|
||||
if (rr->z_buffer.data) {
|
||||
RE_RenderBuffer_assign_data(&new_rr->z_buffer,
|
||||
static_cast<float *>(MEM_dupallocN(rr->z_buffer.data)));
|
||||
}
|
||||
if (rr->byte_buffer.data) {
|
||||
RE_RenderByteBuffer_assign_data(&new_rr->byte_buffer,
|
||||
static_cast<uint8_t *>(MEM_dupallocN(rr->byte_buffer.data)));
|
||||
}
|
||||
|
||||
new_rr->stamp_data = BKE_stamp_data_copy(new_rr->stamp_data);
|
||||
return new_rr;
|
||||
|
|
Loading…
Reference in New Issue