Animation: Gaussian Smooth operator for Graph Editor #105635
|
@ -617,10 +617,12 @@ endif()
|
|||
|
||||
option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON)
|
||||
option(WITH_GPU_BUILDTIME_SHADER_BUILDER "Shader builder is a developer option enabling linting on GLSL during compilation" OFF)
|
||||
option(WITH_RENDERDOC "Use Renderdoc API to capture frames" OFF)
|
||||
|
||||
mark_as_advanced(
|
||||
WITH_OPENGL
|
||||
WITH_GPU_BUILDTIME_SHADER_BUILDER
|
||||
WITH_RENDERDOC
|
||||
)
|
||||
|
||||
# Vulkan
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Project: Renderdoc APP
|
||||
URL: https://github.com/baldurk/renderdoc/
|
||||
License: MIT
|
||||
Upstream version: d47e79ae079783935b8857d6a1730440eafb0b38
|
||||
Local modifications: None
|
|
@ -0,0 +1,723 @@
|
|||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019-2023 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Documentation for the API is available at https://renderdoc.org/docs/in_application_api.html
|
||||
//
|
||||
|
||||
#if !defined(RENDERDOC_NO_STDINT)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
|
||||
#define RENDERDOC_CC __cdecl
|
||||
#elif defined(__linux__)
|
||||
#define RENDERDOC_CC
|
||||
#elif defined(__APPLE__)
|
||||
#define RENDERDOC_CC
|
||||
#else
|
||||
#error "Unknown platform"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constants not used directly in below API
|
||||
|
||||
// This is a GUID/magic value used for when applications pass a path where shader debug
|
||||
// information can be found to match up with a stripped shader.
|
||||
// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue =
|
||||
// RENDERDOC_ShaderDebugMagicValue_value
|
||||
#define RENDERDOC_ShaderDebugMagicValue_struct \
|
||||
{ \
|
||||
0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \
|
||||
}
|
||||
|
||||
// as an alternative when you want a byte array (assuming x86 endianness):
|
||||
#define RENDERDOC_ShaderDebugMagicValue_bytearray \
|
||||
{ \
|
||||
0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \
|
||||
}
|
||||
|
||||
// truncated version when only a uint64_t is available (e.g. Vulkan tags):
|
||||
#define RENDERDOC_ShaderDebugMagicValue_truncated 0x48656670eab25520ULL
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RenderDoc capture options
|
||||
//
|
||||
|
||||
typedef enum RENDERDOC_CaptureOption {
|
||||
// Allow the application to enable vsync
|
||||
//
|
||||
// Default - enabled
|
||||
//
|
||||
// 1 - The application can enable or disable vsync at will
|
||||
// 0 - vsync is force disabled
|
||||
eRENDERDOC_Option_AllowVSync = 0,
|
||||
|
||||
// Allow the application to enable fullscreen
|
||||
//
|
||||
// Default - enabled
|
||||
//
|
||||
// 1 - The application can enable or disable fullscreen at will
|
||||
// 0 - fullscreen is force disabled
|
||||
eRENDERDOC_Option_AllowFullscreen = 1,
|
||||
|
||||
// Record API debugging events and messages
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - Enable built-in API debugging features and records the results into
|
||||
// the capture, which is matched up with events on replay
|
||||
// 0 - no API debugging is forcibly enabled
|
||||
eRENDERDOC_Option_APIValidation = 2,
|
||||
eRENDERDOC_Option_DebugDeviceMode = 2, // deprecated name of this enum
|
||||
|
||||
// Capture CPU callstacks for API events
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - Enables capturing of callstacks
|
||||
// 0 - no callstacks are captured
|
||||
eRENDERDOC_Option_CaptureCallstacks = 3,
|
||||
|
||||
// When capturing CPU callstacks, only capture them from actions.
|
||||
// This option does nothing without the above option being enabled
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - Only captures callstacks for actions.
|
||||
// Ignored if CaptureCallstacks is disabled
|
||||
// 0 - Callstacks, if enabled, are captured for every event.
|
||||
eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4,
|
||||
eRENDERDOC_Option_CaptureCallstacksOnlyActions = 4,
|
||||
|
||||
// Specify a delay in seconds to wait for a debugger to attach, after
|
||||
// creating or injecting into a process, before continuing to allow it to run.
|
||||
//
|
||||
// 0 indicates no delay, and the process will run immediately after injection
|
||||
//
|
||||
// Default - 0 seconds
|
||||
//
|
||||
eRENDERDOC_Option_DelayForDebugger = 5,
|
||||
|
||||
// Verify buffer access. This includes checking the memory returned by a Map() call to
|
||||
// detect any out-of-bounds modification, as well as initialising buffers with undefined contents
|
||||
// to a marker value to catch use of uninitialised memory.
|
||||
//
|
||||
// NOTE: This option is only valid for OpenGL and D3D11. Explicit APIs such as D3D12 and Vulkan do
|
||||
// not do the same kind of interception & checking and undefined contents are really undefined.
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - Verify buffer access
|
||||
// 0 - No verification is performed, and overwriting bounds may cause crashes or corruption in
|
||||
// RenderDoc.
|
||||
eRENDERDOC_Option_VerifyBufferAccess = 6,
|
||||
|
||||
// The old name for eRENDERDOC_Option_VerifyBufferAccess was eRENDERDOC_Option_VerifyMapWrites.
|
||||
// This option now controls the filling of uninitialised buffers with 0xdddddddd which was
|
||||
// previously always enabled
|
||||
eRENDERDOC_Option_VerifyMapWrites = eRENDERDOC_Option_VerifyBufferAccess,
|
||||
|
||||
// Hooks any system API calls that create child processes, and injects
|
||||
// RenderDoc into them recursively with the same options.
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - Hooks into spawned child processes
|
||||
// 0 - Child processes are not hooked by RenderDoc
|
||||
eRENDERDOC_Option_HookIntoChildren = 7,
|
||||
|
||||
// By default RenderDoc only includes resources in the final capture necessary
|
||||
// for that frame, this allows you to override that behaviour.
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - all live resources at the time of capture are included in the capture
|
||||
// and available for inspection
|
||||
// 0 - only the resources referenced by the captured frame are included
|
||||
eRENDERDOC_Option_RefAllResources = 8,
|
||||
|
||||
// **NOTE**: As of RenderDoc v1.1 this option has been deprecated. Setting or
|
||||
// getting it will be ignored, to allow compatibility with older versions.
|
||||
// In v1.1 the option acts as if it's always enabled.
|
||||
//
|
||||
// By default RenderDoc skips saving initial states for resources where the
|
||||
// previous contents don't appear to be used, assuming that writes before
|
||||
// reads indicate previous contents aren't used.
|
||||
//
|
||||
// Default - disabled
|
||||
//
|
||||
// 1 - initial contents at the start of each captured frame are saved, even if
|
||||
// they are later overwritten or cleared before being used.
|
||||
// 0 - unless a read is detected, initial contents will not be saved and will
|
||||
// appear as black or empty data.
|
||||
eRENDERDOC_Option_SaveAllInitials = 9,
|
||||
|
||||
// In APIs that allow for the recording of command lists to be replayed later,
|
||||
// RenderDoc may choose to not capture command lists before a frame capture is
|
||||
// triggered, to reduce overheads. This means any command lists recorded once
|
||||
// and replayed many times will not be available and may cause a failure to
|
||||
// capture.
|
||||
//
|
||||
// NOTE: This is only true for APIs where multithreading is difficult or
|
||||
// discouraged. Newer APIs like Vulkan and D3D12 will ignore this option
|
||||
// and always capture all command lists since the API is heavily oriented
|
||||
// around it and the overheads have been reduced by API design.
|
||||
//
|
||||
// 1 - All command lists are captured from the start of the application
|
||||
// 0 - Command lists are only captured if their recording begins during
|
||||
// the period when a frame capture is in progress.
|
||||
eRENDERDOC_Option_CaptureAllCmdLists = 10,
|
||||
|
||||
// Mute API debugging output when the API validation mode option is enabled
|
||||
//
|
||||
// Default - enabled
|
||||
//
|
||||
// 1 - Mute any API debug messages from being displayed or passed through
|
||||
// 0 - API debugging is displayed as normal
|
||||
eRENDERDOC_Option_DebugOutputMute = 11,
|
||||
|
||||
// Option to allow vendor extensions to be used even when they may be
|
||||
// incompatible with RenderDoc and cause corrupted replays or crashes.
|
||||
//
|
||||
// Default - inactive
|
||||
//
|
||||
// No values are documented, this option should only be used when absolutely
|
||||
// necessary as directed by a RenderDoc developer.
|
||||
eRENDERDOC_Option_AllowUnsupportedVendorExtensions = 12,
|
||||
|
||||
} RENDERDOC_CaptureOption;
|
||||
|
||||
// Sets an option that controls how RenderDoc behaves on capture.
|
||||
//
|
||||
// Returns 1 if the option and value are valid
|
||||
// Returns 0 if either is invalid and the option is unchanged
|
||||
typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val);
|
||||
typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val);
|
||||
|
||||
// Gets the current value of an option as a uint32_t
|
||||
//
|
||||
// If the option is invalid, 0xffffffff is returned
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt);
|
||||
|
||||
// Gets the current value of an option as a float
|
||||
//
|
||||
// If the option is invalid, -FLT_MAX is returned
|
||||
typedef float(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt);
|
||||
|
||||
typedef enum RENDERDOC_InputButton {
|
||||
// '0' - '9' matches ASCII values
|
||||
eRENDERDOC_Key_0 = 0x30,
|
||||
eRENDERDOC_Key_1 = 0x31,
|
||||
eRENDERDOC_Key_2 = 0x32,
|
||||
eRENDERDOC_Key_3 = 0x33,
|
||||
eRENDERDOC_Key_4 = 0x34,
|
||||
eRENDERDOC_Key_5 = 0x35,
|
||||
eRENDERDOC_Key_6 = 0x36,
|
||||
eRENDERDOC_Key_7 = 0x37,
|
||||
eRENDERDOC_Key_8 = 0x38,
|
||||
eRENDERDOC_Key_9 = 0x39,
|
||||
|
||||
// 'A' - 'Z' matches ASCII values
|
||||
eRENDERDOC_Key_A = 0x41,
|
||||
eRENDERDOC_Key_B = 0x42,
|
||||
eRENDERDOC_Key_C = 0x43,
|
||||
eRENDERDOC_Key_D = 0x44,
|
||||
eRENDERDOC_Key_E = 0x45,
|
||||
eRENDERDOC_Key_F = 0x46,
|
||||
eRENDERDOC_Key_G = 0x47,
|
||||
eRENDERDOC_Key_H = 0x48,
|
||||
eRENDERDOC_Key_I = 0x49,
|
||||
eRENDERDOC_Key_J = 0x4A,
|
||||
eRENDERDOC_Key_K = 0x4B,
|
||||
eRENDERDOC_Key_L = 0x4C,
|
||||
eRENDERDOC_Key_M = 0x4D,
|
||||
eRENDERDOC_Key_N = 0x4E,
|
||||
eRENDERDOC_Key_O = 0x4F,
|
||||
eRENDERDOC_Key_P = 0x50,
|
||||
eRENDERDOC_Key_Q = 0x51,
|
||||
eRENDERDOC_Key_R = 0x52,
|
||||
eRENDERDOC_Key_S = 0x53,
|
||||
eRENDERDOC_Key_T = 0x54,
|
||||
eRENDERDOC_Key_U = 0x55,
|
||||
eRENDERDOC_Key_V = 0x56,
|
||||
eRENDERDOC_Key_W = 0x57,
|
||||
eRENDERDOC_Key_X = 0x58,
|
||||
eRENDERDOC_Key_Y = 0x59,
|
||||
eRENDERDOC_Key_Z = 0x5A,
|
||||
|
||||
// leave the rest of the ASCII range free
|
||||
// in case we want to use it later
|
||||
eRENDERDOC_Key_NonPrintable = 0x100,
|
||||
|
||||
eRENDERDOC_Key_Divide,
|
||||
eRENDERDOC_Key_Multiply,
|
||||
eRENDERDOC_Key_Subtract,
|
||||
eRENDERDOC_Key_Plus,
|
||||
|
||||
eRENDERDOC_Key_F1,
|
||||
eRENDERDOC_Key_F2,
|
||||
eRENDERDOC_Key_F3,
|
||||
eRENDERDOC_Key_F4,
|
||||
eRENDERDOC_Key_F5,
|
||||
eRENDERDOC_Key_F6,
|
||||
eRENDERDOC_Key_F7,
|
||||
eRENDERDOC_Key_F8,
|
||||
eRENDERDOC_Key_F9,
|
||||
eRENDERDOC_Key_F10,
|
||||
eRENDERDOC_Key_F11,
|
||||
eRENDERDOC_Key_F12,
|
||||
|
||||
eRENDERDOC_Key_Home,
|
||||
eRENDERDOC_Key_End,
|
||||
eRENDERDOC_Key_Insert,
|
||||
eRENDERDOC_Key_Delete,
|
||||
eRENDERDOC_Key_PageUp,
|
||||
eRENDERDOC_Key_PageDn,
|
||||
|
||||
eRENDERDOC_Key_Backspace,
|
||||
eRENDERDOC_Key_Tab,
|
||||
eRENDERDOC_Key_PrtScrn,
|
||||
eRENDERDOC_Key_Pause,
|
||||
|
||||
eRENDERDOC_Key_Max,
|
||||
} RENDERDOC_InputButton;
|
||||
|
||||
// Sets which key or keys can be used to toggle focus between multiple windows
|
||||
//
|
||||
// If keys is NULL or num is 0, toggle keys will be disabled
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num);
|
||||
|
||||
// Sets which key or keys can be used to capture the next frame
|
||||
//
|
||||
// If keys is NULL or num is 0, captures keys will be disabled
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num);
|
||||
|
||||
typedef enum RENDERDOC_OverlayBits {
|
||||
// This single bit controls whether the overlay is enabled or disabled globally
|
||||
eRENDERDOC_Overlay_Enabled = 0x1,
|
||||
|
||||
// Show the average framerate over several seconds as well as min/max
|
||||
eRENDERDOC_Overlay_FrameRate = 0x2,
|
||||
|
||||
// Show the current frame number
|
||||
eRENDERDOC_Overlay_FrameNumber = 0x4,
|
||||
|
||||
// Show a list of recent captures, and how many captures have been made
|
||||
eRENDERDOC_Overlay_CaptureList = 0x8,
|
||||
|
||||
// Default values for the overlay mask
|
||||
eRENDERDOC_Overlay_Default = (eRENDERDOC_Overlay_Enabled | eRENDERDOC_Overlay_FrameRate |
|
||||
eRENDERDOC_Overlay_FrameNumber | eRENDERDOC_Overlay_CaptureList),
|
||||
|
||||
// Enable all bits
|
||||
eRENDERDOC_Overlay_All = ~0U,
|
||||
|
||||
// Disable all bits
|
||||
eRENDERDOC_Overlay_None = 0,
|
||||
} RENDERDOC_OverlayBits;
|
||||
|
||||
// returns the overlay bits that have been set
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetOverlayBits)();
|
||||
// sets the overlay bits with an and & or mask
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or);
|
||||
|
||||
// this function will attempt to remove RenderDoc's hooks in the application.
|
||||
//
|
||||
// Note: that this can only work correctly if done immediately after
|
||||
// the module is loaded, before any API work happens. RenderDoc will remove its
|
||||
// injected hooks and shut down. Behaviour is undefined if this is called
|
||||
// after any API functions have been called, and there is still no guarantee of
|
||||
// success.
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_RemoveHooks)();
|
||||
|
||||
// DEPRECATED: compatibility for code compiled against pre-1.4.1 headers.
|
||||
typedef pRENDERDOC_RemoveHooks pRENDERDOC_Shutdown;
|
||||
|
||||
// This function will unload RenderDoc's crash handler.
|
||||
//
|
||||
// If you use your own crash handler and don't want RenderDoc's handler to
|
||||
// intercede, you can call this function to unload it and any unhandled
|
||||
// exceptions will pass to the next handler.
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)();
|
||||
|
||||
// Sets the capture file path template
|
||||
//
|
||||
// pathtemplate is a UTF-8 string that gives a template for how captures will be named
|
||||
// and where they will be saved.
|
||||
//
|
||||
// Any extension is stripped off the path, and captures are saved in the directory
|
||||
// specified, and named with the filename and the frame number appended. If the
|
||||
// directory does not exist it will be created, including any parent directories.
|
||||
//
|
||||
// If pathtemplate is NULL, the template will remain unchanged
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// SetCaptureFilePathTemplate("my_captures/example");
|
||||
//
|
||||
// Capture #1 -> my_captures/example_frame123.rdc
|
||||
// Capture #2 -> my_captures/example_frame456.rdc
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureFilePathTemplate)(const char *pathtemplate);
|
||||
|
||||
// returns the current capture path template, see SetCaptureFileTemplate above, as a UTF-8 string
|
||||
typedef const char *(RENDERDOC_CC *pRENDERDOC_GetCaptureFilePathTemplate)();
|
||||
|
||||
// DEPRECATED: compatibility for code compiled against pre-1.1.2 headers.
|
||||
typedef pRENDERDOC_SetCaptureFilePathTemplate pRENDERDOC_SetLogFilePathTemplate;
|
||||
typedef pRENDERDOC_GetCaptureFilePathTemplate pRENDERDOC_GetLogFilePathTemplate;
|
||||
|
||||
// returns the number of captures that have been made
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetNumCaptures)();
|
||||
|
||||
// This function returns the details of a capture, by index. New captures are added
|
||||
// to the end of the list.
|
||||
//
|
||||
// filename will be filled with the absolute path to the capture file, as a UTF-8 string
|
||||
// pathlength will be written with the length in bytes of the filename string
|
||||
// timestamp will be written with the time of the capture, in seconds since the Unix epoch
|
||||
//
|
||||
// Any of the parameters can be NULL and they'll be skipped.
|
||||
//
|
||||
// The function will return 1 if the capture index is valid, or 0 if the index is invalid
|
||||
// If the index is invalid, the values will be unchanged
|
||||
//
|
||||
// Note: when captures are deleted in the UI they will remain in this list, so the
|
||||
// capture path may not exist anymore.
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *filename,
|
||||
uint32_t *pathlength, uint64_t *timestamp);
|
||||
|
||||
// Sets the comments associated with a capture file. These comments are displayed in the
|
||||
// UI program when opening.
|
||||
//
|
||||
// filePath should be a path to the capture file to add comments to. If set to NULL or ""
|
||||
// the most recent capture file created made will be used instead.
|
||||
// comments should be a NULL-terminated UTF-8 string to add as comments.
|
||||
//
|
||||
// Any existing comments will be overwritten.
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureFileComments)(const char *filePath,
|
||||
const char *comments);
|
||||
|
||||
// returns 1 if the RenderDoc UI is connected to this application, 0 otherwise
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsTargetControlConnected)();
|
||||
|
||||
// DEPRECATED: compatibility for code compiled against pre-1.1.1 headers.
|
||||
// This was renamed to IsTargetControlConnected in API 1.1.1, the old typedef is kept here for
|
||||
// backwards compatibility with old code, it is castable either way since it's ABI compatible
|
||||
// as the same function pointer type.
|
||||
typedef pRENDERDOC_IsTargetControlConnected pRENDERDOC_IsRemoteAccessConnected;
|
||||
|
||||
// This function will launch the Replay UI associated with the RenderDoc library injected
|
||||
// into the running application.
|
||||
//
|
||||
// if connectTargetControl is 1, the Replay UI will be launched with a command line parameter
|
||||
// to connect to this application
|
||||
// cmdline is the rest of the command line, as a UTF-8 string. E.g. a captures to open
|
||||
// if cmdline is NULL, the command line will be empty.
|
||||
//
|
||||
// returns the PID of the replay UI if successful, 0 if not successful.
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectTargetControl,
|
||||
const char *cmdline);
|
||||
|
||||
// RenderDoc can return a higher version than requested if it's backwards compatible,
|
||||
// this function returns the actual version returned. If a parameter is NULL, it will be
|
||||
// ignored and the others will be filled out.
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch);
|
||||
|
||||
// Requests that the replay UI show itself (if hidden or not the current top window). This can be
|
||||
// used in conjunction with IsTargetControlConnected and LaunchReplayUI to intelligently handle
|
||||
// showing the UI after making a capture.
|
||||
//
|
||||
// This will return 1 if the request was successfully passed on, though it's not guaranteed that
|
||||
// the UI will be on top in all cases depending on OS rules. It will return 0 if there is no current
|
||||
// target control connection to make such a request, or if there was another error
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_ShowReplayUI)();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Capturing functions
|
||||
//
|
||||
|
||||
// A device pointer is a pointer to the API's root handle.
|
||||
//
|
||||
// This would be an ID3D11Device, HGLRC/GLXContext, ID3D12Device, etc
|
||||
typedef void *RENDERDOC_DevicePointer;
|
||||
|
||||
// A window handle is the OS's native window handle
|
||||
//
|
||||
// This would be an HWND, GLXDrawable, etc
|
||||
typedef void *RENDERDOC_WindowHandle;
|
||||
|
||||
// A helper macro for Vulkan, where the device handle cannot be used directly.
|
||||
//
|
||||
// Passing the VkInstance to this macro will return the RENDERDOC_DevicePointer to use.
|
||||
//
|
||||
// Specifically, the value needed is the dispatch table pointer, which sits as the first
|
||||
// pointer-sized object in the memory pointed to by the VkInstance. Thus we cast to a void** and
|
||||
// indirect once.
|
||||
#define RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(inst) (*((void **)(inst)))
|
||||
|
||||
// This sets the RenderDoc in-app overlay in the API/window pair as 'active' and it will
|
||||
// respond to keypresses. Neither parameter can be NULL
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device,
|
||||
RENDERDOC_WindowHandle wndHandle);
|
||||
|
||||
// capture the next frame on whichever window and API is currently considered active
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_TriggerCapture)();
|
||||
|
||||
// capture the next N frames on whichever window and API is currently considered active
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_TriggerMultiFrameCapture)(uint32_t numFrames);
|
||||
|
||||
// When choosing either a device pointer or a window handle to capture, you can pass NULL.
|
||||
// Passing NULL specifies a 'wildcard' match against anything. This allows you to specify
|
||||
// any API rendering to a specific window, or a specific API instance rendering to any window,
|
||||
// or in the simplest case of one window and one API, you can just pass NULL for both.
|
||||
//
|
||||
// In either case, if there are two or more possible matching (device,window) pairs it
|
||||
// is undefined which one will be captured.
|
||||
//
|
||||
// Note: for headless rendering you can pass NULL for the window handle and either specify
|
||||
// a device pointer or leave it NULL as above.
|
||||
|
||||
// Immediately starts capturing API calls on the specified device pointer and window handle.
|
||||
//
|
||||
// If there is no matching thing to capture (e.g. no supported API has been initialised),
|
||||
// this will do nothing.
|
||||
//
|
||||
// The results are undefined (including crashes) if two captures are started overlapping,
|
||||
// even on separate devices and/oror windows.
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device,
|
||||
RENDERDOC_WindowHandle wndHandle);
|
||||
|
||||
// Returns whether or not a frame capture is currently ongoing anywhere.
|
||||
//
|
||||
// This will return 1 if a capture is ongoing, and 0 if there is no capture running
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)();
|
||||
|
||||
// Ends capturing immediately.
|
||||
//
|
||||
// This will return 1 if the capture succeeded, and 0 if there was an error capturing.
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device,
|
||||
RENDERDOC_WindowHandle wndHandle);
|
||||
|
||||
// Ends capturing immediately and discard any data stored without saving to disk.
|
||||
//
|
||||
// This will return 1 if the capture was discarded, and 0 if there was an error or no capture
|
||||
// was in progress
|
||||
typedef uint32_t(RENDERDOC_CC *pRENDERDOC_DiscardFrameCapture)(RENDERDOC_DevicePointer device,
|
||||
RENDERDOC_WindowHandle wndHandle);
|
||||
|
||||
// Only valid to be called between a call to StartFrameCapture and EndFrameCapture. Gives a custom
|
||||
// title to the capture produced which will be displayed in the UI.
|
||||
//
|
||||
// If multiple captures are ongoing, this title will be applied to the first capture to end after
|
||||
// this call. The second capture to end will have no title, unless this function is called again.
|
||||
//
|
||||
// Calling this function has no effect if no capture is currently running
|
||||
typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureTitle)(const char *title);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RenderDoc API versions
|
||||
//
|
||||
|
||||
// RenderDoc uses semantic versioning (http://semver.org/).
|
||||
//
|
||||
// MAJOR version is incremented when incompatible API changes happen.
|
||||
// MINOR version is incremented when functionality is added in a backwards-compatible manner.
|
||||
// PATCH version is incremented when backwards-compatible bug fixes happen.
|
||||
//
|
||||
// Note that this means the API returned can be higher than the one you might have requested.
|
||||
// e.g. if you are running against a newer RenderDoc that supports 1.0.1, it will be returned
|
||||
// instead of 1.0.0. You can check this with the GetAPIVersion entry point
|
||||
typedef enum RENDERDOC_Version {
|
||||
eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00
|
||||
eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01
|
||||
eRENDERDOC_API_Version_1_0_2 = 10002, // RENDERDOC_API_1_0_2 = 1 00 02
|
||||
eRENDERDOC_API_Version_1_1_0 = 10100, // RENDERDOC_API_1_1_0 = 1 01 00
|
||||
eRENDERDOC_API_Version_1_1_1 = 10101, // RENDERDOC_API_1_1_1 = 1 01 01
|
||||
eRENDERDOC_API_Version_1_1_2 = 10102, // RENDERDOC_API_1_1_2 = 1 01 02
|
||||
eRENDERDOC_API_Version_1_2_0 = 10200, // RENDERDOC_API_1_2_0 = 1 02 00
|
||||
eRENDERDOC_API_Version_1_3_0 = 10300, // RENDERDOC_API_1_3_0 = 1 03 00
|
||||
eRENDERDOC_API_Version_1_4_0 = 10400, // RENDERDOC_API_1_4_0 = 1 04 00
|
||||
eRENDERDOC_API_Version_1_4_1 = 10401, // RENDERDOC_API_1_4_1 = 1 04 01
|
||||
eRENDERDOC_API_Version_1_4_2 = 10402, // RENDERDOC_API_1_4_2 = 1 04 02
|
||||
eRENDERDOC_API_Version_1_5_0 = 10500, // RENDERDOC_API_1_5_0 = 1 05 00
|
||||
eRENDERDOC_API_Version_1_6_0 = 10600, // RENDERDOC_API_1_6_0 = 1 06 00
|
||||
} RENDERDOC_Version;
|
||||
|
||||
// API version changelog:
|
||||
//
|
||||
// 1.0.0 - initial release
|
||||
// 1.0.1 - Bugfix: IsFrameCapturing() was returning false for captures that were triggered
|
||||
// by keypress or TriggerCapture, instead of Start/EndFrameCapture.
|
||||
// 1.0.2 - Refactor: Renamed eRENDERDOC_Option_DebugDeviceMode to eRENDERDOC_Option_APIValidation
|
||||
// 1.1.0 - Add feature: TriggerMultiFrameCapture(). Backwards compatible with 1.0.x since the new
|
||||
// function pointer is added to the end of the struct, the original layout is identical
|
||||
// 1.1.1 - Refactor: Renamed remote access to target control (to better disambiguate from remote
|
||||
// replay/remote server concept in replay UI)
|
||||
// 1.1.2 - Refactor: Renamed "log file" in function names to just capture, to clarify that these
|
||||
// are captures and not debug logging files. This is the first API version in the v1.0
|
||||
// branch.
|
||||
// 1.2.0 - Added feature: SetCaptureFileComments() to add comments to a capture file that will be
|
||||
// displayed in the UI program on load.
|
||||
// 1.3.0 - Added feature: New capture option eRENDERDOC_Option_AllowUnsupportedVendorExtensions
|
||||
// which allows users to opt-in to allowing unsupported vendor extensions to function.
|
||||
// Should be used at the user's own risk.
|
||||
// Refactor: Renamed eRENDERDOC_Option_VerifyMapWrites to
|
||||
// eRENDERDOC_Option_VerifyBufferAccess, which now also controls initialisation to
|
||||
// 0xdddddddd of uninitialised buffer contents.
|
||||
// 1.4.0 - Added feature: DiscardFrameCapture() to discard a frame capture in progress and stop
|
||||
// capturing without saving anything to disk.
|
||||
// 1.4.1 - Refactor: Renamed Shutdown to RemoveHooks to better clarify what is happening
|
||||
// 1.4.2 - Refactor: Renamed 'draws' to 'actions' in callstack capture option.
|
||||
// 1.5.0 - Added feature: ShowReplayUI() to request that the replay UI show itself if connected
|
||||
// 1.6.0 - Added feature: SetCaptureTitle() which can be used to set a title for a
|
||||
// capture made with StartFrameCapture() or EndFrameCapture()
|
||||
|
||||
typedef struct RENDERDOC_API_1_6_0
|
||||
{
|
||||
pRENDERDOC_GetAPIVersion GetAPIVersion;
|
||||
|
||||
pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32;
|
||||
pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32;
|
||||
|
||||
pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32;
|
||||
pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32;
|
||||
|
||||
pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys;
|
||||
pRENDERDOC_SetCaptureKeys SetCaptureKeys;
|
||||
|
||||
pRENDERDOC_GetOverlayBits GetOverlayBits;
|
||||
pRENDERDOC_MaskOverlayBits MaskOverlayBits;
|
||||
|
||||
// Shutdown was renamed to RemoveHooks in 1.4.1.
|
||||
// These unions allow old code to continue compiling without changes
|
||||
union
|
||||
{
|
||||
pRENDERDOC_Shutdown Shutdown;
|
||||
pRENDERDOC_RemoveHooks RemoveHooks;
|
||||
};
|
||||
pRENDERDOC_UnloadCrashHandler UnloadCrashHandler;
|
||||
|
||||
// Get/SetLogFilePathTemplate was renamed to Get/SetCaptureFilePathTemplate in 1.1.2.
|
||||
// These unions allow old code to continue compiling without changes
|
||||
union
|
||||
{
|
||||
// deprecated name
|
||||
pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate;
|
||||
// current name
|
||||
pRENDERDOC_SetCaptureFilePathTemplate SetCaptureFilePathTemplate;
|
||||
};
|
||||
union
|
||||
{
|
||||
// deprecated name
|
||||
pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate;
|
||||
// current name
|
||||
pRENDERDOC_GetCaptureFilePathTemplate GetCaptureFilePathTemplate;
|
||||
};
|
||||
|
||||
pRENDERDOC_GetNumCaptures GetNumCaptures;
|
||||
pRENDERDOC_GetCapture GetCapture;
|
||||
|
||||
pRENDERDOC_TriggerCapture TriggerCapture;
|
||||
|
||||
// IsRemoteAccessConnected was renamed to IsTargetControlConnected in 1.1.1.
|
||||
// This union allows old code to continue compiling without changes
|
||||
union
|
||||
{
|
||||
// deprecated name
|
||||
pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected;
|
||||
// current name
|
||||
pRENDERDOC_IsTargetControlConnected IsTargetControlConnected;
|
||||
};
|
||||
pRENDERDOC_LaunchReplayUI LaunchReplayUI;
|
||||
|
||||
pRENDERDOC_SetActiveWindow SetActiveWindow;
|
||||
|
||||
pRENDERDOC_StartFrameCapture StartFrameCapture;
|
||||
pRENDERDOC_IsFrameCapturing IsFrameCapturing;
|
||||
pRENDERDOC_EndFrameCapture EndFrameCapture;
|
||||
|
||||
// new function in 1.1.0
|
||||
pRENDERDOC_TriggerMultiFrameCapture TriggerMultiFrameCapture;
|
||||
|
||||
// new function in 1.2.0
|
||||
pRENDERDOC_SetCaptureFileComments SetCaptureFileComments;
|
||||
|
||||
// new function in 1.4.0
|
||||
pRENDERDOC_DiscardFrameCapture DiscardFrameCapture;
|
||||
|
||||
// new function in 1.5.0
|
||||
pRENDERDOC_ShowReplayUI ShowReplayUI;
|
||||
|
||||
// new function in 1.6.0
|
||||
pRENDERDOC_SetCaptureTitle SetCaptureTitle;
|
||||
} RENDERDOC_API_1_6_0;
|
||||
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_0_0;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_0_1;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_0_2;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_1_0;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_1_1;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_1_2;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_2_0;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_3_0;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_4_0;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_4_1;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_4_2;
|
||||
typedef RENDERDOC_API_1_6_0 RENDERDOC_API_1_5_0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RenderDoc API entry point
|
||||
//
|
||||
// This entry point can be obtained via GetProcAddress/dlsym if RenderDoc is available.
|
||||
//
|
||||
// The name is the same as the typedef - "RENDERDOC_GetAPI"
|
||||
//
|
||||
// This function is not thread safe, and should not be called on multiple threads at once.
|
||||
// Ideally, call this once as early as possible in your application's startup, before doing
|
||||
// any API work, since some configuration functionality etc has to be done also before
|
||||
// initialising any APIs.
|
||||
//
|
||||
// Parameters:
|
||||
// version is a single value from the RENDERDOC_Version above.
|
||||
//
|
||||
// outAPIPointers will be filled out with a pointer to the corresponding struct of function
|
||||
// pointers.
|
||||
//
|
||||
// Returns:
|
||||
// 1 - if the outAPIPointers has been filled with a pointer to the API struct requested
|
||||
// 0 - if the requested version is not supported or the arguments are invalid.
|
||||
//
|
||||
typedef int(RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
|
@ -67,6 +67,10 @@ if(UNIX AND NOT APPLE)
|
|||
add_subdirectory(libc_compat)
|
||||
endif()
|
||||
|
||||
if (WITH_RENDERDOC)
|
||||
add_subdirectory(renderdoc_dynload)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
# Important this comes after "ghost" as it uses includes defined by GHOST's CMake.
|
||||
if(WITH_GHOST_WAYLAND AND WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
|
|
|
@ -39,7 +39,8 @@ OrientationBounds merge(const OrientationBounds &cone_a, const OrientationBounds
|
|||
b = &cone_a;
|
||||
}
|
||||
|
||||
float theta_d = safe_acosf(dot(a->axis, b->axis));
|
||||
float cos_a_b = dot(a->axis, b->axis);
|
||||
float theta_d = safe_acosf(cos_a_b);
|
||||
float theta_e = fmaxf(a->theta_e, b->theta_e);
|
||||
|
||||
/* Return axis and theta_o of a if it already contains b. */
|
||||
|
@ -55,10 +56,18 @@ OrientationBounds merge(const OrientationBounds &cone_a, const OrientationBounds
|
|||
return OrientationBounds({a->axis, M_PI_F, theta_e});
|
||||
}
|
||||
|
||||
/* Rotate new axis to be between a and b. */
|
||||
float theta_r = theta_o - a->theta_o;
|
||||
float3 new_axis = rotate_around_axis(a->axis, normalize(cross(a->axis, b->axis)), theta_r);
|
||||
new_axis = normalize(new_axis);
|
||||
/* Slerp between a and b. */
|
||||
float3 new_axis;
|
||||
if (cos_a_b < -0.9995f) {
|
||||
/* Opposite direction, any orthogonal vector is fine. */
|
||||
float3 unused;
|
||||
make_orthonormals(a->axis, &new_axis, &unused);
|
||||
}
|
||||
else {
|
||||
float theta_r = theta_o - a->theta_o;
|
||||
float3 ortho = normalize(b->axis - a->axis * cos_a_b);
|
||||
new_axis = a->axis * cosf(theta_r) + ortho * sinf(theta_r);
|
||||
}
|
||||
|
||||
return OrientationBounds({new_axis, theta_o, theta_e});
|
||||
}
|
||||
|
|
|
@ -933,6 +933,11 @@ extern bool GHOST_SupportsCursorWarp(void);
|
|||
*/
|
||||
extern bool GHOST_SupportsWindowPosition(void);
|
||||
|
||||
/**
|
||||
* Support a separate primary clipboard.
|
||||
*/
|
||||
extern bool GHOST_SupportsPrimaryClipboard(void);
|
||||
|
||||
/**
|
||||
* Assign the callback which generates a back-trace (may be NULL).
|
||||
*/
|
||||
|
|
|
@ -327,6 +327,11 @@ class GHOST_ISystem {
|
|||
*/
|
||||
virtual bool supportsWindowPosition() = 0;
|
||||
|
||||
/**
|
||||
* Return true when a separate primary clipboard is supported.
|
||||
*/
|
||||
virtual bool supportsPrimaryClipboard() = 0;
|
||||
|
||||
/**
|
||||
* Focus window after opening, or put them in the background.
|
||||
*/
|
||||
|
|
|
@ -907,6 +907,12 @@ bool GHOST_SupportsWindowPosition(void)
|
|||
return system->supportsWindowPosition();
|
||||
}
|
||||
|
||||
bool GHOST_SupportsPrimaryClipboard(void)
|
||||
{
|
||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||
return system->supportsPrimaryClipboard();
|
||||
}
|
||||
|
||||
void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
|
||||
{
|
||||
GHOST_ISystem::setBacktraceFn(backtrace_fn);
|
||||
|
|
|
@ -428,6 +428,11 @@ bool GHOST_System::supportsWindowPosition()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GHOST_System::supportsPrimaryClipboard()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GHOST_System::initDebug(GHOST_Debug debug)
|
||||
{
|
||||
m_is_debug_enabled = debug.flags & GHOST_kDebugDefault;
|
||||
|
|
|
@ -152,6 +152,7 @@ class GHOST_System : public GHOST_ISystem {
|
|||
|
||||
bool supportsCursorWarp(void);
|
||||
bool supportsWindowPosition(void);
|
||||
bool supportsPrimaryClipboard(void);
|
||||
|
||||
/**
|
||||
* Focus window after opening, or put them in the background.
|
||||
|
|
|
@ -2016,7 +2016,13 @@ static char *read_file_as_buffer(const int fd, const bool nil_terminate, size_t
|
|||
{
|
||||
struct ByteChunk {
|
||||
ByteChunk *next;
|
||||
char data[4096 - sizeof(ByteChunk *)];
|
||||
/* NOTE(@ideasman42): On GNOME-SHELL-43.3, non powers of two values
|
||||
* (1023 or 4088 for e.g.) makes `read()` return longer values than are actually read
|
||||
* (causing uninitialized memory to be used) as well as truncating the end of the buffer.
|
||||
* The WAYLAND spec doesn't mention buffer-size so this may be a bug in GNOME-SHELL.
|
||||
* Whatever the case, using a power of two isn't a problem (besides some slop-space waste).
|
||||
* This works in KDE & WLROOTS based compositors, see: #106040. */
|
||||
char data[4096];
|
||||
};
|
||||
ByteChunk *chunk_first = nullptr, **chunk_link_p = &chunk_first;
|
||||
bool ok = true;
|
||||
|
@ -6682,6 +6688,11 @@ bool GHOST_SystemWayland::supportsWindowPosition()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::supportsPrimaryClipboard()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
|
||||
{
|
||||
/* Caller must lock `server_mutex`. */
|
||||
|
|
|
@ -144,6 +144,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
|
||||
bool supportsCursorWarp() override;
|
||||
bool supportsWindowPosition() override;
|
||||
bool supportsPrimaryClipboard() override;
|
||||
|
||||
/* WAYLAND utility functions (share window/system logic). */
|
||||
|
||||
|
|
|
@ -1740,6 +1740,11 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
|||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
bool GHOST_SystemX11::supportsPrimaryClipboard()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
|
||||
{
|
||||
GHOST_ASSERT((bad_wind != nullptr), "addDirtyWindow() nullptr ptr trapped (window)");
|
||||
|
|
|
@ -168,6 +168,8 @@ class GHOST_SystemX11 : public GHOST_System {
|
|||
*/
|
||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||
|
||||
bool supportsPrimaryClipboard() override;
|
||||
|
||||
/**
|
||||
* Flag a window as dirty. This will
|
||||
* generate a GHOST window update event on a call to processEvents()
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
include
|
||||
../../extern/renderdoc/include
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/renderdoc_api.cc
|
||||
|
||||
include/renderdoc_api.hh
|
||||
)
|
||||
|
||||
blender_add_lib(bf_intern_renderdoc_dynload "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
#include "renderdoc_app.h"
|
||||
|
||||
namespace renderdoc::api {
|
||||
class Renderdoc {
|
||||
private:
|
||||
enum class State {
|
||||
/**
|
||||
* Initial state of the API indicating that the API hasn't checked if it can find renderdoc.
|
||||
*/
|
||||
UNINITIALIZED,
|
||||
|
||||
/**
|
||||
* API has looked for renderdoc, but couldn't find it. This indicates that renderdoc isn't
|
||||
* available on the platform, or wasn't registered correctly.
|
||||
*/
|
||||
NOT_FOUND,
|
||||
|
||||
/**
|
||||
* API has loaded the symbols of renderdoc.
|
||||
*/
|
||||
LOADED,
|
||||
};
|
||||
State state_ = State::UNINITIALIZED;
|
||||
RENDERDOC_API_1_6_0 *renderdoc_api_ = nullptr;
|
||||
|
||||
public:
|
||||
bool start_frame_capture(RENDERDOC_DevicePointer device_handle,
|
||||
RENDERDOC_WindowHandle window_handle);
|
||||
void end_frame_capture(RENDERDOC_DevicePointer device_handle,
|
||||
RENDERDOC_WindowHandle window_handle);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Check if renderdoc has been loaded.
|
||||
*
|
||||
* When not loaded it tries to load the API, but only tries to do it once.
|
||||
*/
|
||||
bool check_loaded();
|
||||
void load();
|
||||
};
|
||||
} // namespace renderdoc::api
|
|
@ -0,0 +1,77 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
#include "renderdoc_api.hh"
|
||||
|
||||
#ifdef _WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <Windows.h>
|
||||
#else
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
namespace renderdoc::api {
|
||||
bool Renderdoc::start_frame_capture(RENDERDOC_DevicePointer device_handle,
|
||||
RENDERDOC_WindowHandle window_handle)
|
||||
{
|
||||
if (!check_loaded()) {
|
||||
return false;
|
||||
}
|
||||
renderdoc_api_->StartFrameCapture(device_handle, window_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderdoc::end_frame_capture(RENDERDOC_DevicePointer device_handle,
|
||||
RENDERDOC_WindowHandle window_handle)
|
||||
|
||||
{
|
||||
if (!check_loaded()) {
|
||||
return;
|
||||
}
|
||||
renderdoc_api_->EndFrameCapture(device_handle, window_handle);
|
||||
}
|
||||
|
||||
bool Renderdoc::check_loaded()
|
||||
{
|
||||
switch (state_) {
|
||||
case State::UNINITIALIZED:
|
||||
load();
|
||||
return renderdoc_api_ != nullptr;
|
||||
break;
|
||||
case State::NOT_FOUND:
|
||||
return false;
|
||||
case State::LOADED:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Renderdoc::load()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (HMODULE mod = GetModuleHandleA("renderdoc.dll")) {
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod,
|
||||
"RENDERDOC_GetAPI");
|
||||
RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&renderdoc_api_);
|
||||
}
|
||||
#else
|
||||
if (void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD)) {
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
|
||||
RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&renderdoc_api_);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (renderdoc_api_ != nullptr) {
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
renderdoc_api_->GetAPIVersion(&major, &minor, &patch);
|
||||
std::cout << "Found renderdoc API [" << major << "." << minor << "." << patch << "]";
|
||||
}
|
||||
else {
|
||||
std::cerr << "Unable to load renderdoc API.\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace renderdoc::api
|
|
@ -208,6 +208,7 @@ url_manual_mapping = (
|
|||
("bpy.types.brushgpencilsettings.use_jitter_pressure*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-jitter-pressure"),
|
||||
("bpy.types.brushgpencilsettings.use_random_press_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-uv"),
|
||||
("bpy.types.brushgpencilsettings.use_settings_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-random"),
|
||||
("bpy.types.brushgpencilsettings.vertex_color_factor*", "grease_pencil/modes/draw/tool_settings/color.html#bpy-types-brushgpencilsettings-vertex-color-factor"),
|
||||
("bpy.types.clothcollisionsettings.collision_quality*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collision-quality"),
|
||||
("bpy.types.clothcollisionsettings.self_distance_min*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-self-distance-min"),
|
||||
("bpy.types.clothsettings.internal_spring_max_length*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring-max-length"),
|
||||
|
@ -239,6 +240,7 @@ url_manual_mapping = (
|
|||
("bpy.types.sequencertimelineoverlay.show_thumbnails*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-thumbnails"),
|
||||
("bpy.types.spacespreadsheet.geometry_component_type*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-geometry-component-type"),
|
||||
("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"),
|
||||
("bpy.types.view3doverlay.sculpt_curves_cage_opacity*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-view3doverlay-sculpt-curves-cage-opacity"),
|
||||
("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"),
|
||||
("bpy.ops.mesh.customdata_bevel_weight_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-vertex-clear"),
|
||||
("bpy.ops.mesh.customdata_custom_splitnormals_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-clear"),
|
||||
|
@ -382,7 +384,6 @@ url_manual_mapping = (
|
|||
("bpy.types.freestylelineset.select_by_edge_types*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-edge-types"),
|
||||
("bpy.types.freestylelineset.select_by_face_marks*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-face-marks"),
|
||||
("bpy.types.geometrynodeinputcurvehandlepositions*", "modeling/geometry_nodes/curve/read/curve_handle_position.html#bpy-types-geometrynodeinputcurvehandlepositions"),
|
||||
("bpy.types.geometrynodeinputedgepathstoselection*", "modeling/geometry_nodes/mesh/operations/edge_paths_to_selection.html#bpy-types-geometrynodeinputedgepathstoselection"),
|
||||
("bpy.types.linestyle*modifier_distancefromcamera*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_camera.html#bpy-types-linestyle-modifier-distancefromcamera"),
|
||||
("bpy.types.linestyle*modifier_distancefromobject*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_object.html#bpy-types-linestyle-modifier-distancefromobject"),
|
||||
("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"),
|
||||
|
@ -406,9 +407,11 @@ url_manual_mapping = (
|
|||
("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"),
|
||||
("bpy.types.toolsettings.use_keyframe_cycle_aware*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-cycle-aware"),
|
||||
("bpy.types.toolsettings.use_keyframe_insert_auto*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-insert-auto"),
|
||||
("bpy.types.view3doverlay.show_sculpt_curves_cage*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-view3doverlay-show-sculpt-curves-cage"),
|
||||
("bpy.types.viewlayer.use_pass_cryptomatte_object*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-object"),
|
||||
("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"),
|
||||
("bpy.ops.ed.lib_id_generate_preview_from_object*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview-from-object"),
|
||||
("bpy.ops.paint.vertex_color_brightness_contrast*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-brightness-contrast"),
|
||||
("bpy.types.brushcurvessculptsettings.add_amount*", "sculpt_paint/curves_sculpting/tools/add_curves.html#bpy-types-brushcurvessculptsettings-add-amount"),
|
||||
("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"),
|
||||
("bpy.types.brushgpencilsettings.random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-strength"),
|
||||
|
@ -449,6 +452,7 @@ url_manual_mapping = (
|
|||
("bpy.types.movietrackingcamera.distortion_model*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-distortion-model"),
|
||||
("bpy.types.movietrackingtrack.use_alpha_preview*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-alpha-preview"),
|
||||
("bpy.types.movietrackingtrack.use_green_channel*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-green-channel"),
|
||||
("bpy.types.nodesocketinterface.hide_in_modifier*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-hide-in-modifier"),
|
||||
("bpy.types.rendersettings.resolution_percentage*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-percentage"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"),
|
||||
("bpy.types.softbodysettings.use_estimate_matrix*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-use-estimate-matrix"),
|
||||
|
@ -524,6 +528,7 @@ url_manual_mapping = (
|
|||
("bpy.types.softbodysettings.use_edge_collision*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-edge-collision"),
|
||||
("bpy.types.softbodysettings.use_face_collision*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-face-collision"),
|
||||
("bpy.types.softbodysettings.use_self_collision*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-use-self-collision"),
|
||||
("bpy.types.spaceclipeditor.show_gizmo_navigate*", "editors/clip/display/gizmo.html#bpy-types-spaceclipeditor-show-gizmo-navigate"),
|
||||
("bpy.types.spacegrapheditor.show_extrapolation*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-extrapolation"),
|
||||
("bpy.types.spaceoutliner.use_filter_collection*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-collection"),
|
||||
("bpy.types.spacesequenceeditor.cursor_location*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-cursor-location"),
|
||||
|
@ -534,6 +539,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spacespreadsheetrowfilter.operation*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-operation"),
|
||||
("bpy.types.spacespreadsheetrowfilter.threshold*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-threshold"),
|
||||
("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"),
|
||||
("bpy.types.transformsequence.use_uniform_scale*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-use-uniform-scale"),
|
||||
("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"),
|
||||
("bpy.types.view3doverlay.show_viewer_attribute*", "modeling/geometry_nodes/output/viewer.html#bpy-types-view3doverlay-show-viewer-attribute"),
|
||||
("bpy.ops.gpencil.bake_grease_pencil_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-grease-pencil-animation"),
|
||||
|
@ -577,7 +583,6 @@ url_manual_mapping = (
|
|||
("bpy.types.freestylelinestyle.use_same_object*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-same-object"),
|
||||
("bpy.types.functionnodeinputspecialcharacters*", "modeling/geometry_nodes/utilities/text/special_characters.html#bpy-types-functionnodeinputspecialcharacters"),
|
||||
("bpy.types.geometrynodecurveendpointselection*", "modeling/geometry_nodes/curve/read/endpoint_selection.html#bpy-types-geometrynodecurveendpointselection"),
|
||||
("bpy.types.geometrynodeinputedgepathstocurves*", "modeling/geometry_nodes/mesh/operations/edge_paths_to_curves.html#bpy-types-geometrynodeinputedgepathstocurves"),
|
||||
("bpy.types.geometrynodeinputmeshedgeneighbors*", "modeling/geometry_nodes/mesh/read/edge_neighbors.html#bpy-types-geometrynodeinputmeshedgeneighbors"),
|
||||
("bpy.types.geometrynodeinputmeshfaceneighbors*", "modeling/geometry_nodes/mesh/read/face_neighbors.html#bpy-types-geometrynodeinputmeshfaceneighbors"),
|
||||
("bpy.types.geometrynodeinputshortestedgepaths*", "modeling/geometry_nodes/mesh/read/shortest_edge_paths.html#bpy-types-geometrynodeinputshortestedgepaths"),
|
||||
|
@ -610,9 +615,11 @@ url_manual_mapping = (
|
|||
("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"),
|
||||
("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"),
|
||||
("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"),
|
||||
("bpy.types.transformsequence.translation_unit*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-translation-unit"),
|
||||
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
|
||||
("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
|
||||
("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"),
|
||||
("bpy.ops.object.geometry_nodes_move_to_nodes*", "modeling/modifiers/generate/geometry_nodes.html#bpy-ops-object-geometry-nodes-move-to-nodes"),
|
||||
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
|
||||
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
|
||||
("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"),
|
||||
|
@ -625,6 +632,7 @@ url_manual_mapping = (
|
|||
("bpy.types.cyclescamerasettings.fisheye_lens*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-lens"),
|
||||
("bpy.types.cyclesobjectsettings.motion_steps*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-motion-steps"),
|
||||
("bpy.types.cyclesrendersettings.filter_width*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-filter-width"),
|
||||
("bpy.types.fileassetselectparams.import_type*", "editors/asset_browser.html#bpy-types-fileassetselectparams-import-type"),
|
||||
("bpy.types.fluiddomainsettings.cfl_condition*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-cfl-condition"),
|
||||
("bpy.types.fluiddomainsettings.show_velocity*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-show-velocity"),
|
||||
("bpy.types.fluiddomainsettings.timesteps_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-max"),
|
||||
|
@ -672,9 +680,11 @@ url_manual_mapping = (
|
|||
("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"),
|
||||
("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-collections"),
|
||||
("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"),
|
||||
("bpy.types.transformsequence.translate_start*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-translate-start"),
|
||||
("bpy.types.view3doverlay.fade_inactive_alpha*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-fade-inactive-alpha"),
|
||||
("bpy.types.view3doverlay.wireframe_threshold*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-threshold"),
|
||||
("bpy.types.viewlayer.active_lightgroup_index*", "render/layers/passes.html#bpy-types-viewlayer-active-lightgroup-index"),
|
||||
("bpy.ops.brush.sculpt_curves_falloff_preset*", "sculpt_paint/curves_sculpting/tools/comb_curves.html#bpy-ops-brush-sculpt-curves-falloff-preset"),
|
||||
("bpy.ops.ed.lib_id_override_editable_toggle*", "editors/outliner/interface.html#bpy-ops-ed-lib-id-override-editable-toggle"),
|
||||
("bpy.ops.geometry.color_attribute_duplicate*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-duplicate"),
|
||||
("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"),
|
||||
|
@ -683,9 +693,11 @@ url_manual_mapping = (
|
|||
("bpy.ops.scene.freestyle_alpha_modifier_add*", "render/freestyle/view_layer/line_style/alpha.html#bpy-ops-scene-freestyle-alpha-modifier-add"),
|
||||
("bpy.ops.scene.freestyle_color_modifier_add*", "render/freestyle/view_layer/line_style/color.html#bpy-ops-scene-freestyle-color-modifier-add"),
|
||||
("bpy.ops.scene.view_layer_remove_lightgroup*", "render/layers/passes.html#bpy-ops-scene-view-layer-remove-lightgroup"),
|
||||
("bpy.ops.sequencer.scene_frame_range_update*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-scene-frame-range-update"),
|
||||
("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"),
|
||||
("bpy.types.brushgpencilsettings.eraser_mode*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-mode"),
|
||||
("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"),
|
||||
("bpy.types.brushgpencilsettings.vertex_mode*", "grease_pencil/modes/draw/tool_settings/color.html#bpy-types-brushgpencilsettings-vertex-mode"),
|
||||
("bpy.types.clothsettings.use_sewing_springs*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-use-sewing-springs"),
|
||||
("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"),
|
||||
("bpy.types.cyclescamerasettings.fisheye_fov*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-fov"),
|
||||
|
@ -720,8 +732,8 @@ url_manual_mapping = (
|
|||
("bpy.types.freestylesettings.use_smoothness*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-smoothness"),
|
||||
("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve/primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"),
|
||||
("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve/primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"),
|
||||
("bpy.types.geometrynoderemovenamedattribute*", "modeling/geometry_nodes/attribute/remove_named_attribute.html#bpy-types-geometrynoderemovenamedattribute"),
|
||||
("bpy.types.geometrynodesamplenearestsurface*", "modeling/geometry_nodes/mesh/operations/sample_nearest_surface.html#bpy-types-geometrynodesamplenearestsurface"),
|
||||
("bpy.types.geometrynodeedgepathstoselection*", "modeling/geometry_nodes/mesh/operations/edge_paths_to_selection.html#bpy-types-geometrynodeedgepathstoselection"),
|
||||
("bpy.types.geometrynodesamplenearestsurface*", "modeling/geometry_nodes/mesh/sample/sample_nearest_surface.html#bpy-types-geometrynodesamplenearestsurface"),
|
||||
("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"),
|
||||
("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"),
|
||||
("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"),
|
||||
|
@ -745,6 +757,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spacesequenceeditor.display_mode*", "editors/video_sequencer/preview/display/display_mode.html#bpy-types-spacesequenceeditor-display-mode"),
|
||||
("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"),
|
||||
("bpy.types.toolsettings.use_snap_selectable*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-selectable"),
|
||||
("bpy.types.transformsequence.rotation_start*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-rotation-start"),
|
||||
("bpy.types.view3doverlay.show_fade_inactive*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-fade-inactive"),
|
||||
("bpy.types.viewlayer.pass_cryptomatte_depth*", "render/layers/passes.html#bpy-types-viewlayer-pass-cryptomatte-depth"),
|
||||
("bpy.ops.clip.stabilize_2d_rotation_select*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-stabilize-2d-rotation-select"),
|
||||
|
@ -764,6 +777,7 @@ url_manual_mapping = (
|
|||
("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"),
|
||||
("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"),
|
||||
("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"),
|
||||
("bpy.types.brush.use_color_as_displacement*", "sculpt_paint/brush/texture.html#bpy-types-brush-use-color-as-displacement"),
|
||||
("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-jitter"),
|
||||
("bpy.types.brushgpencilsettings.show_lasso*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-show-lasso"),
|
||||
("bpy.types.clothsettings.bending_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-bending-stiffness"),
|
||||
|
@ -795,6 +809,7 @@ url_manual_mapping = (
|
|||
("bpy.types.freestylelinestyle.use_chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chaining"),
|
||||
("bpy.types.freestylesettings.sphere_radius*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-sphere-radius"),
|
||||
("bpy.types.geometrynodeattributedomainsize*", "modeling/geometry_nodes/attribute/domain_size.html#bpy-types-geometrynodeattributedomainsize"),
|
||||
("bpy.types.geometrynodeinputnamedattribute*", "modeling/geometry_nodes/geometry/read/named_attribute.html#bpy-types-geometrynodeinputnamedattribute"),
|
||||
("bpy.types.geometrynodesetsplineresolution*", "modeling/geometry_nodes/curve/write/set_spline_resolution.html#bpy-types-geometrynodesetsplineresolution"),
|
||||
("bpy.types.geometrynodestorenamedattribute*", "modeling/geometry_nodes/attribute/store_named_attribute.html#bpy-types-geometrynodestorenamedattribute"),
|
||||
("bpy.types.gpencillayer.annotation_opacity*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-opacity"),
|
||||
|
@ -837,8 +852,10 @@ url_manual_mapping = (
|
|||
("bpy.types.toolsettings.use_snap_sequencer*", "video_editing/edit/montage/editing.html#bpy-types-toolsettings-use-snap-sequencer"),
|
||||
("bpy.types.toolsettings.use_snap_translate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-translate"),
|
||||
("bpy.types.toolsettings.use_uv_select_sync*", "editors/uv/selecting.html#bpy-types-toolsettings-use-uv-select-sync"),
|
||||
("bpy.types.transformsequence.interpolation*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-interpolation"),
|
||||
("bpy.types.view3doverlay.wireframe_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-opacity"),
|
||||
("bpy.ops.asset.open_containing_blend_file*", "editors/asset_browser.html#bpy-ops-asset-open-containing-blend-file"),
|
||||
("bpy.ops.geometry.color_attribute_convert*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-convert"),
|
||||
("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"),
|
||||
("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"),
|
||||
("bpy.ops.node.collapse_hide_unused_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-collapse-hide-unused-toggle"),
|
||||
|
@ -988,9 +1005,12 @@ url_manual_mapping = (
|
|||
("bpy.types.freestylelinestyle.split_dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-dash"),
|
||||
("bpy.types.freestylesettings.use_culling*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-culling"),
|
||||
("bpy.types.geometrynodeduplicateelements*", "modeling/geometry_nodes/geometry/operations/duplicate_elements.html#bpy-types-geometrynodeduplicateelements"),
|
||||
("bpy.types.geometrynodeedgepathstocurves*", "modeling/geometry_nodes/mesh/operations/edge_paths_to_curves.html#bpy-types-geometrynodeedgepathstocurves"),
|
||||
("bpy.types.geometrynodeedgestofacegroups*", "modeling/geometry_nodes/mesh/read/edges_to_face_groups.html#bpy-types-geometrynodeedgestofacegroups"),
|
||||
("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/read/face_area.html#bpy-types-geometrynodeinputmeshfacearea"),
|
||||
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/read/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
|
||||
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
|
||||
("bpy.types.geometrynodeinterpolatecurves*", "modeling/geometry_nodes/curve/operations/interpolate_curves.html#bpy-types-geometrynodeinterpolatecurves"),
|
||||
("bpy.types.geometrynodematerialselection*", "modeling/geometry_nodes/material/material_selection.html#bpy-types-geometrynodematerialselection"),
|
||||
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
|
||||
("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"),
|
||||
|
@ -1027,6 +1047,7 @@ url_manual_mapping = (
|
|||
("bpy.types.toolsettings.use_snap_nonedit*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-nonedit"),
|
||||
("bpy.types.toolsettings.use_snap_project*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-project"),
|
||||
("bpy.types.transformorientationslot.type*", "editors/3dview/controls/orientation.html#bpy-types-transformorientationslot-type"),
|
||||
("bpy.types.transformsequence.scale_start*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence-scale-start"),
|
||||
("bpy.types.unitsettings.temperature_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-temperature-unit"),
|
||||
("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"),
|
||||
("bpy.types.view3doverlay.show_wireframes*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-wireframes"),
|
||||
|
@ -1038,6 +1059,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"),
|
||||
("bpy.ops.object.multires_rebuild_subdiv*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-rebuild-subdiv"),
|
||||
("bpy.ops.outliner.liboverride_operation*", "files/linked_libraries/library_overrides.html#bpy-ops-outliner-liboverride-operation"),
|
||||
("bpy.ops.paint.vertex_color_from_weight*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-from-weight"),
|
||||
("bpy.ops.screen.space_type_set_or_cycle*", "editors/index.html#bpy-ops-screen-space-type-set-or-cycle"),
|
||||
("bpy.ops.sculpt.dynamic_topology_toggle*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-ops-sculpt-dynamic-topology-toggle"),
|
||||
("bpy.ops.sequencer.select_side_of_frame*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-side-of-frame"),
|
||||
|
@ -1161,6 +1183,7 @@ url_manual_mapping = (
|
|||
("bpy.types.compositornodedistancematte*", "compositing/types/matte/distance_key.html#bpy-types-compositornodedistancematte"),
|
||||
("bpy.types.compositornodeseparatecolor*", "compositing/types/converter/separate_color.html#bpy-types-compositornodeseparatecolor"),
|
||||
("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"),
|
||||
("bpy.types.curves.use_sculpt_collision*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-use-sculpt-collision"),
|
||||
("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels.html#bpy-types-dopesheet-use-filter-invert"),
|
||||
("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"),
|
||||
("bpy.types.ffmpegsettings.audio_volume*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-volume"),
|
||||
|
@ -1181,9 +1204,10 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodecurvesplinetype*", "modeling/geometry_nodes/curve/write/set_spline_type.html#bpy-types-geometrynodecurvesplinetype"),
|
||||
("bpy.types.geometrynodeinputmeshisland*", "modeling/geometry_nodes/mesh/read/mesh_island.html#bpy-types-geometrynodeinputmeshisland"),
|
||||
("bpy.types.geometrynodemergebydistance*", "modeling/geometry_nodes/geometry/operations/merge_by_distance.html#bpy-types-geometrynodemergebydistance"),
|
||||
("bpy.types.geometrynoderemoveattribute*", "modeling/geometry_nodes/attribute/remove_named_attribute.html#bpy-types-geometrynoderemoveattribute"),
|
||||
("bpy.types.geometrynodereplacematerial*", "modeling/geometry_nodes/material/replace_material.html#bpy-types-geometrynodereplacematerial"),
|
||||
("bpy.types.geometrynoderotateinstances*", "modeling/geometry_nodes/instances/rotate_instances.html#bpy-types-geometrynoderotateinstances"),
|
||||
("bpy.types.geometrynodesampleuvsurface*", "modeling/geometry_nodes/mesh/operations/sample_uv_surface.html#bpy-types-geometrynodesampleuvsurface"),
|
||||
("bpy.types.geometrynodesampleuvsurface*", "modeling/geometry_nodes/mesh/sample/sample_uv_surface.html#bpy-types-geometrynodesampleuvsurface"),
|
||||
("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/write/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"),
|
||||
("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/read/spline_parameter.html#bpy-types-geometrynodesplineparameter"),
|
||||
("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"),
|
||||
|
@ -1197,6 +1221,7 @@ url_manual_mapping = (
|
|||
("bpy.types.movietrackingcamera.brown_p*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-p"),
|
||||
("bpy.types.object.visible_transmission*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-transmission"),
|
||||
("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"),
|
||||
("bpy.types.pointlight.shadow_soft_size*", "render/lights/light_object.html#bpy-types-pointlight-shadow-soft-size"),
|
||||
("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"),
|
||||
("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"),
|
||||
("bpy.types.rendersettings.resolution_x*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-x"),
|
||||
|
@ -1277,7 +1302,6 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/operations/delete_geometry.html#bpy-types-geometrynodedeletegeometry"),
|
||||
("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/read/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"),
|
||||
("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene/scene_time.html#bpy-types-geometrynodeinputscenetime"),
|
||||
("bpy.types.geometrynodenamedattribute*", "modeling/geometry_nodes/geometry/read/named_attribute.html#bpy-types-geometrynodenamedattribute"),
|
||||
("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"),
|
||||
("bpy.types.geometrynodescaleinstances*", "modeling/geometry_nodes/instances/scale_instances.html#bpy-types-geometrynodescaleinstances"),
|
||||
("bpy.types.geometrynodesetcurvenormal*", "modeling/geometry_nodes/curve/write/set_curve_normal.html#bpy-types-geometrynodesetcurvenormal"),
|
||||
|
@ -1309,10 +1333,12 @@ url_manual_mapping = (
|
|||
("bpy.types.softbodysettings.ball_damp*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-ball-damp"),
|
||||
("bpy.types.softbodysettings.ball_size*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-ball-size"),
|
||||
("bpy.types.softbodysettings.use_edges*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-edges"),
|
||||
("bpy.types.spaceclipeditor.show_gizmo*", "editors/clip/display/gizmo.html#bpy-types-spaceclipeditor-show-gizmo"),
|
||||
("bpy.types.spacefilebrowser.bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-bookmarks"),
|
||||
("bpy.types.spaceoutliner.display_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-display-mode"),
|
||||
("bpy.types.spaceoutliner.filter_state*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-state"),
|
||||
("bpy.types.spaceuveditor.show_stretch*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-stretch"),
|
||||
("bpy.types.spotlight.shadow_soft_size*", "render/lights/light_object.html#bpy-types-spotlight-shadow-soft-size"),
|
||||
("bpy.types.toolsettings.keyframe_type*", "editors/timeline.html#bpy-types-toolsettings-keyframe-type"),
|
||||
("bpy.types.toolsettings.snap_elements*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements"),
|
||||
("bpy.types.toolsettings.use_snap_edit*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-edit"),
|
||||
|
@ -1321,6 +1347,7 @@ url_manual_mapping = (
|
|||
("bpy.types.viewlayer.active_aov_index*", "render/layers/passes.html#bpy-types-viewlayer-active-aov-index"),
|
||||
("bpy.ops.clip.tracking_object_remove*", "movie_clip/tracking/clip/sidebar/track/objects.html#bpy-ops-clip-tracking-object-remove"),
|
||||
("bpy.ops.constraint.copy_to_selected*", "animation/constraints/interface/header.html#bpy-ops-constraint-copy-to-selected"),
|
||||
("bpy.ops.curves.set_selection_domain*", "modeling/curves/primitives.html#bpy-ops-curves-set-selection-domain"),
|
||||
("bpy.ops.gpencil.bake_mesh_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-mesh-animation"),
|
||||
("bpy.ops.gpencil.select_vertex_color*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-vertex-color"),
|
||||
("bpy.ops.gpencil.set_active_material*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-set-active-material"),
|
||||
|
@ -1329,6 +1356,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.gpencil.vertex_color_invert*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-invert"),
|
||||
("bpy.ops.gpencil.vertex_color_levels*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-levels"),
|
||||
("bpy.ops.mask.slide_spline_curvature*", "movie_clip/masking/editing.html#bpy-ops-mask-slide-spline-curvature"),
|
||||
("bpy.ops.mesh.flip_quad_tessellation*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-flip-quad-tessellation"),
|
||||
("bpy.ops.mesh.primitive_cylinder_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cylinder-add"),
|
||||
("bpy.ops.mesh.set_normals_from_faces*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-set-normals-from-faces"),
|
||||
("bpy.ops.mesh.shape_propagate_to_all*", "modeling/meshes/editing/vertex/propagate_shapes.html#bpy-ops-mesh-shape-propagate-to-all"),
|
||||
|
@ -1390,6 +1418,7 @@ url_manual_mapping = (
|
|||
("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"),
|
||||
("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"),
|
||||
("bpy.types.geometrynodeblurattribute*", "modeling/geometry_nodes/attribute/blur_attribute.html#bpy-types-geometrynodeblurattribute"),
|
||||
("bpy.types.geometrynodecornersofface*", "modeling/geometry_nodes/mesh/topology/corners_of_face.html#bpy-types-geometrynodecornersofface"),
|
||||
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
|
||||
("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"),
|
||||
("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"),
|
||||
|
@ -1454,6 +1483,7 @@ url_manual_mapping = (
|
|||
("bpy.types.worldmistsettings.falloff*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-falloff"),
|
||||
("bpy.ops.clip.lock_selection_toggle*", "editors/clip/introduction.html#bpy-ops-clip-lock-selection-toggle"),
|
||||
("bpy.ops.ed.lib_id_generate_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview"),
|
||||
("bpy.ops.geometry.attribute_convert*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-geometry-attribute-convert"),
|
||||
("bpy.ops.mesh.customdata_mask_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-mask-clear"),
|
||||
("bpy.ops.mesh.customdata_skin_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-skin-clear"),
|
||||
("bpy.ops.mesh.extrude_vertices_move*", "modeling/meshes/editing/vertex/extrude_vertices.html#bpy-ops-mesh-extrude-vertices-move"),
|
||||
|
@ -1564,6 +1594,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spaceuveditor.show_faces*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-faces"),
|
||||
("bpy.types.spaceuveditor.uv_opacity*", "editors/uv/overlays.html#bpy-types-spaceuveditor-uv-opacity"),
|
||||
("bpy.types.subdividegpencilmodifier*", "grease_pencil/modifiers/generate/subdivide.html#bpy-types-subdividegpencilmodifier"),
|
||||
("bpy.types.texturenodehuesaturation*", "editors/texture_node/types/color/hue_saturation.html#bpy-types-texturenodehuesaturation"),
|
||||
("bpy.types.texturenodeseparatecolor*", "editors/texture_node/types/color/separate_color.html#bpy-types-texturenodeseparatecolor"),
|
||||
("bpy.types.thicknessgpencilmodifier*", "grease_pencil/modifiers/deform/thickness.html#bpy-types-thicknessgpencilmodifier"),
|
||||
("bpy.types.toolsettings.snap_target*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-target"),
|
||||
|
@ -1599,6 +1630,9 @@ url_manual_mapping = (
|
|||
("bpy.ops.object.multires_subdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-subdivide"),
|
||||
("bpy.ops.object.shape_key_transfer*", "animation/shape_keys/shape_keys_panel.html#bpy-ops-object-shape-key-transfer"),
|
||||
("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"),
|
||||
("bpy.ops.paint.vertex_color_invert*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-invert"),
|
||||
("bpy.ops.paint.vertex_color_levels*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-levels"),
|
||||
("bpy.ops.paint.vertex_color_smooth*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-smooth"),
|
||||
("bpy.ops.poselib.create_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-create-pose-asset"),
|
||||
("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"),
|
||||
("bpy.ops.render.play_rendered_anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"),
|
||||
|
@ -1624,6 +1658,7 @@ url_manual_mapping = (
|
|||
("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"),
|
||||
("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"),
|
||||
("bpy.types.compositornodecomposite*", "compositing/types/output/composite.html#bpy-types-compositornodecomposite"),
|
||||
("bpy.types.compositornodecornerpin*", "compositing/types/distort/corner_pin.html#bpy-types-compositornodecornerpin"),
|
||||
("bpy.types.compositornodedespeckle*", "compositing/types/filter/despeckle.html#bpy-types-compositornodedespeckle"),
|
||||
("bpy.types.compositornodediffmatte*", "compositing/types/matte/difference_key.html#bpy-types-compositornodediffmatte"),
|
||||
("bpy.types.compositornodelumamatte*", "compositing/types/matte/luminance_key.html#bpy-types-compositornodelumamatte"),
|
||||
|
@ -1661,7 +1696,7 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodeinputradius*", "modeling/geometry_nodes/geometry/read/radius.html#bpy-types-geometrynodeinputradius"),
|
||||
("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/operations/mesh_boolean.html#bpy-types-geometrynodemeshboolean"),
|
||||
("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/operations/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"),
|
||||
("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/operations/sample_curve.html#bpy-types-geometrynodesamplecurve"),
|
||||
("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/sample/sample_curve.html#bpy-types-geometrynodesamplecurve"),
|
||||
("bpy.types.geometrynodesampleindex*", "modeling/geometry_nodes/geometry/sample/sample_index.html#bpy-types-geometrynodesampleindex"),
|
||||
("bpy.types.geometrynodesetmaterial*", "modeling/geometry_nodes/material/set_material.html#bpy-types-geometrynodesetmaterial"),
|
||||
("bpy.types.geometrynodesetposition*", "modeling/geometry_nodes/geometry/write/set_position.html#bpy-types-geometrynodesetposition"),
|
||||
|
@ -1729,7 +1764,6 @@ url_manual_mapping = (
|
|||
("bpy.ops.mesh.primitive_plane_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-plane-add"),
|
||||
("bpy.ops.mesh.primitive_torus_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-torus-add"),
|
||||
("bpy.ops.mesh.select_non_manifold*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-non-manifold"),
|
||||
("bpy.ops.object.attribute_convert*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-convert"),
|
||||
("bpy.ops.object.constraints_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-clear"),
|
||||
("bpy.ops.object.quadriflow_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-quadriflow-remesh"),
|
||||
("bpy.ops.object.vertex_group_copy*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy"),
|
||||
|
@ -1780,6 +1814,7 @@ url_manual_mapping = (
|
|||
("bpy.types.compositornodesetalpha*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha"),
|
||||
("bpy.types.compositornodesunbeams*", "compositing/types/filter/sun_beams.html#bpy-types-compositornodesunbeams"),
|
||||
("bpy.types.compositornodetrackpos*", "compositing/types/input/track_position.html#bpy-types-compositornodetrackpos"),
|
||||
("bpy.types.compositornodevaltorgb*", "compositing/types/converter/color_ramp.html#bpy-types-compositornodevaltorgb"),
|
||||
("bpy.types.compositornodezcombine*", "compositing/types/color/z_combine.html#bpy-types-compositornodezcombine"),
|
||||
("bpy.types.constraint.owner_space*", "animation/constraints/interface/common.html#bpy-types-constraint-owner-space"),
|
||||
("bpy.types.copylocationconstraint*", "animation/constraints/transform/copy_location.html#bpy-types-copylocationconstraint"),
|
||||
|
@ -1802,7 +1837,7 @@ url_manual_mapping = (
|
|||
("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/math/float_to_integer.html#bpy-types-functionnodefloattoint"),
|
||||
("bpy.types.functionnodeinputcolor*", "modeling/geometry_nodes/input/constant/color.html#bpy-types-functionnodeinputcolor"),
|
||||
("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/operations/convex_hull.html#bpy-types-geometrynodeconvexhull"),
|
||||
("bpy.types.geometrynodeimageinput*", "modeling/geometry_nodes/input/constant/image.html#bpy-types-geometrynodeimageinput"),
|
||||
("bpy.types.geometrynodeinputimage*", "modeling/geometry_nodes/input/constant/image.html#bpy-types-geometrynodeinputimage"),
|
||||
("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/geometry/read/input_index.html#bpy-types-geometrynodeinputindex"),
|
||||
("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/scene/is_viewport.html#bpy-types-geometrynodeisviewport"),
|
||||
("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh/primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"),
|
||||
|
@ -1903,6 +1938,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.outliner.show_hierarchy*", "editors/outliner/editing.html#bpy-ops-outliner-show-hierarchy"),
|
||||
("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"),
|
||||
("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/brush/brush_settings.html#bpy-ops-paint-brush-colors-flip"),
|
||||
("bpy.ops.paint.vertex_color_dirt*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-dirt"),
|
||||
("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"),
|
||||
("bpy.ops.paintcurve.delete_point*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-delete-point"),
|
||||
("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"),
|
||||
|
@ -1954,7 +1990,6 @@ url_manual_mapping = (
|
|||
("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"),
|
||||
("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"),
|
||||
("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/constant/boolean.html#bpy-types-functionnodeinputbool"),
|
||||
("bpy.types.geometrycornersofface*", "modeling/geometry_nodes/mesh/topology/corners_of_face.html#bpy-types-geometrycornersofface"),
|
||||
("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve/primitives/star.html#bpy-types-geometrynodecurvestar"),
|
||||
("bpy.types.geometrynodefillcurve*", "modeling/geometry_nodes/curve/operations/fill_curve.html#bpy-types-geometrynodefillcurve"),
|
||||
("bpy.types.geometrynodeflipfaces*", "modeling/geometry_nodes/mesh/operations/flip_faces.html#bpy-types-geometrynodeflipfaces"),
|
||||
|
@ -1993,6 +2028,7 @@ url_manual_mapping = (
|
|||
("bpy.types.shadernodeseparatexyz*", "render/shader_nodes/converter/separate_xyz.html#bpy-types-shadernodeseparatexyz"),
|
||||
("bpy.types.shadernodeshadertorgb*", "render/shader_nodes/converter/shader_to_rgb.html#bpy-types-shadernodeshadertorgb"),
|
||||
("bpy.types.shadernodetexgradient*", "render/shader_nodes/textures/gradient.html#bpy-types-shadernodetexgradient"),
|
||||
("bpy.types.shadernodetexmusgrave*", "render/shader_nodes/textures/musgrave.html#bpy-types-shadernodetexmusgrave"),
|
||||
("bpy.types.shadernodevectorcurve*", "render/shader_nodes/vector/curves.html#bpy-types-shadernodevectorcurve"),
|
||||
("bpy.types.shadernodevertexcolor*", "render/shader_nodes/input/vertex_color.html#bpy-types-shadernodevertexcolor"),
|
||||
("bpy.types.shapekey.relative_key*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-relative-key"),
|
||||
|
@ -2041,6 +2077,8 @@ url_manual_mapping = (
|
|||
("bpy.ops.outliner.lib_operation*", "files/linked_libraries/link_append.html#bpy-ops-outliner-lib-operation"),
|
||||
("bpy.ops.outliner.orphans_purge*", "editors/outliner/interface.html#bpy-ops-outliner-orphans-purge"),
|
||||
("bpy.ops.paint.mask_box_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-box-gesture"),
|
||||
("bpy.ops.paint.vertex_color_hsv*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-hsv"),
|
||||
("bpy.ops.paint.vertex_color_set*", "sculpt_paint/vertex_paint/editing.html#bpy-ops-paint-vertex-color-set"),
|
||||
("bpy.ops.pose.blend_to_neighbor*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-blend-to-neighbor"),
|
||||
("bpy.ops.screen.region_quadview*", "editors/3dview/navigate/views.html#bpy-ops-screen-region-quadview"),
|
||||
("bpy.ops.screen.screenshot_area*", "interface/window_system/topbar.html#bpy-ops-screen-screenshot-area"),
|
||||
|
@ -2126,6 +2164,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spacedopesheeteditor*", "editors/dope_sheet/index.html#bpy-types-spacedopesheeteditor"),
|
||||
("bpy.types.spaceview3d.clip_end*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-clip-end"),
|
||||
("bpy.types.speedcontrolsequence*", "video_editing/edit/montage/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"),
|
||||
("bpy.types.spotlight.spot_blend*", "render/lights/light_object.html#bpy-types-spotlight-spot-blend"),
|
||||
("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"),
|
||||
("bpy.types.texturenodetexclouds*", "editors/texture_node/types/textures/clouds.html#bpy-types-texturenodetexclouds"),
|
||||
("bpy.types.texturenodetexmarble*", "editors/texture_node/types/textures/marble.html#bpy-types-texturenodetexmarble"),
|
||||
|
@ -2222,6 +2261,7 @@ url_manual_mapping = (
|
|||
("bpy.types.curve.path_duration*", "modeling/curves/properties/path_animation.html#bpy-types-curve-path-duration"),
|
||||
("bpy.types.curve.use_fill_caps*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-fill-caps"),
|
||||
("bpy.types.curve.use_map_taper*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-map-taper"),
|
||||
("bpy.types.curves.use_mirror_z*", "sculpt_paint/curves_sculpting/introduction.html#bpy-types-curves-use-mirror-z"),
|
||||
("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"),
|
||||
("bpy.types.dashgpencilmodifier*", "grease_pencil/modifiers/generate/dash.html#bpy-types-dashgpencilmodifier"),
|
||||
("bpy.types.fieldsettings.noise*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-noise"),
|
||||
|
@ -2262,6 +2302,8 @@ url_manual_mapping = (
|
|||
("bpy.types.spline.resolution_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-resolution-u"),
|
||||
("bpy.types.spline.use_bezier_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-bezier-u"),
|
||||
("bpy.types.spline.use_cyclic_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-cyclic-u"),
|
||||
("bpy.types.spotlight.show_cone*", "render/lights/light_object.html#bpy-types-spotlight-show-cone"),
|
||||
("bpy.types.spotlight.spot_size*", "render/lights/light_object.html#bpy-types-spotlight-spot-size"),
|
||||
("bpy.types.stretchtoconstraint*", "animation/constraints/tracking/stretch_to.html#bpy-types-stretchtoconstraint"),
|
||||
("bpy.types.texturenodecurvergb*", "editors/texture_node/types/color/rgb_curves.html#bpy-types-texturenodecurvergb"),
|
||||
("bpy.types.texturenodedistance*", "editors/texture_node/types/converter/distance.html#bpy-types-texturenodedistance"),
|
||||
|
@ -2269,7 +2311,7 @@ url_manual_mapping = (
|
|||
("bpy.types.texturenodetexmagic*", "editors/texture_node/types/textures/magic.html#bpy-types-texturenodetexmagic"),
|
||||
("bpy.types.texturenodetexnoise*", "editors/texture_node/types/textures/noise.html#bpy-types-texturenodetexnoise"),
|
||||
("bpy.types.texturenodevaltonor*", "editors/texture_node/types/converter/value_to_normal.html#bpy-types-texturenodevaltonor"),
|
||||
("bpy.types.texturenodevaltorgb*", "editors/texture_node/types/converter/rgb_to_bw.html#bpy-types-texturenodevaltorgb"),
|
||||
("bpy.types.texturenodevaltorgb*", "editors/texture_node/types/converter/color_ramp.html#bpy-types-texturenodevaltorgb"),
|
||||
("bpy.types.timegpencilmodifier*", "grease_pencil/modifiers/modify/time_offset.html#bpy-types-timegpencilmodifier"),
|
||||
("bpy.types.tintgpencilmodifier*", "grease_pencil/modifiers/color/tint.html#bpy-types-tintgpencilmodifier"),
|
||||
("bpy.types.transformconstraint*", "animation/constraints/transform/transformation.html#bpy-types-transformconstraint"),
|
||||
|
@ -2393,6 +2435,7 @@ url_manual_mapping = (
|
|||
("bpy.types.object.hide_select*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-select"),
|
||||
("bpy.types.object.parent_type*", "scene_layout/object/properties/relations.html#bpy-types-object-parent-type"),
|
||||
("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"),
|
||||
("bpy.types.palettecolor.color*", "interface/controls/templates/color_palette.html#bpy-types-palettecolor-color"),
|
||||
("bpy.types.rendersettings.fps*", "render/output/properties/format.html#bpy-types-rendersettings-fps"),
|
||||
("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"),
|
||||
("bpy.types.sculpt.detail_size*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-size"),
|
||||
|
@ -2407,10 +2450,12 @@ url_manual_mapping = (
|
|||
("bpy.types.shadernodeteximage*", "render/shader_nodes/textures/image.html#bpy-types-shadernodeteximage"),
|
||||
("bpy.types.shadernodetexmagic*", "render/shader_nodes/textures/magic.html#bpy-types-shadernodetexmagic"),
|
||||
("bpy.types.shadernodetexnoise*", "render/shader_nodes/textures/noise.html#bpy-types-shadernodetexnoise"),
|
||||
("bpy.types.shadernodevaltorgb*", "render/shader_nodes/converter/color_ramp.html#bpy-types-shadernodevaltorgb"),
|
||||
("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"),
|
||||
("bpy.types.spaceview3d.camera*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-camera"),
|
||||
("bpy.types.splineikconstraint*", "animation/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"),
|
||||
("bpy.types.texturenodechecker*", "editors/texture_node/types/patterns/checker.html#bpy-types-texturenodechecker"),
|
||||
("bpy.types.texturenodergbtobw*", "editors/texture_node/types/converter/rgb_to_bw.html#bpy-types-texturenodergbtobw"),
|
||||
("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"),
|
||||
("bpy.types.texturenodetexwood*", "editors/texture_node/types/textures/wood.html#bpy-types-texturenodetexwood"),
|
||||
("bpy.types.textureslot.offset*", "sculpt_paint/brush/texture.html#bpy-types-textureslot-offset"),
|
||||
|
@ -2424,6 +2469,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.armature.parent_set*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-set"),
|
||||
("bpy.ops.armature.select_all*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-all"),
|
||||
("bpy.ops.armature.symmetrize*", "animation/armatures/bones/editing/symmetrize.html#bpy-ops-armature-symmetrize"),
|
||||
("bpy.ops.asset.catalogs_save*", "files/asset_libraries/catalogs.html#bpy-ops-asset-catalogs-save"),
|
||||
("bpy.ops.clip.average_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-average-tracks"),
|
||||
("bpy.ops.clip.refine_markers*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-refine-markers"),
|
||||
("bpy.ops.clip.select_grouped*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-grouped"),
|
||||
|
@ -2525,6 +2571,7 @@ url_manual_mapping = (
|
|||
("bpy.types.object.lightgroup*", "render/cycles/object_settings/object_data.html#bpy-types-object-lightgroup"),
|
||||
("bpy.types.object.pass_index*", "scene_layout/object/properties/relations.html#bpy-types-object-pass-index"),
|
||||
("bpy.types.object.track_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-track-axis"),
|
||||
("bpy.types.pointlight.energy*", "render/lights/light_object.html#bpy-types-pointlight-energy"),
|
||||
("bpy.types.pose.use_mirror_x*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-mirror-x"),
|
||||
("bpy.types.preferencessystem*", "editors/preferences/system.html#bpy-types-preferencessystem"),
|
||||
("bpy.types.scene.active_clip*", "scene_layout/scene/properties.html#bpy-types-scene-active-clip"),
|
||||
|
@ -2541,6 +2588,7 @@ url_manual_mapping = (
|
|||
("bpy.types.soundsequence.pan*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-soundsequence-pan"),
|
||||
("bpy.types.spline.use_smooth*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-smooth"),
|
||||
("bpy.types.texturenodebricks*", "editors/texture_node/types/patterns/bricks.html#bpy-types-texturenodebricks"),
|
||||
("bpy.types.texturenodeinvert*", "editors/texture_node/types/color/invert.html#bpy-types-texturenodeinvert"),
|
||||
("bpy.types.texturenodemixrgb*", "editors/texture_node/types/color/mix_rgb.html#bpy-types-texturenodemixrgb"),
|
||||
("bpy.types.texturenodeoutput*", "editors/texture_node/types/output/output.html#bpy-types-texturenodeoutput"),
|
||||
("bpy.types.texturenoderotate*", "editors/texture_node/types/distort/rotate.html#bpy-types-texturenoderotate"),
|
||||
|
@ -2555,6 +2603,8 @@ url_manual_mapping = (
|
|||
("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"),
|
||||
("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"),
|
||||
("bpy.ops.armature.subdivide*", "animation/armatures/bones/editing/subdivide.html#bpy-ops-armature-subdivide"),
|
||||
("bpy.ops.asset.catalog_redo*", "editors/asset_browser.html#bpy-ops-asset-catalog-redo"),
|
||||
("bpy.ops.asset.catalog_undo*", "editors/asset_browser.html#bpy-ops-asset-catalog-undo"),
|
||||
("bpy.ops.brush.curve_preset*", "sculpt_paint/brush/falloff.html#bpy-ops-brush-curve-preset"),
|
||||
("bpy.ops.buttons.toggle_pin*", "editors/properties_editor.html#bpy-ops-buttons-toggle-pin"),
|
||||
("bpy.ops.clip.delete_marker*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-marker"),
|
||||
|
@ -2571,6 +2621,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.mask.paste_splines*", "movie_clip/masking/editing.html#bpy-ops-mask-paste-splines"),
|
||||
("bpy.ops.mask.select_circle*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-circle"),
|
||||
("bpy.ops.mask.select_linked*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-linked"),
|
||||
("bpy.ops.mesh.attribute_set*", "modeling/meshes/editing/mesh/set_attribute.html#bpy-ops-mesh-attribute-set"),
|
||||
("bpy.ops.mesh.beautify_fill*", "modeling/meshes/editing/face/beautify_faces.html#bpy-ops-mesh-beautify-fill"),
|
||||
("bpy.ops.mesh.colors_rotate*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-rotate"),
|
||||
("bpy.ops.mesh.edge_collapse*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-edge-collapse"),
|
||||
|
@ -2611,6 +2662,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"),
|
||||
("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"),
|
||||
("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"),
|
||||
("bpy.types.arealight.energy*", "render/lights/light_object.html#bpy-types-arealight-energy"),
|
||||
("bpy.types.arealight.spread*", "render/cycles/light_settings.html#bpy-types-arealight-spread"),
|
||||
("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"),
|
||||
("bpy.types.bone.head_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-head-radius"),
|
||||
|
@ -2672,6 +2724,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spaceview3d.lens*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lens"),
|
||||
("bpy.types.spaceview3d.show*", "editors/3dview/display/index.html#bpy-types-spaceview3d-show"),
|
||||
("bpy.types.sphfluidsettings*", "physics/particles/emitter/physics/fluid.html#bpy-types-sphfluidsettings"),
|
||||
("bpy.types.spotlight.energy*", "render/lights/light_object.html#bpy-types-spotlight-energy"),
|
||||
("bpy.types.subtractsequence*", "video_editing/edit/montage/strips/effects/subtract.html#bpy-types-subtractsequence"),
|
||||
("bpy.types.text.indentation*", "editors/text_editor.html#bpy-types-text-indentation"),
|
||||
("bpy.types.texture.contrast*", "render/materials/legacy_textures/colors.html#bpy-types-texture-contrast"),
|
||||
|
@ -2681,6 +2734,7 @@ url_manual_mapping = (
|
|||
("bpy.types.world.lightgroup*", "render/cycles/world_settings.html#bpy-types-world-lightgroup"),
|
||||
("bpy.ops.armature.dissolve*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-dissolve"),
|
||||
("bpy.ops.armature.separate*", "animation/armatures/bones/editing/separate_bones.html#bpy-ops-armature-separate"),
|
||||
("bpy.ops.asset.catalog_new*", "files/asset_libraries/catalogs.html#bpy-ops-asset-catalog-new"),
|
||||
("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"),
|
||||
("bpy.ops.clip.delete_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-track"),
|
||||
("bpy.ops.clip.select_lasso*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-lasso"),
|
||||
|
@ -2734,6 +2788,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"),
|
||||
("bpy.ops.view3d.view_orbit*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-orbit"),
|
||||
("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"),
|
||||
("bpy.types.arealight.shape*", "render/lights/light_object.html#bpy-types-arealight-shape"),
|
||||
("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"),
|
||||
("bpy.types.armature.rigify*", "addons/rigging/rigify/basics.html#bpy-types-armature-rigify"),
|
||||
("bpy.types.bone.use_deform*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-deform"),
|
||||
|
@ -2776,6 +2831,7 @@ url_manual_mapping = (
|
|||
("bpy.types.spaceproperties*", "editors/properties_editor.html#bpy-types-spaceproperties"),
|
||||
("bpy.types.spacetexteditor*", "editors/text_editor.html#bpy-types-spacetexteditor"),
|
||||
("bpy.types.subsurfmodifier*", "modeling/modifiers/generate/subdivision_surface.html#bpy-types-subsurfmodifier"),
|
||||
("bpy.types.sunlight.energy*", "render/lights/light_object.html#bpy-types-sunlight-energy"),
|
||||
("bpy.types.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"),
|
||||
("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"),
|
||||
("bpy.ops.asset.tag_remove*", "editors/asset_browser.html#bpy-ops-asset-tag-remove"),
|
||||
|
@ -2804,6 +2860,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.node.hide_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-hide-toggle"),
|
||||
("bpy.ops.node.mute_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-mute-toggle"),
|
||||
("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"),
|
||||
("bpy.ops.object.quick_fur*", "physics/introduction.html#bpy-ops-object-quick-fur"),
|
||||
("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"),
|
||||
("bpy.ops.pose.paths_clear*", "animation/motion_paths.html#bpy-ops-pose-paths-clear"),
|
||||
("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"),
|
||||
|
@ -2830,6 +2887,8 @@ url_manual_mapping = (
|
|||
("bpy.ops.wm.owner_disable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-disable"),
|
||||
("bpy.ops.wm.save_homefile*", "interface/window_system/topbar.html#bpy-ops-wm-save-homefile"),
|
||||
("bpy.ops.wm.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"),
|
||||
("bpy.types.arealight.size*", "render/lights/light_object.html#bpy-types-arealight-size"),
|
||||
("bpy.types.attributegroup*", "modeling/meshes/properties/object_data.html#bpy-types-attributegroup"),
|
||||
("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"),
|
||||
("bpy.types.brush.hardness*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-hardness"),
|
||||
("bpy.types.brush.strength*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-strength"),
|
||||
|
@ -2860,6 +2919,7 @@ url_manual_mapping = (
|
|||
("bpy.types.smoothmodifier*", "modeling/modifiers/deform/smooth.html#bpy-types-smoothmodifier"),
|
||||
("bpy.types.sound.use_mono*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-mono"),
|
||||
("bpy.types.spline.order_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-order-u"),
|
||||
("bpy.types.sunlight.angle*", "render/lights/light_object.html#bpy-types-sunlight-angle"),
|
||||
("bpy.types.timelinemarker*", "animation/markers.html#bpy-types-timelinemarker"),
|
||||
("bpy.types.usersolidlight*", "editors/preferences/lights.html#bpy-types-usersolidlight"),
|
||||
("bpy.types.uvwarpmodifier*", "modeling/modifiers/modify/uv_warp.html#bpy-types-uvwarpmodifier"),
|
||||
|
@ -3041,6 +3101,7 @@ url_manual_mapping = (
|
|||
("bpy.types.object.delta*", "scene_layout/object/properties/transforms.html#bpy-types-object-delta"),
|
||||
("bpy.types.object.empty*", "modeling/empties.html#bpy-types-object-empty"),
|
||||
("bpy.types.object.scale*", "scene_layout/object/properties/transforms.html#bpy-types-object-scale"),
|
||||
("bpy.types.palettecolor*", "interface/controls/templates/color_palette.html#bpy-types-palettecolor"),
|
||||
("bpy.types.particleedit*", "physics/particles/mode.html#bpy-types-particleedit"),
|
||||
("bpy.types.scene.camera*", "scene_layout/scene/properties.html#bpy-types-scene-camera"),
|
||||
("bpy.types.sequencecrop*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencecrop"),
|
||||
|
@ -3063,6 +3124,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.asset.tag_add*", "editors/asset_browser.html#bpy-ops-asset-tag-add"),
|
||||
("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"),
|
||||
("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"),
|
||||
("bpy.ops.curves.delete*", "modeling/curves/primitives.html#bpy-ops-curves-delete"),
|
||||
("bpy.ops.file.pack_all*", "files/blend/packed_data.html#bpy-ops-file-pack-all"),
|
||||
("bpy.ops.file.previous*", "editors/file_browser.html#bpy-ops-file-previous"),
|
||||
("bpy.ops.gpencil.paste*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-paste"),
|
||||
|
@ -3153,6 +3215,7 @@ url_manual_mapping = (
|
|||
("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"),
|
||||
("bpy.types.imagepaint*", "sculpt_paint/texture_paint/index.html#bpy-types-imagepaint"),
|
||||
("bpy.types.keymapitem*", "editors/preferences/keymap.html#bpy-types-keymapitem"),
|
||||
("bpy.types.light.type*", "render/lights/light_object.html#bpy-types-light-type"),
|
||||
("bpy.types.lightprobe*", "render/eevee/light_probes/index.html#bpy-types-lightprobe"),
|
||||
("bpy.types.maskparent*", "movie_clip/masking/sidebar.html#bpy-types-maskparent"),
|
||||
("bpy.types.maskspline*", "movie_clip/masking/sidebar.html#bpy-types-maskspline"),
|
||||
|
@ -3218,6 +3281,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.curve.spin*", "modeling/surfaces/editing/surface.html#bpy-ops-curve-spin"),
|
||||
("bpy.ops.graph.bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-bake"),
|
||||
("bpy.ops.graph.copy*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-copy"),
|
||||
("bpy.ops.graph.ease*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-ease"),
|
||||
("bpy.ops.graph.hide*", "editors/graph_editor/channels.html#bpy-ops-graph-hide"),
|
||||
("bpy.ops.graph.snap*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap"),
|
||||
("bpy.ops.image.flip*", "editors/image/editing.html#bpy-ops-image-flip"),
|
||||
|
@ -3318,6 +3382,7 @@ url_manual_mapping = (
|
|||
("bpy.ops.ed.undo*", "interface/undo_redo.html#bpy-ops-ed-undo"),
|
||||
("bpy.ops.gpencil*", "grease_pencil/index.html#bpy-ops-gpencil"),
|
||||
("bpy.ops.lattice*", "animation/lattice.html#bpy-ops-lattice"),
|
||||
("bpy.ops.palette*", "interface/controls/templates/color_palette.html#bpy-ops-palette"),
|
||||
("bpy.ops.poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib"),
|
||||
("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"),
|
||||
("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"),
|
||||
|
|
|
@ -93,7 +93,7 @@ void txt_sel_all(struct Text *text);
|
|||
void txt_sel_clear(struct Text *text);
|
||||
void txt_sel_line(struct Text *text);
|
||||
void txt_sel_set(struct Text *text, int startl, int startc, int endl, int endc);
|
||||
char *txt_sel_to_buf(struct Text *text, size_t *r_buf_strlen);
|
||||
char *txt_sel_to_buf(const struct Text *text, size_t *r_buf_strlen);
|
||||
void txt_insert_buf(struct Text *text, const char *in_buffer, int in_buffer_len)
|
||||
ATTR_NONNULL(1, 2);
|
||||
void txt_split_curline(struct Text *text);
|
||||
|
|
|
@ -688,8 +688,10 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
|
|||
args->face_sets_color_default = pbvh->face_sets_color_default;
|
||||
args->face_sets_color_seed = pbvh->face_sets_color_seed;
|
||||
args->vert_positions = pbvh->vert_positions;
|
||||
args->corner_verts = {pbvh->corner_verts, pbvh->mesh->totloop};
|
||||
args->corner_edges = pbvh->mesh ? pbvh->mesh->corner_edges() : blender::Span<int>();
|
||||
if (pbvh->mesh) {
|
||||
args->corner_verts = {pbvh->corner_verts, pbvh->mesh->totloop};
|
||||
args->corner_edges = pbvh->mesh->corner_edges();
|
||||
}
|
||||
args->polys = pbvh->polys;
|
||||
args->mlooptri = pbvh->looptri;
|
||||
|
||||
|
|
|
@ -113,6 +113,8 @@
|
|||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
CurveMapping *BKE_sculpt_default_cavity_curve()
|
||||
|
@ -380,10 +382,11 @@ static void scene_free_markers(Scene *scene, bool do_id_user)
|
|||
|
||||
static void scene_free_data(ID *id)
|
||||
{
|
||||
|
||||
Scene *scene = (Scene *)id;
|
||||
const bool do_id_user = false;
|
||||
|
||||
DRW_drawdata_free(id);
|
||||
|
||||
SEQ_editing_free(scene, do_id_user);
|
||||
|
||||
BKE_keyingsets_free(&scene->keyingsets);
|
||||
|
|
|
@ -1450,7 +1450,7 @@ char *txt_to_buf(Text *text, size_t *r_buf_strlen)
|
|||
return buf;
|
||||
}
|
||||
|
||||
char *txt_sel_to_buf(Text *text, size_t *r_buf_strlen)
|
||||
char *txt_sel_to_buf(const Text *text, size_t *r_buf_strlen)
|
||||
{
|
||||
char *buf;
|
||||
size_t length = 0;
|
||||
|
|
|
@ -102,6 +102,11 @@ size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w,
|
|||
size_t maxncpy) ATTR_NONNULL(1, 2);
|
||||
size_t BLI_str_utf32_as_utf8(char *__restrict dst, const char32_t *__restrict src, size_t maxncpy)
|
||||
ATTR_NONNULL(1, 2);
|
||||
/**
|
||||
* \return The UTF-32 len in UTF-8 with a clamped length.
|
||||
*/
|
||||
size_t BLI_str_utf32_as_utf8_len_ex(const char32_t *src, size_t src_maxlen) ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_NONNULL(1);
|
||||
/**
|
||||
* \return The UTF-32 len in UTF-8.
|
||||
*/
|
||||
|
|
|
@ -651,6 +651,18 @@ size_t BLI_str_utf32_as_utf8(char *__restrict dst,
|
|||
return len;
|
||||
}
|
||||
|
||||
size_t BLI_str_utf32_as_utf8_len_ex(const char32_t *src, const size_t src_maxlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
const char32_t *src_end = src + src_maxlen;
|
||||
|
||||
while ((src < src_end) && *src) {
|
||||
len += BLI_str_utf8_from_unicode_len((uint)*src++);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t BLI_str_utf32_as_utf8_len(const char32_t *src)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
|
|
@ -1164,13 +1164,19 @@ void DepsgraphRelationBuilder::build_object_pointcache(Object *object)
|
|||
OperationKey transform_key(
|
||||
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT);
|
||||
add_relation(point_cache_key, transform_key, "Point Cache -> Rigid Body");
|
||||
/* Manual changes to effectors need to invalidate simulation. */
|
||||
OperationKey rigidbody_rebuild_key(
|
||||
&scene_->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_REBUILD);
|
||||
add_relation(rigidbody_rebuild_key,
|
||||
point_cache_key,
|
||||
"Rigid Body Rebuild -> Point Cache Reset",
|
||||
RELATION_FLAG_FLUSH_USER_EDIT_ONLY);
|
||||
/* Manual changes to effectors need to invalidate simulation.
|
||||
*
|
||||
* Don't add this relation for the render pipeline dependency graph as it does not contain
|
||||
* rigid body simulation. Good thing is that there are no user edits in such dependency
|
||||
* graph, so the relation is not really needed in it. */
|
||||
if (!graph_->is_render_pipeline_depsgraph) {
|
||||
OperationKey rigidbody_rebuild_key(
|
||||
&scene_->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_REBUILD);
|
||||
add_relation(rigidbody_rebuild_key,
|
||||
point_cache_key,
|
||||
"Rigid Body Rebuild -> Point Cache Reset",
|
||||
RELATION_FLAG_FLUSH_USER_EDIT_ONLY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
flag = FLAG_GEOMETRY;
|
||||
|
|
|
@ -4805,7 +4805,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
|
|||
/* try to resolve the path stored in the F-Curve */
|
||||
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
|
||||
/* set the special 'replace' flag if on a keyframe */
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra)) {
|
||||
flag |= INSERTKEY_REPLACE;
|
||||
}
|
||||
|
||||
|
@ -4867,7 +4867,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
|
|||
FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, &ptr, rna_path, 0);
|
||||
|
||||
/* set the special 'replace' flag if on a keyframe */
|
||||
if (fcurve_frame_has_keyframe(fcu, remapped_frame, 0)) {
|
||||
if (fcurve_frame_has_keyframe(fcu, remapped_frame)) {
|
||||
flag |= INSERTKEY_REPLACE;
|
||||
}
|
||||
|
||||
|
@ -4927,7 +4927,7 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C,
|
|||
|
||||
if (fcu && prop) {
|
||||
/* set the special 'replace' flag if on a keyframe */
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra)) {
|
||||
flag |= INSERTKEY_REPLACE;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,106 @@
|
|||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Channel helper functions
|
||||
* \{ */
|
||||
|
||||
static bool get_normalized_fcurve_bounds(FCurve *fcu,
|
||||
bAnimContext *ac,
|
||||
const bAnimListElem *ale,
|
||||
const bool include_handles,
|
||||
const float range[2],
|
||||
rctf *r_bounds)
|
||||
{
|
||||
const bool fcu_selection_only = false;
|
||||
const bool found_bounds = BKE_fcurve_calc_bounds(
|
||||
fcu, fcu_selection_only, include_handles, range, r_bounds);
|
||||
|
||||
if (!found_bounds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const short mapping_flag = ANIM_get_normalization_flags(ac);
|
||||
|
||||
float offset;
|
||||
const float unit_fac = ANIM_unit_mapping_get_factor(
|
||||
ac->scene, ale->id, fcu, mapping_flag, &offset);
|
||||
|
||||
r_bounds->ymin = (r_bounds->ymin + offset) * unit_fac;
|
||||
r_bounds->ymax = (r_bounds->ymax + offset) * unit_fac;
|
||||
|
||||
const float min_height = 0.01f;
|
||||
const float height = BLI_rctf_size_y(r_bounds);
|
||||
if (height < min_height) {
|
||||
r_bounds->ymin -= (min_height - height) / 2;
|
||||
r_bounds->ymax += (min_height - height) / 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_gpencil_bounds(bGPDlayer *gpl, const float range[2], rctf *r_bounds)
|
||||
{
|
||||
bool found_start = false;
|
||||
int start_frame = 0;
|
||||
int end_frame = 1;
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
if (gpf->framenum < range[0]) {
|
||||
continue;
|
||||
}
|
||||
if (gpf->framenum > range[1]) {
|
||||
break;
|
||||
}
|
||||
if (!found_start) {
|
||||
start_frame = gpf->framenum;
|
||||
found_start = true;
|
||||
}
|
||||
end_frame = gpf->framenum;
|
||||
}
|
||||
r_bounds->xmin = start_frame;
|
||||
r_bounds->xmax = end_frame;
|
||||
r_bounds->ymin = 0;
|
||||
r_bounds->ymax = 1;
|
||||
|
||||
return found_start;
|
||||
}
|
||||
|
||||
static bool get_channel_bounds(bAnimContext *ac,
|
||||
bAnimListElem *ale,
|
||||
const float range[2],
|
||||
const bool include_handles,
|
||||
rctf *r_bounds)
|
||||
{
|
||||
bool found_bounds = false;
|
||||
switch (ale->datatype) {
|
||||
case ALE_GPFRAME: {
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
found_bounds = get_gpencil_bounds(gpl, range, r_bounds);
|
||||
break;
|
||||
}
|
||||
case ALE_FCURVE: {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
found_bounds = get_normalized_fcurve_bounds(fcu, ac, ale, include_handles, range, r_bounds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found_bounds;
|
||||
}
|
||||
|
||||
/* Pad the given rctf with regions that could block the view.
|
||||
* For example Markers and Time Scrubbing. */
|
||||
static void add_region_padding(bContext *C, bAnimContext *ac, rctf *bounds)
|
||||
{
|
||||
BLI_rctf_scale(bounds, 1.1f);
|
||||
|
||||
const float pad_top = UI_TIME_SCRUB_MARGIN_Y;
|
||||
const float pad_bottom = BLI_listbase_is_empty(ED_context_get_markers(C)) ?
|
||||
V2D_SCROLL_HANDLE_HEIGHT :
|
||||
UI_MARKER_MARGIN_Y;
|
||||
BLI_rctf_pad_y(bounds, ac->region->winy, pad_bottom, pad_top);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Channel Selection API
|
||||
* \{ */
|
||||
|
@ -3643,87 +3743,6 @@ static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
|
|||
/** \name View Channel Operator
|
||||
* \{ */
|
||||
|
||||
static bool get_normalized_fcurve_bounds(FCurve *fcu,
|
||||
bAnimContext *ac,
|
||||
const bAnimListElem *ale,
|
||||
const bool include_handles,
|
||||
const float range[2],
|
||||
rctf *r_bounds)
|
||||
{
|
||||
const bool fcu_selection_only = false;
|
||||
const bool found_bounds = BKE_fcurve_calc_bounds(
|
||||
fcu, fcu_selection_only, include_handles, range, r_bounds);
|
||||
|
||||
if (!found_bounds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const short mapping_flag = ANIM_get_normalization_flags(ac);
|
||||
|
||||
float offset;
|
||||
const float unit_fac = ANIM_unit_mapping_get_factor(
|
||||
ac->scene, ale->id, fcu, mapping_flag, &offset);
|
||||
|
||||
r_bounds->ymin = (r_bounds->ymin + offset) * unit_fac;
|
||||
r_bounds->ymax = (r_bounds->ymax + offset) * unit_fac;
|
||||
|
||||
const float min_height = 0.01f;
|
||||
const float height = BLI_rctf_size_y(r_bounds);
|
||||
if (height < min_height) {
|
||||
r_bounds->ymin -= (min_height - height) / 2;
|
||||
r_bounds->ymax += (min_height - height) / 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_gpencil_bounds(bGPDlayer *gpl, const float range[2], rctf *r_bounds)
|
||||
{
|
||||
bool found_start = false;
|
||||
int start_frame = 0;
|
||||
int end_frame = 1;
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
if (gpf->framenum < range[0]) {
|
||||
continue;
|
||||
}
|
||||
if (gpf->framenum > range[1]) {
|
||||
break;
|
||||
}
|
||||
if (!found_start) {
|
||||
start_frame = gpf->framenum;
|
||||
found_start = true;
|
||||
}
|
||||
end_frame = gpf->framenum;
|
||||
}
|
||||
r_bounds->xmin = start_frame;
|
||||
r_bounds->xmax = end_frame;
|
||||
r_bounds->ymin = 0;
|
||||
r_bounds->ymax = 1;
|
||||
|
||||
return found_start;
|
||||
}
|
||||
|
||||
static bool get_channel_bounds(bAnimContext *ac,
|
||||
bAnimListElem *ale,
|
||||
const float range[2],
|
||||
const bool include_handles,
|
||||
rctf *r_bounds)
|
||||
{
|
||||
bool found_bounds = false;
|
||||
switch (ale->datatype) {
|
||||
case ALE_GPFRAME: {
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
found_bounds = get_gpencil_bounds(gpl, range, r_bounds);
|
||||
break;
|
||||
}
|
||||
case ALE_FCURVE: {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
found_bounds = get_normalized_fcurve_bounds(fcu, ac, ale, include_handles, range, r_bounds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found_bounds;
|
||||
}
|
||||
|
||||
static void get_view_range(Scene *scene, const bool use_preview_range, float r_range[2])
|
||||
{
|
||||
if (use_preview_range && scene->r.flag & SCER_PRV_RANGE) {
|
||||
|
@ -3736,19 +3755,6 @@ static void get_view_range(Scene *scene, const bool use_preview_range, float r_r
|
|||
}
|
||||
}
|
||||
|
||||
/* Pad the given rctf with regions that could block the view.
|
||||
* For example Markers and Time Scrubbing. */
|
||||
static void add_region_padding(bContext *C, bAnimContext *ac, rctf *bounds)
|
||||
{
|
||||
BLI_rctf_scale(bounds, 1.1f);
|
||||
|
||||
const float pad_top = UI_TIME_SCRUB_MARGIN_Y;
|
||||
const float pad_bottom = BLI_listbase_is_empty(ED_context_get_markers(C)) ?
|
||||
V2D_SCROLL_HANDLE_HEIGHT :
|
||||
UI_MARKER_MARGIN_Y;
|
||||
BLI_rctf_pad_y(bounds, ac->region->winy, pad_bottom, pad_top);
|
||||
}
|
||||
|
||||
static int graphkeys_view_selected_channels_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAnimContext ac;
|
||||
|
|
|
@ -2852,7 +2852,7 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
|
|||
* For whole block, only key if there's a keyframe on that frame already
|
||||
* This is a valid assumption when we're blocking + tweaking
|
||||
*/
|
||||
return id_frame_has_keyframe(id, cfra, ANIMFILTER_KEYS_LOCAL);
|
||||
return id_frame_has_keyframe(id, cfra);
|
||||
}
|
||||
|
||||
/* Normal Mode (or treat as being normal mode):
|
||||
|
@ -2871,15 +2871,14 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
|
|||
|
||||
/* --------------- API/Per-Datablock Handling ------------------- */
|
||||
|
||||
bool fcurve_frame_has_keyframe(const FCurve *fcu, float frame, short filter)
|
||||
bool fcurve_frame_has_keyframe(const FCurve *fcu, float frame)
|
||||
{
|
||||
/* quick sanity check */
|
||||
if (ELEM(NULL, fcu, fcu->bezt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We either include all regardless of muting, or only non-muted. */
|
||||
if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
|
||||
if ((fcu->flag & FCURVE_MUTED) == 0) {
|
||||
bool replace;
|
||||
int i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, frame, fcu->totvert, &replace);
|
||||
|
||||
|
@ -2926,7 +2925,7 @@ bool fcurve_is_changed(PointerRNA ptr,
|
|||
* Since we're only concerned whether a keyframe exists,
|
||||
* we can simply loop until a match is found.
|
||||
*/
|
||||
static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
|
||||
static bool action_frame_has_keyframe(bAction *act, float frame)
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
|
@ -2935,8 +2934,7 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* if only check non-muted, check if muted */
|
||||
if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED)) {
|
||||
if (act->flag & ACT_MUTED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2946,7 +2944,7 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
|
|||
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
|
||||
/* only check if there are keyframes (currently only of type BezTriple) */
|
||||
if (fcu->bezt && fcu->totvert) {
|
||||
if (fcurve_frame_has_keyframe(fcu, frame, filter)) {
|
||||
if (fcurve_frame_has_keyframe(fcu, frame)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2957,7 +2955,7 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
|
|||
}
|
||||
|
||||
/* Checks whether an Object has a keyframe for a given frame */
|
||||
static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
|
||||
static bool object_frame_has_keyframe(Object *ob, float frame)
|
||||
{
|
||||
/* error checking */
|
||||
if (ob == NULL) {
|
||||
|
@ -2972,59 +2970,18 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
|
|||
*/
|
||||
float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter)) {
|
||||
if (action_frame_has_keyframe(ob->adt->action, ob_frame)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try shape-key keyframes (if available, and allowed by filter). */
|
||||
if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY)) {
|
||||
Key *key = BKE_key_from_object(ob);
|
||||
|
||||
/* Shape-keys can have keyframes ('Relative Shape Keys')
|
||||
* or depend on time (old 'Absolute Shape Keys'). */
|
||||
|
||||
/* 1. test for relative (with keyframes) */
|
||||
if (id_frame_has_keyframe((ID *)key, frame, filter)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 2. test for time */
|
||||
/* TODO: yet to be implemented (this feature may evolve before then anyway). */
|
||||
}
|
||||
|
||||
/* try materials */
|
||||
if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOMAT)) {
|
||||
/* if only active, then we can skip a lot of looping */
|
||||
if (filter & ANIMFILTER_KEYS_ACTIVE) {
|
||||
Material *ma = BKE_object_material_get(ob, (ob->actcol + 1));
|
||||
|
||||
/* we only retrieve the active material... */
|
||||
if (id_frame_has_keyframe((ID *)ma, frame, filter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int a;
|
||||
|
||||
/* loop over materials */
|
||||
for (a = 0; a < ob->totcol; a++) {
|
||||
Material *ma = BKE_object_material_get(ob, a + 1);
|
||||
|
||||
if (id_frame_has_keyframe((ID *)ma, frame, filter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------- API ------------------- */
|
||||
|
||||
bool id_frame_has_keyframe(ID *id, float frame, short filter)
|
||||
bool id_frame_has_keyframe(ID *id, float frame)
|
||||
{
|
||||
/* sanity checks */
|
||||
if (id == NULL) {
|
||||
|
@ -3034,7 +2991,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter)
|
|||
/* perform special checks for 'macro' types */
|
||||
switch (GS(id->name)) {
|
||||
case ID_OB: /* object */
|
||||
return object_frame_has_keyframe((Object *)id, frame, filter);
|
||||
return object_frame_has_keyframe((Object *)id, frame);
|
||||
#if 0
|
||||
/* XXX TODO... for now, just use 'normal' behavior */
|
||||
case ID_SCE: /* scene */
|
||||
|
@ -3046,7 +3003,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter)
|
|||
|
||||
/* only check keyframes in active action */
|
||||
if (adt) {
|
||||
return action_frame_has_keyframe(adt->action, frame, filter);
|
||||
return action_frame_has_keyframe(adt->action, frame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "BKE_asset.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -52,7 +53,7 @@ void ED_asset_generate_preview(const bContext *C, ID *id)
|
|||
BKE_previewimg_clear(preview);
|
||||
}
|
||||
|
||||
UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
|
||||
UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, !G.background);
|
||||
}
|
||||
|
||||
bool ED_asset_clear_id(ID *id)
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#define MAXTEXT 32766
|
||||
|
||||
static int kill_selection(Object *obedit, int ins);
|
||||
static char *font_select_to_buffer(Object *obedit);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal Utilities
|
||||
|
@ -453,6 +454,19 @@ static int kill_selection(Object *obedit, int ins) /* ins == new character len *
|
|||
return direction;
|
||||
}
|
||||
|
||||
static void font_select_update_primary_clipboard(Object *obedit)
|
||||
{
|
||||
if ((WM_capabilities_flag() & WM_CAPABILITY_PRIMARY_CLIPBOARD) == 0) {
|
||||
return;
|
||||
}
|
||||
char *buf = font_select_to_buffer(obedit);
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
WM_clipboard_text_set(buf, true);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -525,6 +539,29 @@ static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Generic Copy Functions
|
||||
* \{ */
|
||||
|
||||
static char *font_select_to_buffer(Object *obedit)
|
||||
{
|
||||
int selstart, selend;
|
||||
if (!BKE_vfont_select_get(obedit, &selstart, &selend)) {
|
||||
return NULL;
|
||||
}
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
char32_t *text_buf = ef->textbuf + selstart;
|
||||
const size_t text_buf_len = selend - selstart;
|
||||
|
||||
const size_t len_utf8 = BLI_str_utf32_as_utf8_len_ex(text_buf, text_buf_len + 1);
|
||||
char *buf = MEM_mallocN(len_utf8 + 1, __func__);
|
||||
BLI_str_utf32_as_utf8(buf, text_buf, len_utf8);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Paste From File Operator
|
||||
* \{ */
|
||||
|
@ -864,6 +901,7 @@ static int font_select_all_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
ef->pos = ef->len;
|
||||
|
||||
text_update_edited(C, obedit, FO_SELCHANGE);
|
||||
font_select_update_primary_clipboard(obedit);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -1000,6 +1038,7 @@ static bool paste_selection(Object *obedit, ReportList *reports)
|
|||
|
||||
static int paste_text_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool selection = RNA_boolean_get(op->ptr, "selection");
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
int retval;
|
||||
size_t len_utf8;
|
||||
|
@ -1013,7 +1052,7 @@ static int paste_text_exec(bContext *C, wmOperator *op)
|
|||
int len;
|
||||
} clipboard_system = {NULL}, clipboard_vfont = {NULL};
|
||||
|
||||
clipboard_system.buf = WM_clipboard_text_get(false, &clipboard_system.len);
|
||||
clipboard_system.buf = WM_clipboard_text_get(selection, &clipboard_system.len);
|
||||
|
||||
if (clipboard_system.buf == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
|
@ -1077,6 +1116,15 @@ void FONT_OT_text_paste(wmOperatorType *ot)
|
|||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"selection",
|
||||
0,
|
||||
"Selection",
|
||||
"Paste text selected elsewhere rather than copied (X11/Wayland only)");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1216,6 +1264,7 @@ static int move_cursor(bContext *C, int type, const bool select)
|
|||
|
||||
if (select) {
|
||||
ef->selend = ef->pos;
|
||||
font_select_update_primary_clipboard(obedit);
|
||||
}
|
||||
|
||||
text_update_edited(C, obedit, cursmove);
|
||||
|
|
|
@ -608,7 +608,7 @@ bool autokeyframe_cfra_can_key(const struct Scene *scene, struct ID *id);
|
|||
* Checks if some F-Curve has a keyframe for a given frame.
|
||||
* \note Used for the buttons to check for keyframes.
|
||||
*/
|
||||
bool fcurve_frame_has_keyframe(const struct FCurve *fcu, float frame, short filter);
|
||||
bool fcurve_frame_has_keyframe(const struct FCurve *fcu, float frame);
|
||||
|
||||
/**
|
||||
* \brief Lesser Keyframe Checking API call.
|
||||
|
@ -629,23 +629,7 @@ bool fcurve_is_changed(struct PointerRNA ptr,
|
|||
* in case some detail of the implementation changes...
|
||||
* \param frame: The value of this is quite often result of #BKE_scene_ctime_get()
|
||||
*/
|
||||
bool id_frame_has_keyframe(struct ID *id, float frame, short filter);
|
||||
|
||||
/**
|
||||
* Filter flags for #id_frame_has_keyframe.
|
||||
*
|
||||
* \warning do not alter order of these, as also stored in files (for `v3d->keyflags`).
|
||||
*/
|
||||
typedef enum eAnimFilterFlags {
|
||||
/* general */
|
||||
ANIMFILTER_KEYS_LOCAL = (1 << 0), /* only include locally available anim data */
|
||||
ANIMFILTER_KEYS_MUTED = (1 << 1), /* include muted elements */
|
||||
ANIMFILTER_KEYS_ACTIVE = (1 << 2), /* only include active-subelements */
|
||||
|
||||
/* object specific */
|
||||
ANIMFILTER_KEYS_NOMAT = (1 << 9), /* don't include material keyframes */
|
||||
ANIMFILTER_KEYS_NOSKEY = (1 << 10), /* don't include shape keys (for geometry) */
|
||||
} eAnimFilterFlags;
|
||||
bool id_frame_has_keyframe(struct ID *id, float frame);
|
||||
|
||||
/* Utility functions for auto key-frame. */
|
||||
|
||||
|
|
|
@ -2014,7 +2014,11 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
|
|||
break;
|
||||
}
|
||||
|
||||
ui_block_views_bounds_calc(block);
|
||||
/* Update bounds of all views in this block. If this block is a panel, this will be done later in
|
||||
* #UI_panels_end(), because buttons are offset there. */
|
||||
if (!block->panel) {
|
||||
ui_block_views_bounds_calc(block);
|
||||
}
|
||||
|
||||
if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
|
||||
UI_block_bounds_set_normal(block, 0);
|
||||
|
|
|
@ -94,7 +94,7 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
|
|||
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra)) {
|
||||
but->flag |= UI_BUT_ANIMATED_KEY;
|
||||
}
|
||||
|
||||
|
|
|
@ -1831,6 +1831,10 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
|
|||
LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) {
|
||||
if (block->active && block->panel) {
|
||||
ui_offset_panel_block(block);
|
||||
|
||||
/* Update bounds for all "views" in this block. Usually this is done in #UI_block_end(), but
|
||||
* that wouldn't work because of the offset applied above. */
|
||||
ui_block_views_bounds_calc(block);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,72 @@
|
|||
|
||||
#include "console_intern.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
|
||||
static char *console_select_to_buffer(SpaceConsole *sc)
|
||||
{
|
||||
if (sc->sel_start == sc->sel_end) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ConsoleLine cl_dummy = {NULL};
|
||||
console_scrollback_prompt_begin(sc, &cl_dummy);
|
||||
|
||||
int offset = 0;
|
||||
for (ConsoleLine *cl = sc->scrollback.first; cl; cl = cl->next) {
|
||||
offset += cl->len + 1;
|
||||
}
|
||||
|
||||
char *buf_str = NULL;
|
||||
if (offset != 0) {
|
||||
offset -= 1;
|
||||
int sel[2] = {offset - sc->sel_end, offset - sc->sel_start};
|
||||
DynStr *buf_dyn = BLI_dynstr_new();
|
||||
for (ConsoleLine *cl = sc->scrollback.first; cl; cl = cl->next) {
|
||||
if (sel[0] <= cl->len && sel[1] >= 0) {
|
||||
int sta = max_ii(sel[0], 0);
|
||||
int end = min_ii(sel[1], cl->len);
|
||||
|
||||
if (BLI_dynstr_get_len(buf_dyn)) {
|
||||
BLI_dynstr_append(buf_dyn, "\n");
|
||||
}
|
||||
|
||||
BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
|
||||
}
|
||||
|
||||
sel[0] -= cl->len + 1;
|
||||
sel[1] -= cl->len + 1;
|
||||
}
|
||||
|
||||
buf_str = BLI_dynstr_get_cstring(buf_dyn);
|
||||
|
||||
BLI_dynstr_free(buf_dyn);
|
||||
}
|
||||
console_scrollback_prompt_end(sc, &cl_dummy);
|
||||
|
||||
return buf_str;
|
||||
}
|
||||
|
||||
static void console_select_update_primary_clipboard(SpaceConsole *sc)
|
||||
{
|
||||
if ((WM_capabilities_flag() & WM_CAPABILITY_PRIMARY_CLIPBOARD) == 0) {
|
||||
return;
|
||||
}
|
||||
if (sc->sel_start == sc->sel_end) {
|
||||
return;
|
||||
}
|
||||
char *buf = console_select_to_buffer(sc);
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
WM_clipboard_text_set(buf, true);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* so when we type - the view scrolls to the bottom */
|
||||
static void console_scroll_bottom(ARegion *region)
|
||||
{
|
||||
|
@ -966,61 +1032,13 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot)
|
|||
static int console_copy_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
|
||||
DynStr *buf_dyn;
|
||||
char *buf_str;
|
||||
|
||||
ConsoleLine *cl;
|
||||
int sel[2];
|
||||
int offset = 0;
|
||||
|
||||
ConsoleLine cl_dummy = {NULL};
|
||||
|
||||
if (sc->sel_start == sc->sel_end) {
|
||||
char *buf = console_select_to_buffer(sc);
|
||||
if (buf == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
console_scrollback_prompt_begin(sc, &cl_dummy);
|
||||
|
||||
for (cl = sc->scrollback.first; cl; cl = cl->next) {
|
||||
offset += cl->len + 1;
|
||||
}
|
||||
|
||||
if (offset == 0) {
|
||||
console_scrollback_prompt_end(sc, &cl_dummy);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
buf_dyn = BLI_dynstr_new();
|
||||
offset -= 1;
|
||||
sel[0] = offset - sc->sel_end;
|
||||
sel[1] = offset - sc->sel_start;
|
||||
|
||||
for (cl = sc->scrollback.first; cl; cl = cl->next) {
|
||||
if (sel[0] <= cl->len && sel[1] >= 0) {
|
||||
int sta = max_ii(sel[0], 0);
|
||||
int end = min_ii(sel[1], cl->len);
|
||||
|
||||
if (BLI_dynstr_get_len(buf_dyn)) {
|
||||
BLI_dynstr_append(buf_dyn, "\n");
|
||||
}
|
||||
|
||||
BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
|
||||
}
|
||||
|
||||
sel[0] -= cl->len + 1;
|
||||
sel[1] -= cl->len + 1;
|
||||
}
|
||||
|
||||
buf_str = BLI_dynstr_get_cstring(buf_dyn);
|
||||
|
||||
BLI_dynstr_free(buf_dyn);
|
||||
WM_clipboard_text_set(buf_str, 0);
|
||||
|
||||
MEM_freeN(buf_str);
|
||||
|
||||
console_scrollback_prompt_end(sc, &cl_dummy);
|
||||
|
||||
WM_clipboard_text_set(buf, 0);
|
||||
MEM_freeN(buf);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -1038,14 +1056,15 @@ void CONSOLE_OT_copy(wmOperatorType *ot)
|
|||
/* properties */
|
||||
}
|
||||
|
||||
static int console_paste_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
static int console_paste_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool selection = RNA_boolean_get(op->ptr, "selection");
|
||||
SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
ConsoleLine *ci = console_history_verify(C);
|
||||
int buf_len;
|
||||
|
||||
char *buf_str = WM_clipboard_text_get(false, &buf_len);
|
||||
char *buf_str = WM_clipboard_text_get(selection, &buf_len);
|
||||
char *buf_step, *buf_next;
|
||||
|
||||
if (buf_str == NULL) {
|
||||
|
@ -1091,6 +1110,13 @@ void CONSOLE_OT_paste(wmOperatorType *ot)
|
|||
ot->exec = console_paste_exec;
|
||||
|
||||
/* properties */
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"selection",
|
||||
0,
|
||||
"Selection",
|
||||
"Paste text selected elsewhere rather than copied (X11/Wayland only)");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
typedef struct SetConsoleCursor {
|
||||
|
@ -1146,18 +1172,12 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEven
|
|||
}
|
||||
}
|
||||
|
||||
static void console_cursor_set_exit(bContext *UNUSED(C), wmOperator *op)
|
||||
static void console_cursor_set_exit(bContext *C, wmOperator *op)
|
||||
{
|
||||
// SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
SetConsoleCursor *scu = op->customdata;
|
||||
|
||||
#if 0
|
||||
if (txt_has_sel(text)) {
|
||||
buffer = txt_sel_to_buf(text);
|
||||
WM_clipboard_text_set(buffer, 1);
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
#endif
|
||||
console_select_update_primary_clipboard(sc);
|
||||
|
||||
MEM_freeN(scu);
|
||||
}
|
||||
|
@ -1254,6 +1274,11 @@ static int console_selectword_invoke(bContext *C, wmOperator *UNUSED(op), const
|
|||
}
|
||||
|
||||
console_scrollback_prompt_end(sc, &cl_dummy);
|
||||
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
console_select_update_primary_clipboard(sc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@
|
|||
#include "UI_interface.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "nla_intern.h" /* own include */
|
||||
#include "nla_private.h" /* FIXME: maybe this shouldn't be included? */
|
||||
#include "nla_intern.h"
|
||||
#include "nla_private.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public Utilities
|
||||
|
|
|
@ -85,7 +85,6 @@ static void deselect_nla_strips(bAnimContext *ac, short test, short sel)
|
|||
short smode;
|
||||
|
||||
/* determine type-based settings */
|
||||
/* FIXME: double check whether ANIMFILTER_LIST_VISIBLE is needed! */
|
||||
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY);
|
||||
|
||||
/* filter data */
|
||||
|
|
|
@ -159,6 +159,22 @@ BLI_INLINE int text_pixel_x_to_column(SpaceText *st, const int x)
|
|||
return (x + (st->runtime.cwidth_px / 2)) / st->runtime.cwidth_px;
|
||||
}
|
||||
|
||||
static void text_select_update_primary_clipboard(const Text *text)
|
||||
{
|
||||
if ((WM_capabilities_flag() & WM_CAPABILITY_PRIMARY_CLIPBOARD) == 0) {
|
||||
return;
|
||||
}
|
||||
if (!txt_has_sel(text)) {
|
||||
return;
|
||||
}
|
||||
char *buf = txt_sel_to_buf(text, NULL);
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
WM_clipboard_text_set(buf, true);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -954,11 +970,13 @@ void TEXT_OT_paste(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna,
|
||||
"selection",
|
||||
0,
|
||||
"Selection",
|
||||
"Paste text selected elsewhere rather than copied (X11 only)");
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"selection",
|
||||
0,
|
||||
"Selection",
|
||||
"Paste text selected elsewhere rather than copied (X11/Wayland only)");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1499,6 +1517,8 @@ static int text_select_all_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
txt_sel_all(text);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
text_select_update_primary_clipboard(text);
|
||||
|
||||
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1529,6 +1549,8 @@ static int text_select_line_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
txt_sel_line(text);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
text_select_update_primary_clipboard(text);
|
||||
|
||||
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1562,6 +1584,8 @@ static int text_select_word_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
txt_jump_right(text, true, use_init_step);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
text_select_update_primary_clipboard(text);
|
||||
|
||||
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -2246,6 +2270,10 @@ static int text_move_cursor(bContext *C, int type, bool select)
|
|||
}
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
if (select) {
|
||||
text_select_update_primary_clipboard(st->text);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -3243,17 +3271,11 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *ev
|
|||
static void text_cursor_set_exit(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceText *st = CTX_wm_space_text(C);
|
||||
Text *text = st->text;
|
||||
SetSelection *ssel = op->customdata;
|
||||
char *buffer;
|
||||
|
||||
if (txt_has_sel(text)) {
|
||||
buffer = txt_sel_to_buf(text, NULL);
|
||||
WM_clipboard_text_set(buffer, 1);
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
text_select_update_primary_clipboard(st->text);
|
||||
|
||||
WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
|
||||
|
||||
text_cursor_timer_remove(C, ssel);
|
||||
|
|
|
@ -1386,8 +1386,7 @@ static void draw_selected_name(
|
|||
}
|
||||
|
||||
/* color depends on whether there is a keyframe */
|
||||
if (id_frame_has_keyframe(
|
||||
(ID *)ob, /* BKE_scene_ctime_get(scene) */ float(cfra), ANIMFILTER_KEYS_LOCAL)) {
|
||||
if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_ctime_get(scene) */ float(cfra))) {
|
||||
UI_FontThemeColor(font_id, TH_TIME_KEYFRAME);
|
||||
}
|
||||
else if (ED_gpencil_has_keyframe_v3d(scene, ob, cfra)) {
|
||||
|
|
|
@ -421,27 +421,29 @@ static float2 find_best_fit_for_island(
|
|||
const float size_x_scaled = BLI_rctf_size_x(&island->bounds_rect) * scale;
|
||||
const float size_y_scaled = BLI_rctf_size_y(&island->bounds_rect) * scale;
|
||||
|
||||
/* Scan using an "Alpaca"-style search, first vertically. */
|
||||
|
||||
int t = 0;
|
||||
while (t <= scan_line) {
|
||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||
|
||||
/* Scan using an "Alpaca"-style search, both horizontally and vertically at the same time. */
|
||||
|
||||
const float2 horiz(scan_line_bscaled - size_x_scaled, t_bscaled - size_y_scaled);
|
||||
const float extentH = occupancy.trace_island(island, scale, margin, horiz, false);
|
||||
if (extentH < 0.0f) {
|
||||
return horiz;
|
||||
const float2 probe(scan_line_bscaled - size_x_scaled, t_bscaled - size_y_scaled);
|
||||
const float extent = occupancy.trace_island(island, scale, margin, probe, false);
|
||||
if (extent < 0.0f) {
|
||||
return probe;
|
||||
}
|
||||
t = t + std::max(1, int(extent));
|
||||
}
|
||||
|
||||
const float2 vert(t_bscaled - size_x_scaled, scan_line_bscaled - size_y_scaled);
|
||||
const float extentV = occupancy.trace_island(island, scale, margin, vert, false);
|
||||
if (extentV < 0.0f) {
|
||||
return vert;
|
||||
/* Now scan horizontally. */
|
||||
t = 0;
|
||||
while (t <= scan_line) {
|
||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||
const float2 probe(t_bscaled - size_x_scaled, scan_line_bscaled - size_y_scaled);
|
||||
const float extent = occupancy.trace_island(island, scale, margin, probe, false);
|
||||
if (extent < 0.0f) {
|
||||
return probe;
|
||||
}
|
||||
|
||||
const float min_extent = std::min(extentH, extentV);
|
||||
|
||||
t = t + std::max(1, int(min_extent));
|
||||
t = t + std::max(1, int(extent));
|
||||
}
|
||||
return float2(-1, -1);
|
||||
}
|
||||
|
|
|
@ -2439,6 +2439,17 @@ static float p_abf_compute_gradient(PAbfSystem *sys, PChart *chart)
|
|||
return norm;
|
||||
}
|
||||
|
||||
static void p_abf_adjust_alpha(PAbfSystem *sys,
|
||||
const int id,
|
||||
const float dlambda1,
|
||||
const float pre)
|
||||
{
|
||||
float alpha = sys->alpha[id];
|
||||
const float dalpha = (sys->bAlpha[id] - dlambda1);
|
||||
alpha += dalpha / sys->weight[id] - pre;
|
||||
sys->alpha[id] = clamp_f(alpha, 0.0f, float(M_PI));
|
||||
}
|
||||
|
||||
static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
|
||||
{
|
||||
int ninterior = sys->ninterior;
|
||||
|
@ -2596,11 +2607,11 @@ static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
|
|||
|
||||
if (success) {
|
||||
for (PFace *f = chart->faces; f; f = f->nextlink) {
|
||||
float dlambda1, pre[3], dalpha;
|
||||
float pre[3];
|
||||
PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
|
||||
PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert;
|
||||
|
||||
pre[0] = pre[1] = pre[2] = 0.0;
|
||||
pre[0] = pre[1] = pre[2] = 0.0f;
|
||||
|
||||
if (v1->flag & PVERT_INTERIOR) {
|
||||
float x = EIG_linear_solver_variable_get(context, 0, v1->u.id);
|
||||
|
@ -2626,30 +2637,14 @@ static bool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
|
|||
pre[2] += sys->J2dt[e3->u.id][2] * x;
|
||||
}
|
||||
|
||||
dlambda1 = pre[0] + pre[1] + pre[2];
|
||||
float dlambda1 = pre[0] + pre[1] + pre[2];
|
||||
dlambda1 = sys->dstar[f->u.id] * (sys->bstar[f->u.id] - dlambda1);
|
||||
|
||||
sys->lambdaTriangle[f->u.id] += dlambda1;
|
||||
|
||||
dalpha = (sys->bAlpha[e1->u.id] - dlambda1);
|
||||
sys->alpha[e1->u.id] += dalpha / sys->weight[e1->u.id] - pre[0];
|
||||
|
||||
dalpha = (sys->bAlpha[e2->u.id] - dlambda1);
|
||||
sys->alpha[e2->u.id] += dalpha / sys->weight[e2->u.id] - pre[1];
|
||||
|
||||
dalpha = (sys->bAlpha[e3->u.id] - dlambda1);
|
||||
sys->alpha[e3->u.id] += dalpha / sys->weight[e3->u.id] - pre[2];
|
||||
|
||||
/* clamp */
|
||||
PEdge *e = f->edge;
|
||||
do {
|
||||
if (sys->alpha[e->u.id] > float(M_PI)) {
|
||||
sys->alpha[e->u.id] = float(M_PI);
|
||||
}
|
||||
else if (sys->alpha[e->u.id] < 0.0f) {
|
||||
sys->alpha[e->u.id] = 0.0f;
|
||||
}
|
||||
} while (e != f->edge);
|
||||
p_abf_adjust_alpha(sys, e1->u.id, dlambda1, pre[0]);
|
||||
p_abf_adjust_alpha(sys, e2->u.id, dlambda1, pre[1]);
|
||||
p_abf_adjust_alpha(sys, e3->u.id, dlambda1, pre[2]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ninterior; i++) {
|
||||
|
|
|
@ -42,8 +42,17 @@ set(INC
|
|||
../../../intern/mantaflow/extern
|
||||
)
|
||||
|
||||
if(WITH_RENDERDOC)
|
||||
list(APPEND INC
|
||||
../../../extern/renderdoc/include
|
||||
../../../intern/renderdoc_dynload/include
|
||||
)
|
||||
add_definitions(-DWITH_RENDERDOC)
|
||||
endif()
|
||||
|
||||
set(INC_SYS
|
||||
${Epoxy_INCLUDE_DIRS}
|
||||
${IMATH_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
|
@ -195,6 +204,8 @@ set(VULKAN_SRC
|
|||
vulkan/vk_command_buffer.cc
|
||||
vulkan/vk_common.cc
|
||||
vulkan/vk_context.cc
|
||||
vulkan/vk_data_conversion.cc
|
||||
vulkan/vk_debug.cc
|
||||
vulkan/vk_descriptor_pools.cc
|
||||
vulkan/vk_descriptor_set.cc
|
||||
vulkan/vk_drawlist.cc
|
||||
|
@ -207,6 +218,7 @@ set(VULKAN_SRC
|
|||
vulkan/vk_pixel_buffer.cc
|
||||
vulkan/vk_push_constants.cc
|
||||
vulkan/vk_query.cc
|
||||
vulkan/vk_resource_tracker.cc
|
||||
vulkan/vk_shader.cc
|
||||
vulkan/vk_shader_interface.cc
|
||||
vulkan/vk_shader_log.cc
|
||||
|
@ -222,6 +234,7 @@ set(VULKAN_SRC
|
|||
vulkan/vk_command_buffer.hh
|
||||
vulkan/vk_common.hh
|
||||
vulkan/vk_context.hh
|
||||
vulkan/vk_data_conversion.hh
|
||||
vulkan/vk_descriptor_pools.hh
|
||||
vulkan/vk_descriptor_set.hh
|
||||
vulkan/vk_drawlist.hh
|
||||
|
@ -234,6 +247,7 @@ set(VULKAN_SRC
|
|||
vulkan/vk_pixel_buffer.hh
|
||||
vulkan/vk_push_constants.hh
|
||||
vulkan/vk_query.hh
|
||||
vulkan/vk_resource_tracker.hh
|
||||
vulkan/vk_shader.hh
|
||||
vulkan/vk_shader_interface.hh
|
||||
vulkan/vk_shader_log.hh
|
||||
|
@ -742,6 +756,10 @@ if(WITH_OPENCOLORIO)
|
|||
target_link_libraries(bf_gpu PUBLIC bf_ocio_shaders)
|
||||
endif()
|
||||
|
||||
if(WITH_RENDERDOC)
|
||||
target_link_libraries(bf_gpu PUBLIC bf_intern_renderdoc_dynload)
|
||||
endif()
|
||||
|
||||
|
||||
if(CXX_WARN_NO_SUGGEST_OVERRIDE)
|
||||
target_compile_options(bf_gpu PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wsuggest-override>)
|
||||
|
|
|
@ -213,7 +213,8 @@ void Texture::detach_from(FrameBuffer *fb)
|
|||
void Texture::update(eGPUDataFormat format, const void *data)
|
||||
{
|
||||
int mip = 0;
|
||||
int extent[3], offset[3] = {0, 0, 0};
|
||||
int extent[3] = {1, 1, 1};
|
||||
int offset[3] = {0, 0, 0};
|
||||
this->mip_size_get(mip, extent);
|
||||
this->update_sub(mip, offset, extent, format, data);
|
||||
}
|
||||
|
|
|
@ -759,7 +759,8 @@ inline size_t to_bytesize(eGPUTextureFormat tex_format, eGPUDataFormat data_form
|
|||
}
|
||||
|
||||
/* Definitely not complete, edit according to the gl specification. */
|
||||
inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
|
||||
constexpr inline bool validate_data_format(eGPUTextureFormat tex_format,
|
||||
eGPUDataFormat data_format)
|
||||
{
|
||||
switch (tex_format) {
|
||||
/* Formats texture & render-buffer */
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#ifdef WITH_RENDERDOC
|
||||
# include "renderdoc_api.hh"
|
||||
#endif
|
||||
|
||||
#include "gl_batch.hh"
|
||||
#include "gl_compute.hh"
|
||||
#include "gl_context.hh"
|
||||
|
@ -30,6 +34,9 @@ namespace gpu {
|
|||
class GLBackend : public GPUBackend {
|
||||
private:
|
||||
GLSharedOrphanLists shared_orphan_list_;
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc::api::Renderdoc renderdoc_;
|
||||
#endif
|
||||
|
||||
public:
|
||||
GLBackend()
|
||||
|
@ -155,6 +162,9 @@ class GLBackend : public GPUBackend {
|
|||
void render_end(void) override{};
|
||||
void render_step(void) override{};
|
||||
|
||||
bool debug_capture_begin();
|
||||
void debug_capture_end();
|
||||
|
||||
private:
|
||||
static void platform_init();
|
||||
static void platform_exit();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "gl_backend.hh"
|
||||
#include "gl_context.hh"
|
||||
#include "gl_uniform_buffer.hh"
|
||||
|
||||
|
@ -382,11 +383,28 @@ void GLContext::debug_group_end()
|
|||
|
||||
bool GLContext::debug_capture_begin()
|
||||
{
|
||||
return GLBackend::get()->debug_capture_begin();
|
||||
}
|
||||
|
||||
bool GLBackend::debug_capture_begin()
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
return renderdoc_.start_frame_capture(nullptr, nullptr);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLContext::debug_capture_end()
|
||||
{
|
||||
GLBackend::get()->debug_capture_end();
|
||||
}
|
||||
|
||||
void GLBackend::debug_capture_end()
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc_.end_frame_capture(nullptr, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *GLContext::debug_capture_scope_create(const char * /*name*/)
|
||||
|
|
|
@ -5,36 +5,48 @@
|
|||
#include "CLG_log.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_debug.h"
|
||||
#include "GPU_init_exit.h"
|
||||
#include "gpu_testing.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
void GPUTest::SetUp()
|
||||
{
|
||||
prev_g_debug_ = G.debug;
|
||||
G.debug |= G_DEBUG_GPU;
|
||||
|
||||
CLG_init();
|
||||
GPU_backend_type_selection_set(gpu_backend_type);
|
||||
GHOST_GLSettings glSettings = {};
|
||||
glSettings.context_type = draw_context_type;
|
||||
glSettings.flags = GHOST_glDebugContext;
|
||||
CLG_init();
|
||||
ghost_system = GHOST_CreateSystem();
|
||||
ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
|
||||
GHOST_ActivateOpenGLContext(ghost_context);
|
||||
context = GPU_context_create(nullptr, ghost_context);
|
||||
GPU_init();
|
||||
|
||||
GPU_context_begin_frame(context);
|
||||
GPU_debug_capture_begin();
|
||||
}
|
||||
|
||||
void GPUTest::TearDown()
|
||||
{
|
||||
GPU_debug_capture_end();
|
||||
GPU_context_end_frame(context);
|
||||
|
||||
GPU_exit();
|
||||
GPU_context_discard(context);
|
||||
GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
|
||||
GHOST_DisposeSystem(ghost_system);
|
||||
CLG_exit();
|
||||
|
||||
G.debug = prev_g_debug_;
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -24,6 +24,8 @@ class GPUTest : public ::testing::Test {
|
|||
GHOST_ContextHandle ghost_context;
|
||||
struct GPUContext *context;
|
||||
|
||||
int32_t prev_g_debug_;
|
||||
|
||||
protected:
|
||||
GPUTest(GHOST_TDrawingContextType draw_context_type, eGPUBackendType gpu_backend_type)
|
||||
: draw_context_type(draw_context_type), gpu_backend_type(gpu_backend_type)
|
||||
|
|
|
@ -78,6 +78,11 @@ struct Shader {
|
|||
GPUShader *shader = nullptr;
|
||||
Vector<CallData> call_datas;
|
||||
|
||||
Shader()
|
||||
{
|
||||
call_datas.reserve(10);
|
||||
}
|
||||
|
||||
~Shader()
|
||||
{
|
||||
if (shader != nullptr) {
|
||||
|
@ -117,7 +122,9 @@ struct Shader {
|
|||
|
||||
void dispatch()
|
||||
{
|
||||
GPU_compute_dispatch(shader, 1, 1, 1);
|
||||
/* Dispatching 1000000 times to add some stress to the GPU. Without it tests may succeed when
|
||||
* using too simple shaders. */
|
||||
GPU_compute_dispatch(shader, 1000, 1000, 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -177,11 +184,7 @@ static void test_push_constants_512bytes()
|
|||
}
|
||||
GPU_TEST(push_constants_512bytes)
|
||||
|
||||
#if 0
|
||||
/* Schedule multiple simultaneously. */
|
||||
/* These test have been disabled for now as this will to be solved in a separate PR.
|
||||
* - `DescriptorSets` may not be altered, when they are in the command queue or being executed.
|
||||
*/
|
||||
static void test_push_constants_multiple()
|
||||
{
|
||||
do_push_constants_test("gpu_push_constants_test", 10);
|
||||
|
@ -205,6 +208,5 @@ static void test_push_constants_multiple_512bytes()
|
|||
do_push_constants_test("gpu_push_constants_512bytes_test", 10);
|
||||
}
|
||||
GPU_TEST(push_constants_multiple_512bytes)
|
||||
#endif
|
||||
|
||||
} // namespace blender::gpu::tests
|
||||
|
|
|
@ -5,10 +5,23 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "gpu_texture_private.hh"
|
||||
|
||||
/* Not all texture types are supported by all platforms. This define safe guards them until we have
|
||||
* a working workaround or decided to remove support for those texture types. */
|
||||
#define RUN_UNSUPPORTED false
|
||||
|
||||
/* Skip tests that haven't been developed yet due to non standard data types or it needs an
|
||||
* framebuffer to create the texture. */
|
||||
#define RUN_SRGB_UNIMPLEMENTED false
|
||||
#define RUN_NON_STANDARD_UNIMPLEMENTED false
|
||||
#define RUN_COMPONENT_UNIMPLEMENTED false
|
||||
|
||||
namespace blender::gpu::tests {
|
||||
|
||||
static void test_texture_read()
|
||||
|
@ -48,4 +61,709 @@ static void test_texture_read()
|
|||
}
|
||||
GPU_TEST(texture_read)
|
||||
|
||||
template<typename DataType> static DataType *generate_test_data(size_t data_len)
|
||||
{
|
||||
DataType *data = static_cast<DataType *>(MEM_mallocN(data_len * sizeof(DataType), __func__));
|
||||
for (int i : IndexRange(data_len)) {
|
||||
if (std::is_same<DataType, float>()) {
|
||||
data[i] = (DataType)(i % 8) / 8.0f;
|
||||
}
|
||||
else {
|
||||
data[i] = (DataType)(i % 8);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
template<eGPUTextureFormat DeviceFormat,
|
||||
eGPUDataFormat HostFormat,
|
||||
typename DataType,
|
||||
int Size = 16>
|
||||
static void texture_create_upload_read()
|
||||
{
|
||||
static_assert(!std::is_same<DataType, float>());
|
||||
static_assert(validate_data_format(DeviceFormat, HostFormat));
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUTexture *texture = GPU_texture_create_2d(
|
||||
"texture", Size, Size, 1, DeviceFormat, usage, nullptr);
|
||||
if (texture == nullptr) {
|
||||
GTEST_SKIP() << "Platform doesn't support texture format [" << STRINGIFY(DeviceFormat) << "]";
|
||||
}
|
||||
|
||||
size_t data_len = Size * Size * to_component_len(DeviceFormat);
|
||||
DataType *data = static_cast<DataType *>(generate_test_data<DataType>(data_len));
|
||||
GPU_texture_update(texture, HostFormat, data);
|
||||
|
||||
DataType *read_data = static_cast<DataType *>(GPU_texture_read(texture, HostFormat, 0));
|
||||
bool failed = false;
|
||||
for (int i : IndexRange(data_len)) {
|
||||
bool ok = (read_data[i] - data[i]) == 0;
|
||||
failed |= !ok;
|
||||
}
|
||||
EXPECT_FALSE(failed);
|
||||
|
||||
MEM_freeN(read_data);
|
||||
MEM_freeN(data);
|
||||
|
||||
GPU_texture_free(texture);
|
||||
}
|
||||
|
||||
template<eGPUTextureFormat DeviceFormat, eGPUDataFormat HostFormat, int Size = 16>
|
||||
static void texture_create_upload_read_with_bias(float max_allowed_bias)
|
||||
{
|
||||
static_assert(validate_data_format(DeviceFormat, HostFormat));
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUTexture *texture = GPU_texture_create_2d(
|
||||
"texture", Size, Size, 1, DeviceFormat, usage, nullptr);
|
||||
if (texture == nullptr) {
|
||||
GTEST_SKIP() << "Platform doesn't support texture format [" << STRINGIFY(DeviceFormat) << "]";
|
||||
}
|
||||
|
||||
size_t data_len = Size * Size * to_component_len(DeviceFormat);
|
||||
float *data = static_cast<float *>(generate_test_data<float>(data_len));
|
||||
GPU_texture_update(texture, HostFormat, data);
|
||||
|
||||
float *read_data = static_cast<float *>(GPU_texture_read(texture, HostFormat, 0));
|
||||
float max_used_bias = 0.0f;
|
||||
for (int i : IndexRange(data_len)) {
|
||||
float bias = abs(read_data[i] - data[i]);
|
||||
max_used_bias = max_ff(max_used_bias, bias);
|
||||
}
|
||||
EXPECT_LE(max_used_bias, max_allowed_bias);
|
||||
|
||||
MEM_freeN(read_data);
|
||||
MEM_freeN(data);
|
||||
|
||||
GPU_texture_free(texture);
|
||||
}
|
||||
|
||||
/* Derivative of texture_create_upload_read_pixels that doesn't test each component, but a pixel at
|
||||
* a time. This is needed to check the R11G11B10 and similar types. */
|
||||
template<eGPUTextureFormat DeviceFormat, eGPUDataFormat HostFormat, int Size = 16>
|
||||
static void texture_create_upload_read_pixel()
|
||||
{
|
||||
using DataType = uint32_t;
|
||||
static_assert(validate_data_format(DeviceFormat, HostFormat));
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUTexture *texture = GPU_texture_create_2d(
|
||||
"texture", Size, Size, 1, DeviceFormat, usage, nullptr);
|
||||
ASSERT_NE(texture, nullptr);
|
||||
|
||||
size_t data_len = Size * Size;
|
||||
DataType *data = static_cast<DataType *>(generate_test_data<DataType>(data_len));
|
||||
GPU_texture_update(texture, HostFormat, data);
|
||||
|
||||
DataType *read_data = static_cast<DataType *>(GPU_texture_read(texture, HostFormat, 0));
|
||||
bool failed = false;
|
||||
for (int i : IndexRange(data_len)) {
|
||||
bool ok = (read_data[i] - data[i]) == 0;
|
||||
failed |= !ok;
|
||||
}
|
||||
EXPECT_FALSE(failed);
|
||||
|
||||
MEM_freeN(read_data);
|
||||
MEM_freeN(data);
|
||||
|
||||
GPU_texture_free(texture);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_FLOAT
|
||||
* \{ */
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA8, GPU_DATA_FLOAT>(0.004f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA16F, GPU_DATA_FLOAT>(0.9f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA16, GPU_DATA_FLOAT>(0.00002f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA32F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA32F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA32F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RG8, GPU_DATA_FLOAT>(0.004f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RG16F, GPU_DATA_FLOAT>(0.9f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RG16, GPU_DATA_FLOAT>(0.00002f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG32F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RG32F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG32F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R8()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R8, GPU_DATA_FLOAT>(0.004f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R16F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R16F, GPU_DATA_FLOAT>(0.9f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R16()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R16, GPU_DATA_FLOAT>(0.00002f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R32F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R32F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R32F);
|
||||
|
||||
#if RUN_NON_STANDARD_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB10_A2, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB10_A2UI, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R11F_G11F_B10F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F);
|
||||
#endif
|
||||
|
||||
#if RUN_SRGB_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_SRGB8_A8, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8);
|
||||
#endif
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA8_SNORM, GPU_DATA_FLOAT>(0.004f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_SNORM);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA16_SNORM, GPU_DATA_FLOAT>(0.00002f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16_SNORM);
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB8, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB8_SNORM, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8_SNORM);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB16F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB16, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16);
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB16_SNORM, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16_SNORM);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB32F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB32F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB32F);
|
||||
#endif
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RG8_SNORM, GPU_DATA_FLOAT>(0.004f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8_SNORM);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RG16_SNORM, GPU_DATA_FLOAT>(0.00002f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16_SNORM);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R8_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R8_SNORM, GPU_DATA_FLOAT>(0.004f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R8_SNORM);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R16_SNORM()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_R16_SNORM, GPU_DATA_FLOAT>(0.00002f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16_SNORM);
|
||||
|
||||
#if RUN_NON_STANDARD_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT1()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_SRGB8_A8_DXT1, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT1);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT3()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_SRGB8_A8_DXT3, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT3);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT5()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_SRGB8_A8_DXT5, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT5);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT1()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA8_DXT1, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT1);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT3()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA8_DXT3, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT3);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT5()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGBA8_DXT5, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT5);
|
||||
#endif
|
||||
|
||||
#if RUN_SRGB_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_SRGB8, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8);
|
||||
#endif
|
||||
|
||||
#if RUN_NON_STANDARD_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_RGB9_E5, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5);
|
||||
#endif
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_DEPTH_COMPONENT32F, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F);
|
||||
#endif
|
||||
|
||||
#if RUN_COMPONENT_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT24()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_DEPTH_COMPONENT24, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT24);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16()
|
||||
{
|
||||
texture_create_upload_read_with_bias<GPU_DEPTH_COMPONENT16, GPU_DATA_FLOAT>(0.0f);
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16);
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_HALF_FLOAT
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA16F, GPU_DATA_HALF_FLOAT, uint16_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RG16F()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG16F, GPU_DATA_HALF_FLOAT, uint16_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RG16F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_R16F()
|
||||
{
|
||||
texture_create_upload_read<GPU_R16F, GPU_DATA_HALF_FLOAT, uint16_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_R16F);
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB16F, GPU_DATA_HALF_FLOAT, uint16_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F);
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_INT
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA8I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA16I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA16I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA16I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA32I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA32I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA32I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG8I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG8I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG8I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG16I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG16I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG16I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG32I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG32I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG32I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_R8I()
|
||||
{
|
||||
texture_create_upload_read<GPU_R8I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R8I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_R16I()
|
||||
{
|
||||
texture_create_upload_read<GPU_R16I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R16I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_R32I()
|
||||
{
|
||||
texture_create_upload_read<GPU_R32I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R32I);
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB8I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB8I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB8I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB16I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB16I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB16I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB32I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB32I, GPU_DATA_INT, int32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB32I);
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_UINT
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA8UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA16UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA16UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA16UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA32UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA32UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA32UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RG8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG8UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RG16UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG16UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG16UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RG32UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG32UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG32UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_R8UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R16UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_R16UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R16UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R32UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_R32UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R32UI);
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH32F_STENCIL8, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH24_STENCIL8()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH24_STENCIL8, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH24_STENCIL8);
|
||||
#endif
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB8UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB16UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB16UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB16UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB32UI, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI);
|
||||
#endif
|
||||
|
||||
#if RUN_COMPONENT_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH_COMPONENT32F, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH_COMPONENT24, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH_COMPONENT16, GPU_DATA_UINT, uint32_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16);
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_UBYTE
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA8UI, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGBA8, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG8UI, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8()
|
||||
{
|
||||
texture_create_upload_read<GPU_RG8, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_R8UI()
|
||||
{
|
||||
texture_create_upload_read<GPU_R8UI, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8UI);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_R8()
|
||||
{
|
||||
texture_create_upload_read<GPU_R8, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8);
|
||||
|
||||
#if RUN_SRGB_UNIMPLEMENTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8()
|
||||
{
|
||||
texture_create_upload_read<GPU_SRGB8_A8, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8);
|
||||
#endif
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB8I, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8()
|
||||
{
|
||||
texture_create_upload_read<GPU_RGB8, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8()
|
||||
{
|
||||
texture_create_upload_read<GPU_SRGB8, GPU_DATA_UBYTE, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8);
|
||||
#endif
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_UINT_24_8
|
||||
* \{ */
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH32F_STENCIL8()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH32F_STENCIL8, GPU_DATA_UINT_24_8, void>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH32F_STENCIL8);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH24_STENCIL8()
|
||||
{
|
||||
texture_create_upload_read<GPU_DEPTH24_STENCIL8, GPU_DATA_UINT_24_8, void>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH24_STENCIL8);
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_10_11_11_REV
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F()
|
||||
{
|
||||
texture_create_upload_read<GPU_R11F_G11F_B10F, GPU_DATA_10_11_11_REV, uint8_t>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F);
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_2_10_10_10_REV
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2()
|
||||
{
|
||||
texture_create_upload_read_pixel<GPU_RGB10_A2, GPU_DATA_2_10_10_10_REV>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2);
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI()
|
||||
{
|
||||
texture_create_upload_read_pixel<GPU_RGB10_A2UI, GPU_DATA_2_10_10_10_REV>();
|
||||
}
|
||||
GPU_TEST(texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI);
|
||||
|
||||
/* \} */
|
||||
|
||||
} // namespace blender::gpu::tests
|
||||
|
|
|
@ -66,13 +66,14 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_
|
|||
VKShader *shader = static_cast<VKShader *>(context.shader);
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
VKPipeline &pipeline = shader->pipeline_get();
|
||||
VKDescriptorSet &descriptor_set = pipeline.descriptor_set_get();
|
||||
VKDescriptorSetTracker &descriptor_set = pipeline.descriptor_set_get();
|
||||
VKPushConstants &push_constants = pipeline.push_constants_get();
|
||||
|
||||
push_constants.update(context);
|
||||
descriptor_set.update(context.device_get());
|
||||
command_buffer.bind(
|
||||
descriptor_set, shader->vk_pipeline_layout_get(), VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||
descriptor_set.update(context);
|
||||
command_buffer.bind(*descriptor_set.active_descriptor_set(),
|
||||
shader->vk_pipeline_layout_get(),
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
#include "gpu_backend.hh"
|
||||
|
||||
#ifdef WITH_RENDERDOC
|
||||
# include "renderdoc_api.hh"
|
||||
#endif
|
||||
|
||||
#include "vk_common.hh"
|
||||
|
||||
#include "shaderc/shaderc.hpp"
|
||||
|
@ -20,6 +24,9 @@ class VKContext;
|
|||
class VKBackend : public GPUBackend {
|
||||
private:
|
||||
shaderc::Compiler shaderc_compiler_;
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc::api::Renderdoc renderdoc_api_;
|
||||
#endif
|
||||
|
||||
public:
|
||||
VKBackend()
|
||||
|
@ -59,10 +66,18 @@ class VKBackend : public GPUBackend {
|
|||
void render_end() override;
|
||||
void render_step() override;
|
||||
|
||||
bool debug_capture_begin(VkInstance vk_instance);
|
||||
void debug_capture_end(VkInstance vk_instance);
|
||||
|
||||
shaderc::Compiler &get_shaderc_compiler();
|
||||
|
||||
static void capabilities_init(VKContext &context);
|
||||
|
||||
static VKBackend &get()
|
||||
{
|
||||
return *static_cast<VKBackend *>(GPUBackend::get());
|
||||
}
|
||||
|
||||
private:
|
||||
static void init_platform();
|
||||
static void platform_exit();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_context.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
#include "gpu_context_private.hh"
|
||||
|
||||
#include "vk_common.hh"
|
||||
#include "vk_context.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKContext;
|
||||
|
||||
/**
|
||||
* Class for handing vulkan buffers (allocation/updating/binding).
|
||||
|
|
|
@ -32,6 +32,7 @@ void VKCommandBuffer::init(const VkDevice vk_device,
|
|||
vk_device_ = vk_device;
|
||||
vk_queue_ = vk_queue;
|
||||
vk_command_buffer_ = vk_command_buffer;
|
||||
submission_id_.reset();
|
||||
|
||||
if (vk_fence_ == VK_NULL_HANDLE) {
|
||||
VK_ALLOCATION_CALLBACKS;
|
||||
|
@ -102,6 +103,30 @@ void VKCommandBuffer::copy(VKBuffer &dst_buffer,
|
|||
regions.size(),
|
||||
regions.data());
|
||||
}
|
||||
void VKCommandBuffer::copy(VKTexture &dst_texture,
|
||||
VKBuffer &src_buffer,
|
||||
Span<VkBufferImageCopy> regions)
|
||||
{
|
||||
vkCmdCopyBufferToImage(vk_command_buffer_,
|
||||
src_buffer.vk_handle(),
|
||||
dst_texture.vk_image_handle(),
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
regions.size(),
|
||||
regions.data());
|
||||
}
|
||||
|
||||
void VKCommandBuffer::clear(VkImage vk_image,
|
||||
VkImageLayout vk_image_layout,
|
||||
const VkClearColorValue &vk_clear_color,
|
||||
Span<VkImageSubresourceRange> ranges)
|
||||
{
|
||||
vkCmdClearColorImage(vk_command_buffer_,
|
||||
vk_image,
|
||||
vk_image_layout,
|
||||
&vk_clear_color,
|
||||
ranges.size(),
|
||||
ranges.data());
|
||||
}
|
||||
|
||||
void VKCommandBuffer::pipeline_barrier(VkPipelineStageFlags source_stages,
|
||||
VkPipelineStageFlags destination_stages)
|
||||
|
@ -160,6 +185,7 @@ void VKCommandBuffer::submit_encoded_commands()
|
|||
submit_info.pCommandBuffers = &vk_command_buffer_;
|
||||
|
||||
vkQueueSubmit(vk_queue_, 1, &submit_info, vk_fence_);
|
||||
submission_id_.next();
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk_common.hh"
|
||||
#include "vk_resource_tracker.hh"
|
||||
|
||||
#include "BLI_utility_mixins.hh"
|
||||
|
||||
|
@ -27,6 +28,7 @@ class VKCommandBuffer : NonCopyable, NonMovable {
|
|||
|
||||
/** Owning handles */
|
||||
VkFence vk_fence_ = VK_NULL_HANDLE;
|
||||
VKSubmissionID submission_id_;
|
||||
|
||||
public:
|
||||
virtual ~VKCommandBuffer();
|
||||
|
@ -48,9 +50,17 @@ class VKCommandBuffer : NonCopyable, NonMovable {
|
|||
void dispatch(int groups_x_len, int groups_y_len, int groups_z_len);
|
||||
/** Copy the contents of a texture MIP level to the dst buffer. */
|
||||
void copy(VKBuffer &dst_buffer, VKTexture &src_texture, Span<VkBufferImageCopy> regions);
|
||||
void copy(VKTexture &dst_texture, VKBuffer &src_buffer, Span<VkBufferImageCopy> regions);
|
||||
void pipeline_barrier(VkPipelineStageFlags source_stages,
|
||||
VkPipelineStageFlags destination_stages);
|
||||
void pipeline_barrier(Span<VkImageMemoryBarrier> image_memory_barriers);
|
||||
/**
|
||||
* Clear color image resource.
|
||||
*/
|
||||
void clear(VkImage vk_image,
|
||||
VkImageLayout vk_image_layout,
|
||||
const VkClearColorValue &vk_clear_color,
|
||||
Span<VkImageSubresourceRange> ranges);
|
||||
void fill(VKBuffer &buffer, uint32_t data);
|
||||
|
||||
/**
|
||||
|
@ -59,6 +69,11 @@ class VKCommandBuffer : NonCopyable, NonMovable {
|
|||
*/
|
||||
void submit();
|
||||
|
||||
const VKSubmissionID &submission_id_get() const
|
||||
{
|
||||
return submission_id_;
|
||||
}
|
||||
|
||||
private:
|
||||
void encode_recorded_commands();
|
||||
void submit_encoded_commands();
|
||||
|
|
|
@ -120,35 +120,4 @@ void VKContext::memory_statistics_get(int * /*total_mem*/, int * /*free_mem*/)
|
|||
{
|
||||
}
|
||||
|
||||
void VKContext::debug_group_begin(const char *, int)
|
||||
{
|
||||
}
|
||||
|
||||
void VKContext::debug_group_end()
|
||||
{
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_begin()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_end()
|
||||
{
|
||||
}
|
||||
|
||||
void *VKContext::debug_capture_scope_create(const char * /*name*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_scope_begin(void * /*scope*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_scope_end(void * /*scope*/)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -0,0 +1,780 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "vk_data_conversion.hh"
|
||||
|
||||
#include "Imath/half.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Conversion types
|
||||
* \{ */
|
||||
|
||||
enum class ConversionType {
|
||||
/** No conversion needed, result can be directly read back to host memory. */
|
||||
PASS_THROUGH,
|
||||
|
||||
FLOAT_TO_UNORM8,
|
||||
UNORM8_TO_FLOAT,
|
||||
|
||||
FLOAT_TO_SNORM8,
|
||||
SNORM8_TO_FLOAT,
|
||||
|
||||
FLOAT_TO_UNORM16,
|
||||
UNORM16_TO_FLOAT,
|
||||
|
||||
FLOAT_TO_SNORM16,
|
||||
SNORM16_TO_FLOAT,
|
||||
|
||||
UI32_TO_UI16,
|
||||
UI16_TO_UI32,
|
||||
|
||||
UI32_TO_UI8,
|
||||
UI8_TO_UI32,
|
||||
|
||||
I32_TO_I16,
|
||||
I16_TO_I32,
|
||||
|
||||
I32_TO_I8,
|
||||
I8_TO_I32,
|
||||
|
||||
/** Convert device 16F to floats. */
|
||||
HALF_TO_FLOAT,
|
||||
FLOAT_TO_HALF,
|
||||
|
||||
/**
|
||||
* The requested conversion isn't supported.
|
||||
*/
|
||||
UNSUPPORTED,
|
||||
};
|
||||
|
||||
static ConversionType type_of_conversion_float(eGPUTextureFormat device_format)
|
||||
{
|
||||
switch (device_format) {
|
||||
case GPU_RGBA32F:
|
||||
case GPU_RG32F:
|
||||
case GPU_R32F:
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
case GPU_RGBA16F:
|
||||
case GPU_RG16F:
|
||||
case GPU_R16F:
|
||||
case GPU_RGB16F:
|
||||
return ConversionType::FLOAT_TO_HALF;
|
||||
|
||||
case GPU_RGBA8:
|
||||
case GPU_RG8:
|
||||
case GPU_R8:
|
||||
return ConversionType::FLOAT_TO_UNORM8;
|
||||
|
||||
case GPU_RGBA8_SNORM:
|
||||
case GPU_RGB8_SNORM:
|
||||
case GPU_RG8_SNORM:
|
||||
case GPU_R8_SNORM:
|
||||
return ConversionType::FLOAT_TO_SNORM8;
|
||||
|
||||
case GPU_RGBA16:
|
||||
case GPU_RG16:
|
||||
case GPU_R16:
|
||||
return ConversionType::FLOAT_TO_UNORM16;
|
||||
|
||||
case GPU_RGBA16_SNORM:
|
||||
case GPU_RGB16_SNORM:
|
||||
case GPU_RG16_SNORM:
|
||||
case GPU_R16_SNORM:
|
||||
return ConversionType::FLOAT_TO_SNORM16;
|
||||
|
||||
case GPU_RGB32F: /* GPU_RGB32F Not supported by vendors. */
|
||||
case GPU_RGBA8UI:
|
||||
case GPU_RGBA8I:
|
||||
case GPU_RGBA16UI:
|
||||
case GPU_RGBA16I:
|
||||
case GPU_RGBA32UI:
|
||||
case GPU_RGBA32I:
|
||||
case GPU_RG8UI:
|
||||
case GPU_RG8I:
|
||||
case GPU_RG16UI:
|
||||
case GPU_RG16I:
|
||||
case GPU_RG32UI:
|
||||
case GPU_RG32I:
|
||||
case GPU_R8UI:
|
||||
case GPU_R8I:
|
||||
case GPU_R16UI:
|
||||
case GPU_R16I:
|
||||
case GPU_R32UI:
|
||||
case GPU_R32I:
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_RGB10_A2UI:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
case GPU_SRGB8_A8:
|
||||
case GPU_RGB8UI:
|
||||
case GPU_RGB8I:
|
||||
case GPU_RGB8:
|
||||
case GPU_RGB16UI:
|
||||
case GPU_RGB16I:
|
||||
case GPU_RGB16:
|
||||
case GPU_RGB32UI:
|
||||
case GPU_RGB32I:
|
||||
case GPU_SRGB8_A8_DXT1:
|
||||
case GPU_SRGB8_A8_DXT3:
|
||||
case GPU_SRGB8_A8_DXT5:
|
||||
case GPU_RGBA8_DXT1:
|
||||
case GPU_RGBA8_DXT3:
|
||||
case GPU_RGBA8_DXT5:
|
||||
case GPU_SRGB8:
|
||||
case GPU_RGB9_E5:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType type_of_conversion_int(eGPUTextureFormat device_format)
|
||||
{
|
||||
switch (device_format) {
|
||||
case GPU_RGBA32I:
|
||||
case GPU_RG32I:
|
||||
case GPU_R32I:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
case GPU_RGBA16I:
|
||||
case GPU_RG16I:
|
||||
case GPU_R16I:
|
||||
return ConversionType::I32_TO_I16;
|
||||
|
||||
case GPU_RGBA8I:
|
||||
case GPU_RG8I:
|
||||
case GPU_R8I:
|
||||
return ConversionType::I32_TO_I8;
|
||||
|
||||
case GPU_RGBA8UI:
|
||||
case GPU_RGBA8:
|
||||
case GPU_RGBA16UI:
|
||||
case GPU_RGBA16F:
|
||||
case GPU_RGBA16:
|
||||
case GPU_RGBA32UI:
|
||||
case GPU_RGBA32F:
|
||||
case GPU_RG8UI:
|
||||
case GPU_RG8:
|
||||
case GPU_RG16UI:
|
||||
case GPU_RG16F:
|
||||
case GPU_RG32UI:
|
||||
case GPU_RG32F:
|
||||
case GPU_RG16:
|
||||
case GPU_R8UI:
|
||||
case GPU_R8:
|
||||
case GPU_R16UI:
|
||||
case GPU_R16F:
|
||||
case GPU_R16:
|
||||
case GPU_R32UI:
|
||||
case GPU_R32F:
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_RGB10_A2UI:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
case GPU_SRGB8_A8:
|
||||
case GPU_RGBA8_SNORM:
|
||||
case GPU_RGBA16_SNORM:
|
||||
case GPU_RGB8UI:
|
||||
case GPU_RGB8I:
|
||||
case GPU_RGB8:
|
||||
case GPU_RGB8_SNORM:
|
||||
case GPU_RGB16UI:
|
||||
case GPU_RGB16I:
|
||||
case GPU_RGB16F:
|
||||
case GPU_RGB16:
|
||||
case GPU_RGB16_SNORM:
|
||||
case GPU_RGB32UI:
|
||||
case GPU_RGB32I:
|
||||
case GPU_RGB32F:
|
||||
case GPU_RG8_SNORM:
|
||||
case GPU_RG16_SNORM:
|
||||
case GPU_R8_SNORM:
|
||||
case GPU_R16_SNORM:
|
||||
case GPU_SRGB8_A8_DXT1:
|
||||
case GPU_SRGB8_A8_DXT3:
|
||||
case GPU_SRGB8_A8_DXT5:
|
||||
case GPU_RGBA8_DXT1:
|
||||
case GPU_RGBA8_DXT3:
|
||||
case GPU_RGBA8_DXT5:
|
||||
case GPU_SRGB8:
|
||||
case GPU_RGB9_E5:
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format)
|
||||
{
|
||||
switch (device_format) {
|
||||
case GPU_RGBA32UI:
|
||||
case GPU_RG32UI:
|
||||
case GPU_R32UI:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
case GPU_RGBA16UI:
|
||||
case GPU_RG16UI:
|
||||
case GPU_R16UI:
|
||||
case GPU_RGB16UI:
|
||||
return ConversionType::UI32_TO_UI16;
|
||||
|
||||
case GPU_RGBA8UI:
|
||||
case GPU_RG8UI:
|
||||
case GPU_R8UI:
|
||||
return ConversionType::UI32_TO_UI8;
|
||||
|
||||
case GPU_RGBA8I:
|
||||
case GPU_RGBA8:
|
||||
case GPU_RGBA16I:
|
||||
case GPU_RGBA16F:
|
||||
case GPU_RGBA16:
|
||||
case GPU_RGBA32I:
|
||||
case GPU_RGBA32F:
|
||||
case GPU_RG8I:
|
||||
case GPU_RG8:
|
||||
case GPU_RG16I:
|
||||
case GPU_RG16F:
|
||||
case GPU_RG16:
|
||||
case GPU_RG32I:
|
||||
case GPU_RG32F:
|
||||
case GPU_R8I:
|
||||
case GPU_R8:
|
||||
case GPU_R16I:
|
||||
case GPU_R16F:
|
||||
case GPU_R16:
|
||||
case GPU_R32I:
|
||||
case GPU_R32F:
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_RGB10_A2UI:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
case GPU_SRGB8_A8:
|
||||
case GPU_RGBA8_SNORM:
|
||||
case GPU_RGBA16_SNORM:
|
||||
case GPU_RGB8UI:
|
||||
case GPU_RGB8I:
|
||||
case GPU_RGB8:
|
||||
case GPU_RGB8_SNORM:
|
||||
case GPU_RGB16I:
|
||||
case GPU_RGB16F:
|
||||
case GPU_RGB16:
|
||||
case GPU_RGB16_SNORM:
|
||||
case GPU_RGB32UI:
|
||||
case GPU_RGB32I:
|
||||
case GPU_RGB32F:
|
||||
case GPU_RG8_SNORM:
|
||||
case GPU_RG16_SNORM:
|
||||
case GPU_R8_SNORM:
|
||||
case GPU_R16_SNORM:
|
||||
case GPU_SRGB8_A8_DXT1:
|
||||
case GPU_SRGB8_A8_DXT3:
|
||||
case GPU_SRGB8_A8_DXT5:
|
||||
case GPU_RGBA8_DXT1:
|
||||
case GPU_RGBA8_DXT3:
|
||||
case GPU_RGBA8_DXT5:
|
||||
case GPU_SRGB8:
|
||||
case GPU_RGB9_E5:
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType type_of_conversion_half(eGPUTextureFormat device_format)
|
||||
{
|
||||
switch (device_format) {
|
||||
case GPU_RGBA16F:
|
||||
case GPU_RG16F:
|
||||
case GPU_R16F:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
case GPU_RGBA8UI:
|
||||
case GPU_RGBA8I:
|
||||
case GPU_RGBA8:
|
||||
case GPU_RGBA16UI:
|
||||
case GPU_RGBA16I:
|
||||
case GPU_RGBA16:
|
||||
case GPU_RGBA32UI:
|
||||
case GPU_RGBA32I:
|
||||
case GPU_RGBA32F:
|
||||
case GPU_RG8UI:
|
||||
case GPU_RG8I:
|
||||
case GPU_RG8:
|
||||
case GPU_RG16UI:
|
||||
case GPU_RG16I:
|
||||
case GPU_RG16:
|
||||
case GPU_RG32UI:
|
||||
case GPU_RG32I:
|
||||
case GPU_RG32F:
|
||||
case GPU_R8UI:
|
||||
case GPU_R8I:
|
||||
case GPU_R8:
|
||||
case GPU_R16UI:
|
||||
case GPU_R16I:
|
||||
case GPU_R16:
|
||||
case GPU_R32UI:
|
||||
case GPU_R32I:
|
||||
case GPU_R32F:
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_RGB10_A2UI:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
case GPU_SRGB8_A8:
|
||||
case GPU_RGBA8_SNORM:
|
||||
case GPU_RGBA16_SNORM:
|
||||
case GPU_RGB8UI:
|
||||
case GPU_RGB8I:
|
||||
case GPU_RGB8:
|
||||
case GPU_RGB8_SNORM:
|
||||
case GPU_RGB16UI:
|
||||
case GPU_RGB16I:
|
||||
case GPU_RGB16F:
|
||||
case GPU_RGB16:
|
||||
case GPU_RGB16_SNORM:
|
||||
case GPU_RGB32UI:
|
||||
case GPU_RGB32I:
|
||||
case GPU_RGB32F:
|
||||
case GPU_RG8_SNORM:
|
||||
case GPU_RG16_SNORM:
|
||||
case GPU_R8_SNORM:
|
||||
case GPU_R16_SNORM:
|
||||
case GPU_SRGB8_A8_DXT1:
|
||||
case GPU_SRGB8_A8_DXT3:
|
||||
case GPU_SRGB8_A8_DXT5:
|
||||
case GPU_RGBA8_DXT1:
|
||||
case GPU_RGBA8_DXT3:
|
||||
case GPU_RGBA8_DXT5:
|
||||
case GPU_SRGB8:
|
||||
case GPU_RGB9_E5:
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType type_of_conversion_ubyte(eGPUTextureFormat device_format)
|
||||
{
|
||||
switch (device_format) {
|
||||
case GPU_RGBA8UI:
|
||||
case GPU_RGBA8:
|
||||
case GPU_RG8UI:
|
||||
case GPU_RG8:
|
||||
case GPU_R8UI:
|
||||
case GPU_R8:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
case GPU_RGBA8I:
|
||||
case GPU_RGBA16UI:
|
||||
case GPU_RGBA16I:
|
||||
case GPU_RGBA16F:
|
||||
case GPU_RGBA16:
|
||||
case GPU_RGBA32UI:
|
||||
case GPU_RGBA32I:
|
||||
case GPU_RGBA32F:
|
||||
case GPU_RG8I:
|
||||
case GPU_RG16UI:
|
||||
case GPU_RG16I:
|
||||
case GPU_RG16F:
|
||||
case GPU_RG16:
|
||||
case GPU_RG32UI:
|
||||
case GPU_RG32I:
|
||||
case GPU_RG32F:
|
||||
case GPU_R8I:
|
||||
case GPU_R16UI:
|
||||
case GPU_R16I:
|
||||
case GPU_R16F:
|
||||
case GPU_R16:
|
||||
case GPU_R32UI:
|
||||
case GPU_R32I:
|
||||
case GPU_R32F:
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_RGB10_A2UI:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
case GPU_SRGB8_A8:
|
||||
case GPU_RGBA8_SNORM:
|
||||
case GPU_RGBA16_SNORM:
|
||||
case GPU_RGB8UI:
|
||||
case GPU_RGB8I:
|
||||
case GPU_RGB8:
|
||||
case GPU_RGB8_SNORM:
|
||||
case GPU_RGB16UI:
|
||||
case GPU_RGB16I:
|
||||
case GPU_RGB16F:
|
||||
case GPU_RGB16:
|
||||
case GPU_RGB16_SNORM:
|
||||
case GPU_RGB32UI:
|
||||
case GPU_RGB32I:
|
||||
case GPU_RGB32F:
|
||||
case GPU_RG8_SNORM:
|
||||
case GPU_RG16_SNORM:
|
||||
case GPU_R8_SNORM:
|
||||
case GPU_R16_SNORM:
|
||||
case GPU_SRGB8_A8_DXT1:
|
||||
case GPU_SRGB8_A8_DXT3:
|
||||
case GPU_SRGB8_A8_DXT5:
|
||||
case GPU_RGBA8_DXT1:
|
||||
case GPU_RGBA8_DXT3:
|
||||
case GPU_RGBA8_DXT5:
|
||||
case GPU_SRGB8:
|
||||
case GPU_RGB9_E5:
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType type_of_conversion_r11g11b10(eGPUTextureFormat device_format)
|
||||
{
|
||||
if (device_format == GPU_R11F_G11F_B10F) {
|
||||
return ConversionType::PASS_THROUGH;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType type_of_conversion_r10g10b10a2(eGPUTextureFormat device_format)
|
||||
{
|
||||
if (ELEM(device_format, GPU_RGB10_A2, GPU_RGB10_A2UI)) {
|
||||
return ConversionType::PASS_THROUGH;
|
||||
}
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType host_to_device(eGPUDataFormat host_format, eGPUTextureFormat device_format)
|
||||
{
|
||||
BLI_assert(validate_data_format(device_format, host_format));
|
||||
|
||||
switch (host_format) {
|
||||
case GPU_DATA_FLOAT:
|
||||
return type_of_conversion_float(device_format);
|
||||
case GPU_DATA_UINT:
|
||||
return type_of_conversion_uint(device_format);
|
||||
case GPU_DATA_INT:
|
||||
return type_of_conversion_int(device_format);
|
||||
case GPU_DATA_HALF_FLOAT:
|
||||
return type_of_conversion_half(device_format);
|
||||
case GPU_DATA_UBYTE:
|
||||
return type_of_conversion_ubyte(device_format);
|
||||
case GPU_DATA_10_11_11_REV:
|
||||
return type_of_conversion_r11g11b10(device_format);
|
||||
case GPU_DATA_2_10_10_10_REV:
|
||||
return type_of_conversion_r10g10b10a2(device_format);
|
||||
|
||||
case GPU_DATA_UINT_24_8:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
static ConversionType reversed(ConversionType type)
|
||||
{
|
||||
#define CASE_SINGLE(a, b) \
|
||||
case ConversionType::a##_TO_##b: \
|
||||
return ConversionType::b##_TO_##a;
|
||||
|
||||
#define CASE_PAIR(a, b) \
|
||||
CASE_SINGLE(a, b) \
|
||||
CASE_SINGLE(b, a)
|
||||
|
||||
switch (type) {
|
||||
case ConversionType::PASS_THROUGH:
|
||||
return ConversionType::PASS_THROUGH;
|
||||
|
||||
CASE_PAIR(FLOAT, UNORM8)
|
||||
CASE_PAIR(FLOAT, SNORM8)
|
||||
CASE_PAIR(FLOAT, UNORM16)
|
||||
CASE_PAIR(FLOAT, SNORM16)
|
||||
CASE_PAIR(UI32, UI16)
|
||||
CASE_PAIR(I32, I16)
|
||||
CASE_PAIR(UI32, UI8)
|
||||
CASE_PAIR(I32, I8)
|
||||
CASE_PAIR(FLOAT, HALF)
|
||||
|
||||
case ConversionType::UNSUPPORTED:
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
#undef CASE_PAIR
|
||||
#undef CASE_SINGLE
|
||||
|
||||
return ConversionType::UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Data Conversion
|
||||
* \{ */
|
||||
|
||||
template<typename InnerType> struct SignedNormalized {
|
||||
static_assert(std::is_same<InnerType, uint8_t>() || std::is_same<InnerType, uint16_t>());
|
||||
InnerType value;
|
||||
|
||||
static constexpr int32_t scalar()
|
||||
{
|
||||
return (1 << (sizeof(InnerType) * 8 - 1));
|
||||
}
|
||||
|
||||
static constexpr int32_t delta()
|
||||
{
|
||||
return (1 << (sizeof(InnerType) * 8 - 1)) - 1;
|
||||
}
|
||||
|
||||
static constexpr int32_t max()
|
||||
{
|
||||
return ((1 << (sizeof(InnerType) * 8)) - 1);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename InnerType> struct UnsignedNormalized {
|
||||
static_assert(std::is_same<InnerType, uint8_t>() || std::is_same<InnerType, uint16_t>());
|
||||
InnerType value;
|
||||
|
||||
static constexpr int32_t scalar()
|
||||
{
|
||||
return (1 << (sizeof(InnerType) * 8)) - 1;
|
||||
}
|
||||
|
||||
static constexpr int32_t max()
|
||||
{
|
||||
return ((1 << (sizeof(InnerType) * 8)) - 1);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename InnerType> struct ComponentValue {
|
||||
InnerType value;
|
||||
};
|
||||
|
||||
using UI8 = ComponentValue<uint8_t>;
|
||||
using UI16 = ComponentValue<uint16_t>;
|
||||
using UI32 = ComponentValue<uint32_t>;
|
||||
using I8 = ComponentValue<int8_t>;
|
||||
using I16 = ComponentValue<int16_t>;
|
||||
using I32 = ComponentValue<int32_t>;
|
||||
using F32 = ComponentValue<float>;
|
||||
using F16 = ComponentValue<uint16_t>;
|
||||
|
||||
template<typename StorageType>
|
||||
void convert_component(SignedNormalized<StorageType> &dst, const F32 &src)
|
||||
{
|
||||
static constexpr int32_t scalar = SignedNormalized<StorageType>::scalar();
|
||||
static constexpr int32_t delta = SignedNormalized<StorageType>::delta();
|
||||
static constexpr int32_t max = SignedNormalized<StorageType>::max();
|
||||
dst.value = (clamp_i((src.value * scalar + delta), 0, max));
|
||||
}
|
||||
|
||||
template<typename StorageType>
|
||||
void convert_component(F32 &dst, const SignedNormalized<StorageType> &src)
|
||||
{
|
||||
static constexpr int32_t scalar = SignedNormalized<StorageType>::scalar();
|
||||
static constexpr int32_t delta = SignedNormalized<StorageType>::delta();
|
||||
dst.value = float(int32_t(src.value) - delta) / scalar;
|
||||
}
|
||||
|
||||
template<typename StorageType>
|
||||
void convert_component(UnsignedNormalized<StorageType> &dst, const F32 &src)
|
||||
{
|
||||
static constexpr int32_t scalar = UnsignedNormalized<StorageType>::scalar();
|
||||
static constexpr int32_t max = scalar;
|
||||
dst.value = (clamp_i((src.value * scalar), 0, max));
|
||||
}
|
||||
|
||||
template<typename StorageType>
|
||||
void convert_component(F32 &dst, const UnsignedNormalized<StorageType> &src)
|
||||
{
|
||||
static constexpr int32_t scalar = UnsignedNormalized<StorageType>::scalar();
|
||||
dst.value = float(src.value) / scalar;
|
||||
}
|
||||
|
||||
/* Copy the contents of src to dst with out performing any actual conversion.*/
|
||||
template<typename DestinationType, typename SourceType>
|
||||
void convert_component(DestinationType &dst, const SourceType &src)
|
||||
{
|
||||
static_assert(std::is_same<DestinationType, UI8>() || std::is_same<DestinationType, UI16>() ||
|
||||
std::is_same<DestinationType, UI32>() || std::is_same<DestinationType, I8>() ||
|
||||
std::is_same<DestinationType, I16>() || std::is_same<DestinationType, I32>());
|
||||
static_assert(std::is_same<SourceType, UI8>() || std::is_same<SourceType, UI16>() ||
|
||||
std::is_same<SourceType, UI32>() || std::is_same<SourceType, I8>() ||
|
||||
std::is_same<SourceType, I16>() || std::is_same<SourceType, I32>());
|
||||
static_assert(!std::is_same<DestinationType, SourceType>());
|
||||
dst.value = src.value;
|
||||
}
|
||||
|
||||
static void convert_component(F16 &dst, const F32 &src)
|
||||
{
|
||||
dst.value = imath_float_to_half(src.value);
|
||||
}
|
||||
|
||||
static void convert_component(F32 &dst, const F16 &src)
|
||||
{
|
||||
dst.value = imath_half_to_float(src.value);
|
||||
}
|
||||
|
||||
/* \} */
|
||||
|
||||
template<typename DestinationType, typename SourceType>
|
||||
void convert_per_component(MutableSpan<DestinationType> dst, Span<SourceType> src)
|
||||
{
|
||||
BLI_assert(src.size() == dst.size());
|
||||
for (int64_t index : IndexRange(src.size())) {
|
||||
convert_component(dst[index], src[index]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DestinationType, typename SourceType>
|
||||
void convert_per_component(void *dst_memory,
|
||||
const void *src_memory,
|
||||
size_t buffer_size,
|
||||
eGPUTextureFormat device_format)
|
||||
{
|
||||
size_t total_components = to_component_len(device_format) * buffer_size;
|
||||
Span<SourceType> src = Span<SourceType>(static_cast<const SourceType *>(src_memory),
|
||||
total_components);
|
||||
MutableSpan<DestinationType> dst = MutableSpan<DestinationType>(
|
||||
static_cast<DestinationType *>(dst_memory), total_components);
|
||||
convert_per_component<DestinationType, SourceType>(dst, src);
|
||||
}
|
||||
|
||||
static void convert_buffer(void *dst_memory,
|
||||
const void *src_memory,
|
||||
size_t buffer_size,
|
||||
eGPUTextureFormat device_format,
|
||||
ConversionType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ConversionType::UNSUPPORTED:
|
||||
return;
|
||||
|
||||
case ConversionType::PASS_THROUGH:
|
||||
memcpy(dst_memory, src_memory, buffer_size * to_bytesize(device_format));
|
||||
return;
|
||||
|
||||
case ConversionType::UI32_TO_UI16:
|
||||
convert_per_component<UI16, UI32>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::UI16_TO_UI32:
|
||||
convert_per_component<UI32, UI16>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::UI32_TO_UI8:
|
||||
convert_per_component<UI8, UI32>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::UI8_TO_UI32:
|
||||
convert_per_component<UI32, UI8>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::I32_TO_I16:
|
||||
convert_per_component<I16, I32>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::I16_TO_I32:
|
||||
convert_per_component<I32, I16>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::I32_TO_I8:
|
||||
convert_per_component<I8, I32>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::I8_TO_I32:
|
||||
convert_per_component<I32, I8>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::FLOAT_TO_SNORM8:
|
||||
convert_per_component<SignedNormalized<uint8_t>, F32>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
case ConversionType::SNORM8_TO_FLOAT:
|
||||
convert_per_component<F32, SignedNormalized<uint8_t>>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::FLOAT_TO_SNORM16:
|
||||
convert_per_component<SignedNormalized<uint16_t>, F32>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
case ConversionType::SNORM16_TO_FLOAT:
|
||||
convert_per_component<F32, SignedNormalized<uint16_t>>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::FLOAT_TO_UNORM8:
|
||||
convert_per_component<UnsignedNormalized<uint8_t>, F32>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
case ConversionType::UNORM8_TO_FLOAT:
|
||||
convert_per_component<F32, UnsignedNormalized<uint8_t>>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::FLOAT_TO_UNORM16:
|
||||
convert_per_component<UnsignedNormalized<uint16_t>, F32>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
case ConversionType::UNORM16_TO_FLOAT:
|
||||
convert_per_component<F32, UnsignedNormalized<uint16_t>>(
|
||||
dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
|
||||
case ConversionType::FLOAT_TO_HALF:
|
||||
convert_per_component<F16, F32>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
case ConversionType::HALF_TO_FLOAT:
|
||||
convert_per_component<F32, F16>(dst_memory, src_memory, buffer_size, device_format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name API
|
||||
* \{ */
|
||||
|
||||
void convert_host_to_device(void *dst_buffer,
|
||||
const void *src_buffer,
|
||||
size_t buffer_size,
|
||||
eGPUDataFormat host_format,
|
||||
eGPUTextureFormat device_format)
|
||||
{
|
||||
ConversionType conversion_type = host_to_device(host_format, device_format);
|
||||
BLI_assert(conversion_type != ConversionType::UNSUPPORTED);
|
||||
convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
|
||||
}
|
||||
|
||||
void convert_device_to_host(void *dst_buffer,
|
||||
const void *src_buffer,
|
||||
size_t buffer_size,
|
||||
eGPUDataFormat host_format,
|
||||
eGPUTextureFormat device_format)
|
||||
{
|
||||
ConversionType conversion_type = reversed(host_to_device(host_format, device_format));
|
||||
BLI_assert(conversion_type != ConversionType::UNSUPPORTED);
|
||||
convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type);
|
||||
}
|
||||
|
||||
/* \} */
|
||||
|
||||
} // namespace blender::gpu
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu_texture_private.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/**
|
||||
* Convert host buffer to device buffer.
|
||||
*
|
||||
* \param dst_buffer: device buffer.
|
||||
* \param src_buffer: host buffer.
|
||||
* \param buffer_size: number of pixels to convert from the start of the given buffer.
|
||||
* \param host_format: format of the host buffer
|
||||
* \param device_format: format of the device buffer.
|
||||
*
|
||||
* \note Will assert when the host_format/device_format combination isn't valid
|
||||
* (#validate_data_format) or supported. Some combinations aren't supported in Vulkan due to
|
||||
* platform incompatibility.
|
||||
*/
|
||||
void convert_host_to_device(void *dst_buffer,
|
||||
const void *src_buffer,
|
||||
size_t buffer_size,
|
||||
eGPUDataFormat host_format,
|
||||
eGPUTextureFormat device_format);
|
||||
|
||||
/**
|
||||
* Convert device buffer to host buffer.
|
||||
*
|
||||
* \param dst_buffer: host buffer
|
||||
* \param src_buffer: device buffer.
|
||||
* \param buffer_size: number of pixels to convert from the start of the given buffer.
|
||||
* \param host_format: format of the host buffer
|
||||
* \param device_format: format of the device buffer.
|
||||
*
|
||||
* \note Will assert when the host_format/device_format combination isn't valid
|
||||
* (#validate_data_format) or supported. Some combinations aren't supported in Vulkan due to
|
||||
* platform incompatibility.
|
||||
*/
|
||||
void convert_device_to_host(void *dst_buffer,
|
||||
const void *src_buffer,
|
||||
size_t buffer_size,
|
||||
eGPUDataFormat host_format,
|
||||
eGPUTextureFormat device_format);
|
||||
|
||||
}; // namespace blender::gpu
|
|
@ -0,0 +1,62 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
void VKContext::debug_group_begin(const char *, int)
|
||||
{
|
||||
}
|
||||
|
||||
void VKContext::debug_group_end()
|
||||
{
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_begin()
|
||||
{
|
||||
return VKBackend::get().debug_capture_begin(vk_instance_);
|
||||
}
|
||||
|
||||
bool VKBackend::debug_capture_begin(VkInstance vk_instance)
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
return renderdoc_api_.start_frame_capture(vk_instance, nullptr);
|
||||
#else
|
||||
UNUSED_VARS(vk_instance);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_end()
|
||||
{
|
||||
VKBackend::get().debug_capture_end(vk_instance_);
|
||||
}
|
||||
|
||||
void VKBackend::debug_capture_end(VkInstance vk_instance)
|
||||
{
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc_api_.end_frame_capture(vk_instance, nullptr);
|
||||
#else
|
||||
UNUSED_VARS(vk_instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *VKContext::debug_capture_scope_create(const char * /*name*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool VKContext::debug_capture_scope_begin(void * /*scope*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void VKContext::debug_capture_scope_end(void * /*scope*/)
|
||||
{
|
||||
}
|
||||
} // namespace blender::gpu
|
|
@ -80,7 +80,8 @@ bool VKDescriptorPools::is_last_pool_active()
|
|||
return active_pool_index_ == pools_.size() - 1;
|
||||
}
|
||||
|
||||
VKDescriptorSet VKDescriptorPools::allocate(const VkDescriptorSetLayout &descriptor_set_layout)
|
||||
std::unique_ptr<VKDescriptorSet> VKDescriptorPools::allocate(
|
||||
const VkDescriptorSetLayout &descriptor_set_layout)
|
||||
{
|
||||
VkDescriptorSetAllocateInfo allocate_info = {};
|
||||
VkDescriptorPool pool = active_pool_get();
|
||||
|
@ -102,7 +103,7 @@ VKDescriptorSet VKDescriptorPools::allocate(const VkDescriptorSetLayout &descrip
|
|||
return allocate(descriptor_set_layout);
|
||||
}
|
||||
|
||||
return VKDescriptorSet(pool, vk_descriptor_set);
|
||||
return std::make_unique<VKDescriptorSet>(pool, vk_descriptor_set);
|
||||
}
|
||||
|
||||
void VKDescriptorPools::free(VKDescriptorSet &descriptor_set)
|
||||
|
|
|
@ -47,7 +47,7 @@ class VKDescriptorPools {
|
|||
|
||||
void init(const VkDevice vk_device);
|
||||
|
||||
VKDescriptorSet allocate(const VkDescriptorSetLayout &descriptor_set_layout);
|
||||
std::unique_ptr<VKDescriptorSet> allocate(const VkDescriptorSetLayout &descriptor_set_layout);
|
||||
void free(VKDescriptorSet &descriptor_set);
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "vk_descriptor_set.hh"
|
||||
#include "vk_index_buffer.hh"
|
||||
#include "vk_shader.hh"
|
||||
#include "vk_storage_buffer.hh"
|
||||
#include "vk_texture.hh"
|
||||
#include "vk_uniform_buffer.hh"
|
||||
|
@ -17,9 +18,7 @@
|
|||
namespace blender::gpu {
|
||||
|
||||
VKDescriptorSet::VKDescriptorSet(VKDescriptorSet &&other)
|
||||
: vk_descriptor_pool_(other.vk_descriptor_pool_),
|
||||
vk_descriptor_set_(other.vk_descriptor_set_),
|
||||
bindings_(std::move(other.bindings_))
|
||||
: vk_descriptor_pool_(other.vk_descriptor_pool_), vk_descriptor_set_(other.vk_descriptor_set_)
|
||||
{
|
||||
other.mark_freed();
|
||||
}
|
||||
|
@ -40,7 +39,8 @@ void VKDescriptorSet::mark_freed()
|
|||
vk_descriptor_pool_ = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void VKDescriptorSet::bind(VKStorageBuffer &buffer, const Location location)
|
||||
void VKDescriptorSetTracker::bind(VKStorageBuffer &buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
|
@ -48,7 +48,8 @@ void VKDescriptorSet::bind(VKStorageBuffer &buffer, const Location location)
|
|||
binding.buffer_size = buffer.size_in_bytes();
|
||||
}
|
||||
|
||||
void VKDescriptorSet::bind_as_ssbo(VKVertexBuffer &buffer, const Location location)
|
||||
void VKDescriptorSetTracker::bind_as_ssbo(VKVertexBuffer &buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
|
@ -56,7 +57,8 @@ void VKDescriptorSet::bind_as_ssbo(VKVertexBuffer &buffer, const Location locati
|
|||
binding.buffer_size = buffer.size_used_get();
|
||||
}
|
||||
|
||||
void VKDescriptorSet::bind(VKUniformBuffer &buffer, const Location location)
|
||||
void VKDescriptorSetTracker::bind(VKUniformBuffer &buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
|
@ -64,7 +66,8 @@ void VKDescriptorSet::bind(VKUniformBuffer &buffer, const Location location)
|
|||
binding.buffer_size = buffer.size_in_bytes();
|
||||
}
|
||||
|
||||
void VKDescriptorSet::bind_as_ssbo(VKIndexBuffer &buffer, const Location location)
|
||||
void VKDescriptorSetTracker::bind_as_ssbo(VKIndexBuffer &buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
|
@ -72,14 +75,16 @@ void VKDescriptorSet::bind_as_ssbo(VKIndexBuffer &buffer, const Location locatio
|
|||
binding.buffer_size = buffer.size_get();
|
||||
}
|
||||
|
||||
void VKDescriptorSet::image_bind(VKTexture &texture, const Location location)
|
||||
void VKDescriptorSetTracker::image_bind(VKTexture &texture,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
binding.vk_image_view = texture.vk_image_view_handle();
|
||||
}
|
||||
|
||||
VKDescriptorSet::Binding &VKDescriptorSet::ensure_location(const Location location)
|
||||
VKDescriptorSetTracker::Binding &VKDescriptorSetTracker::ensure_location(
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
for (Binding &binding : bindings_) {
|
||||
if (binding.location == location) {
|
||||
|
@ -93,8 +98,12 @@ VKDescriptorSet::Binding &VKDescriptorSet::ensure_location(const Location locati
|
|||
return bindings_.last();
|
||||
}
|
||||
|
||||
void VKDescriptorSet::update(VkDevice vk_device)
|
||||
void VKDescriptorSetTracker::update(VKContext &context)
|
||||
{
|
||||
tracked_resource_for(context, !bindings_.is_empty());
|
||||
std::unique_ptr<VKDescriptorSet> &descriptor_set = active_descriptor_set();
|
||||
VkDescriptorSet vk_descriptor_set = descriptor_set->vk_handle();
|
||||
|
||||
Vector<VkDescriptorBufferInfo> buffer_infos;
|
||||
Vector<VkWriteDescriptorSet> descriptor_writes;
|
||||
|
||||
|
@ -109,7 +118,7 @@ void VKDescriptorSet::update(VkDevice vk_device)
|
|||
|
||||
VkWriteDescriptorSet write_descriptor = {};
|
||||
write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write_descriptor.dstSet = vk_descriptor_set_;
|
||||
write_descriptor.dstSet = vk_descriptor_set;
|
||||
write_descriptor.dstBinding = binding.location;
|
||||
write_descriptor.descriptorCount = 1;
|
||||
write_descriptor.descriptorType = binding.type;
|
||||
|
@ -129,7 +138,7 @@ void VKDescriptorSet::update(VkDevice vk_device)
|
|||
|
||||
VkWriteDescriptorSet write_descriptor = {};
|
||||
write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write_descriptor.dstSet = vk_descriptor_set_;
|
||||
write_descriptor.dstSet = vk_descriptor_set;
|
||||
write_descriptor.dstBinding = binding.location;
|
||||
write_descriptor.descriptorCount = 1;
|
||||
write_descriptor.descriptorType = binding.type;
|
||||
|
@ -141,10 +150,16 @@ void VKDescriptorSet::update(VkDevice vk_device)
|
|||
"Not all changes have been converted to a write descriptor. Check "
|
||||
"`Binding::is_buffer` and `Binding::is_image`.");
|
||||
|
||||
VkDevice vk_device = context.device_get();
|
||||
vkUpdateDescriptorSets(
|
||||
vk_device, descriptor_writes.size(), descriptor_writes.data(), 0, nullptr);
|
||||
|
||||
bindings_.clear();
|
||||
}
|
||||
|
||||
std::unique_ptr<VKDescriptorSet> VKDescriptorSetTracker::create_resource(VKContext &context)
|
||||
{
|
||||
return context.descriptor_pools_get().allocate(layout_);
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
|
||||
#include "gpu_shader_private.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_common.hh"
|
||||
#include "vk_resource_tracker.hh"
|
||||
#include "vk_uniform_buffer.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKIndexBuffer;
|
||||
|
@ -21,6 +24,7 @@ class VKStorageBuffer;
|
|||
class VKTexture;
|
||||
class VKUniformBuffer;
|
||||
class VKVertexBuffer;
|
||||
class VKDescriptorSetTracker;
|
||||
|
||||
/**
|
||||
* In vulkan shader resources (images and buffers) are grouped in descriptor sets.
|
||||
|
@ -31,7 +35,6 @@ class VKVertexBuffer;
|
|||
* to use 2 descriptor sets per shader. One for each #blender::gpu::shader::Frequency.
|
||||
*/
|
||||
class VKDescriptorSet : NonCopyable {
|
||||
struct Binding;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -69,42 +72,13 @@ class VKDescriptorSet : NonCopyable {
|
|||
return binding;
|
||||
}
|
||||
|
||||
friend struct Binding;
|
||||
friend struct VKDescriptorSetTracker;
|
||||
friend class VKShaderInterface;
|
||||
};
|
||||
|
||||
private:
|
||||
struct Binding {
|
||||
Location location;
|
||||
VkDescriptorType type;
|
||||
|
||||
VkBuffer vk_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceSize buffer_size = 0;
|
||||
|
||||
VkImageView vk_image_view = VK_NULL_HANDLE;
|
||||
|
||||
Binding()
|
||||
{
|
||||
location.binding = 0;
|
||||
}
|
||||
|
||||
bool is_buffer() const
|
||||
{
|
||||
return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
}
|
||||
|
||||
bool is_image() const
|
||||
{
|
||||
return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
VkDescriptorPool vk_descriptor_pool_ = VK_NULL_HANDLE;
|
||||
VkDescriptorSet vk_descriptor_set_ = VK_NULL_HANDLE;
|
||||
|
||||
/** A list of bindings that needs to be updated. */
|
||||
Vector<Binding> bindings_;
|
||||
|
||||
public:
|
||||
VKDescriptorSet() = default;
|
||||
VKDescriptorSet(VkDescriptorPool vk_descriptor_pool, VkDescriptorSet vk_descriptor_set)
|
||||
|
@ -131,22 +105,73 @@ class VKDescriptorSet : NonCopyable {
|
|||
{
|
||||
return vk_descriptor_pool_;
|
||||
}
|
||||
void mark_freed();
|
||||
};
|
||||
|
||||
void bind_as_ssbo(VKVertexBuffer &buffer, Location location);
|
||||
void bind_as_ssbo(VKIndexBuffer &buffer, Location location);
|
||||
void bind(VKStorageBuffer &buffer, Location location);
|
||||
void bind(VKUniformBuffer &buffer, Location location);
|
||||
void image_bind(VKTexture &texture, Location location);
|
||||
class VKDescriptorSetTracker : protected VKResourceTracker<VKDescriptorSet> {
|
||||
friend class VKDescriptorSet;
|
||||
|
||||
public:
|
||||
struct Binding {
|
||||
VKDescriptorSet::Location location;
|
||||
VkDescriptorType type;
|
||||
|
||||
VkBuffer vk_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceSize buffer_size = 0;
|
||||
|
||||
VkImageView vk_image_view = VK_NULL_HANDLE;
|
||||
|
||||
Binding()
|
||||
{
|
||||
location.binding = 0;
|
||||
}
|
||||
|
||||
bool is_buffer() const
|
||||
{
|
||||
return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
}
|
||||
|
||||
bool is_image() const
|
||||
{
|
||||
return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
/** A list of bindings that needs to be updated.*/
|
||||
Vector<Binding> bindings_;
|
||||
VkDescriptorSetLayout layout_;
|
||||
|
||||
public:
|
||||
VKDescriptorSetTracker()
|
||||
{
|
||||
}
|
||||
|
||||
VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout)
|
||||
{
|
||||
}
|
||||
|
||||
void bind_as_ssbo(VKVertexBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind_as_ssbo(VKIndexBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void image_bind(VKTexture &texture, VKDescriptorSet::Location location);
|
||||
|
||||
/**
|
||||
* Update the descriptor set on the device.
|
||||
*/
|
||||
void update(VkDevice vk_device);
|
||||
void update(VKContext &context);
|
||||
|
||||
void mark_freed();
|
||||
std::unique_ptr<VKDescriptorSet> &active_descriptor_set()
|
||||
{
|
||||
return active_resource();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<VKDescriptorSet> create_resource(VKContext &context) override;
|
||||
|
||||
private:
|
||||
Binding &ensure_location(Location location);
|
||||
Binding &ensure_location(VKDescriptorSet::Location location);
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
namespace blender::gpu {
|
||||
|
||||
VKPipeline::VKPipeline(VkPipeline vk_pipeline,
|
||||
VKDescriptorSet &&descriptor_set,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
VKPushConstants &&push_constants)
|
||||
: vk_pipeline_(vk_pipeline),
|
||||
descriptor_set_(std::move(descriptor_set)),
|
||||
descriptor_set_(vk_descriptor_set_layout),
|
||||
push_constants_(std::move(push_constants))
|
||||
{
|
||||
}
|
||||
|
@ -56,9 +56,8 @@ VKPipeline VKPipeline::create_compute_pipeline(
|
|||
return VKPipeline();
|
||||
}
|
||||
|
||||
VKDescriptorSet descriptor_set = context.descriptor_pools_get().allocate(descriptor_set_layout);
|
||||
VKPushConstants push_constants(&push_constants_layout);
|
||||
return VKPipeline(vk_pipeline, std::move(descriptor_set), std::move(push_constants));
|
||||
return VKPipeline(vk_pipeline, descriptor_set_layout, std::move(push_constants));
|
||||
}
|
||||
|
||||
VkPipeline VKPipeline::vk_handle() const
|
||||
|
|
|
@ -21,7 +21,7 @@ class VKContext;
|
|||
|
||||
class VKPipeline : NonCopyable {
|
||||
VkPipeline vk_pipeline_ = VK_NULL_HANDLE;
|
||||
VKDescriptorSet descriptor_set_;
|
||||
VKDescriptorSetTracker descriptor_set_;
|
||||
VKPushConstants push_constants_;
|
||||
|
||||
public:
|
||||
|
@ -29,7 +29,7 @@ class VKPipeline : NonCopyable {
|
|||
|
||||
virtual ~VKPipeline();
|
||||
VKPipeline(VkPipeline vk_pipeline,
|
||||
VKDescriptorSet &&vk_descriptor_set,
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout,
|
||||
VKPushConstants &&push_constants);
|
||||
VKPipeline &operator=(VKPipeline &&other)
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ class VKPipeline : NonCopyable {
|
|||
VkPipelineLayout &pipeline_layouts,
|
||||
const VKPushConstants::Layout &push_constants_layout);
|
||||
|
||||
VKDescriptorSet &descriptor_set_get()
|
||||
VKDescriptorSetTracker &descriptor_set_get()
|
||||
{
|
||||
return descriptor_set_;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "vk_pixel_buffer.hh"
|
||||
|
||||
#include "vk_context.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
VKPixelBuffer::VKPixelBuffer(int64_t size) : PixelBuffer(size)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "vk_push_constants.hh"
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_memory_layout.hh"
|
||||
#include "vk_shader.hh"
|
||||
#include "vk_shader_interface.hh"
|
||||
|
@ -103,24 +104,12 @@ VKPushConstants::VKPushConstants() = default;
|
|||
VKPushConstants::VKPushConstants(const Layout *layout) : layout_(layout)
|
||||
{
|
||||
data_ = MEM_mallocN(layout->size_in_bytes(), __func__);
|
||||
switch (layout_->storage_type_get()) {
|
||||
case StorageType::UNIFORM_BUFFER:
|
||||
uniform_buffer_ = new VKUniformBuffer(layout_->size_in_bytes(), __func__);
|
||||
break;
|
||||
|
||||
case StorageType::PUSH_CONSTANTS:
|
||||
case StorageType::NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VKPushConstants::VKPushConstants(VKPushConstants &&other) : layout_(other.layout_)
|
||||
{
|
||||
data_ = other.data_;
|
||||
other.data_ = nullptr;
|
||||
|
||||
uniform_buffer_ = other.uniform_buffer_;
|
||||
other.uniform_buffer_ = nullptr;
|
||||
}
|
||||
|
||||
VKPushConstants::~VKPushConstants()
|
||||
|
@ -129,9 +118,6 @@ VKPushConstants::~VKPushConstants()
|
|||
MEM_freeN(data_);
|
||||
data_ = nullptr;
|
||||
}
|
||||
|
||||
delete uniform_buffer_;
|
||||
uniform_buffer_ = nullptr;
|
||||
}
|
||||
|
||||
VKPushConstants &VKPushConstants::operator=(VKPushConstants &&other)
|
||||
|
@ -141,9 +127,6 @@ VKPushConstants &VKPushConstants::operator=(VKPushConstants &&other)
|
|||
data_ = other.data_;
|
||||
other.data_ = nullptr;
|
||||
|
||||
uniform_buffer_ = other.uniform_buffer_;
|
||||
other.uniform_buffer_ = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -155,7 +138,7 @@ void VKPushConstants::update(VKContext &context)
|
|||
BLI_assert_msg(&pipeline.push_constants_get() == this,
|
||||
"Invalid state detected. Push constants doesn't belong to the active shader of "
|
||||
"the given context.");
|
||||
VKDescriptorSet &descriptor_set = pipeline.descriptor_set_get();
|
||||
VKDescriptorSetTracker &descriptor_set = pipeline.descriptor_set_get();
|
||||
|
||||
switch (layout_get().storage_type_get()) {
|
||||
case VKPushConstants::StorageType::NONE:
|
||||
|
@ -167,7 +150,7 @@ void VKPushConstants::update(VKContext &context)
|
|||
|
||||
case VKPushConstants::StorageType::UNIFORM_BUFFER:
|
||||
update_uniform_buffer();
|
||||
descriptor_set.bind(uniform_buffer_get(), layout_get().descriptor_set_location_get());
|
||||
descriptor_set.bind(*uniform_buffer_get(), layout_get().descriptor_set_location_get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -175,16 +158,22 @@ void VKPushConstants::update(VKContext &context)
|
|||
void VKPushConstants::update_uniform_buffer()
|
||||
{
|
||||
BLI_assert(layout_->storage_type_get() == StorageType::UNIFORM_BUFFER);
|
||||
BLI_assert(uniform_buffer_ != nullptr);
|
||||
BLI_assert(data_ != nullptr);
|
||||
uniform_buffer_->update(data_);
|
||||
VKContext &context = *VKContext::get();
|
||||
std::unique_ptr<VKUniformBuffer> &uniform_buffer = tracked_resource_for(context, is_dirty_);
|
||||
uniform_buffer->update(data_);
|
||||
is_dirty_ = false;
|
||||
}
|
||||
|
||||
VKUniformBuffer &VKPushConstants::uniform_buffer_get()
|
||||
std::unique_ptr<VKUniformBuffer> &VKPushConstants::uniform_buffer_get()
|
||||
{
|
||||
BLI_assert(layout_->storage_type_get() == StorageType::UNIFORM_BUFFER);
|
||||
BLI_assert(uniform_buffer_ != nullptr);
|
||||
return *uniform_buffer_;
|
||||
return active_resource();
|
||||
}
|
||||
|
||||
std::unique_ptr<VKUniformBuffer> VKPushConstants::create_resource(VKContext & /*context*/)
|
||||
{
|
||||
return std::make_unique<VKUniformBuffer>(layout_->size_in_bytes(), __func__);
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -43,7 +43,7 @@ class VKContext;
|
|||
* It should also keep track of the submissions in order to reuse the allocated
|
||||
* data.
|
||||
*/
|
||||
class VKPushConstants : NonCopyable {
|
||||
class VKPushConstants : VKResourceTracker<VKUniformBuffer> {
|
||||
public:
|
||||
/** Different methods to store push constants. */
|
||||
enum class StorageType {
|
||||
|
@ -151,7 +151,7 @@ class VKPushConstants : NonCopyable {
|
|||
private:
|
||||
const Layout *layout_ = nullptr;
|
||||
void *data_ = nullptr;
|
||||
VKUniformBuffer *uniform_buffer_ = nullptr;
|
||||
bool is_dirty_ = false;
|
||||
|
||||
public:
|
||||
VKPushConstants();
|
||||
|
@ -171,6 +171,11 @@ class VKPushConstants : NonCopyable {
|
|||
return *layout_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of Resource Tracking API is called when new resource is needed.
|
||||
*/
|
||||
std::unique_ptr<VKUniformBuffer> create_resource(VKContext &context) override;
|
||||
|
||||
/**
|
||||
* Get the reference to the active data.
|
||||
*
|
||||
|
@ -209,6 +214,7 @@ class VKPushConstants : NonCopyable {
|
|||
layout_->size_in_bytes(),
|
||||
"Tried to write outside the push constant allocated memory.");
|
||||
memcpy(dst, input_data, comp_len * array_size * sizeof(T));
|
||||
is_dirty_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -222,6 +228,7 @@ class VKPushConstants : NonCopyable {
|
|||
src += comp_len;
|
||||
dst += 4;
|
||||
}
|
||||
is_dirty_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,7 +250,7 @@ class VKPushConstants : NonCopyable {
|
|||
*
|
||||
* Only valid when storage type = StorageType::UNIFORM_BUFFER.
|
||||
*/
|
||||
VKUniformBuffer &uniform_buffer_get();
|
||||
std::unique_ptr<VKUniformBuffer> &uniform_buffer_get();
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "vk_resource_tracker.hh"
|
||||
#include "vk_context.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
bool VKSubmissionTracker::is_changed(VKContext &context)
|
||||
{
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
const VKSubmissionID ¤t_id = command_buffer.submission_id_get();
|
||||
if (last_known_id_ != current_id) {
|
||||
last_known_id_ = current_id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
|
@ -0,0 +1,177 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_utility_mixins.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "vk_common.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKContext;
|
||||
class VKCommandBuffer;
|
||||
|
||||
/**
|
||||
* In vulkan multiple commands can be in flight simultaneously.
|
||||
*
|
||||
* These commands can share the same resources like descriptor sets
|
||||
* or push constants. When between commands these resources are updated
|
||||
* a new version of these resources should be created.
|
||||
*
|
||||
* When a resource is updated it should check the submission id of the
|
||||
* command buffer. If it is different, then the resource can be reused.
|
||||
* If the submission id is the same a new version of the resource to now
|
||||
* intervene with other commands that uses the resource.
|
||||
*
|
||||
* VKSubmissionID is the identifier to keep track if a new submission is
|
||||
* being recorded.
|
||||
*/
|
||||
struct VKSubmissionID {
|
||||
private:
|
||||
int64_t id_ = -1;
|
||||
|
||||
public:
|
||||
VKSubmissionID() = default;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Reset the submission id.
|
||||
*
|
||||
* This should only be called during initialization of the command buffer.
|
||||
* As it leads to undesired behavior after resources are already tracking
|
||||
* the submission id.
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
id_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the submission id.
|
||||
*
|
||||
* Is called when submitting a command buffer to the queue. In this case resource
|
||||
* known that the next time it is used that it can free its sub resources used by
|
||||
* the previous submission.
|
||||
*/
|
||||
void next()
|
||||
{
|
||||
id_++;
|
||||
}
|
||||
|
||||
public:
|
||||
const VKSubmissionID &operator=(const VKSubmissionID &other)
|
||||
{
|
||||
id_ = other.id_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const VKSubmissionID &other)
|
||||
{
|
||||
return id_ == other.id_;
|
||||
}
|
||||
|
||||
bool operator!=(const VKSubmissionID &other)
|
||||
{
|
||||
return id_ != other.id_;
|
||||
}
|
||||
|
||||
friend class VKCommandBuffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Submission tracker keeps track of the last known submission id of the
|
||||
* command buffer.
|
||||
*/
|
||||
class VKSubmissionTracker {
|
||||
VKSubmissionID last_known_id_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Check if the submission_id has changed since the last time it was called
|
||||
* on this VKSubmissionTracker.
|
||||
*/
|
||||
bool is_changed(VKContext &context);
|
||||
};
|
||||
|
||||
/**
|
||||
* VKResourceTracker will keep track of resources.
|
||||
*/
|
||||
template<typename Resource> class VKResourceTracker : NonCopyable {
|
||||
VKSubmissionTracker submission_tracker_;
|
||||
Vector<std::unique_ptr<Resource>> tracked_resources_;
|
||||
|
||||
protected:
|
||||
VKResourceTracker<Resource>() = default;
|
||||
VKResourceTracker<Resource>(VKResourceTracker<Resource> &&other)
|
||||
: submission_tracker_(other.submission_tracker_),
|
||||
tracked_resources_(std::move(other.tracked_resources_))
|
||||
{
|
||||
}
|
||||
|
||||
VKResourceTracker<Resource> &operator=(VKResourceTracker<Resource> &&other)
|
||||
{
|
||||
submission_tracker_ = other.submission_tracker_;
|
||||
tracked_resources_ = std::move(other.tracked_resources_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~VKResourceTracker()
|
||||
{
|
||||
free_tracked_resources();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a resource what can be used by the resource tracker.
|
||||
*
|
||||
* When a different submission was detected all previous resources
|
||||
* will be freed and a new resource will be returned.
|
||||
*
|
||||
* When still in the same submission and we need to update the resource
|
||||
* (is_dirty=true) then a new resource will be returned. Otherwise
|
||||
* the previous used resource will be used.
|
||||
*
|
||||
* When no resources exists, a new resource will be created.
|
||||
*
|
||||
* The resource given back is owned by this resource tracker. And
|
||||
* the resource should not be stored outside this class as it might
|
||||
* be destroyed when the next submission is detected.
|
||||
*/
|
||||
std::unique_ptr<Resource> &tracked_resource_for(VKContext &context, const bool is_dirty)
|
||||
{
|
||||
if (submission_tracker_.is_changed(context)) {
|
||||
free_tracked_resources();
|
||||
tracked_resources_.append(create_resource(context));
|
||||
}
|
||||
else if (is_dirty || tracked_resources_.is_empty()) {
|
||||
tracked_resources_.append(create_resource(context));
|
||||
}
|
||||
return active_resource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to create a new resource. Can be called by the `tracked_resource_for` method.
|
||||
*/
|
||||
virtual std::unique_ptr<Resource> create_resource(VKContext &context) = 0;
|
||||
|
||||
/**
|
||||
* Return the active resource of the tracker.
|
||||
*/
|
||||
std::unique_ptr<Resource> &active_resource()
|
||||
{
|
||||
BLI_assert(!tracked_resources_.is_empty());
|
||||
return tracked_resources_.last();
|
||||
}
|
||||
|
||||
private:
|
||||
void free_tracked_resources()
|
||||
{
|
||||
tracked_resources_.clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
|
@ -542,7 +542,7 @@ Vector<uint32_t> VKShader::compile_glsl_to_spirv(Span<const char *> sources,
|
|||
shaderc_shader_kind stage)
|
||||
{
|
||||
std::string combined_sources = combine_sources(sources);
|
||||
VKBackend &backend = static_cast<VKBackend &>(*VKBackend::get());
|
||||
VKBackend &backend = VKBackend::get();
|
||||
shaderc::Compiler &compiler = backend.get_shaderc_compiler();
|
||||
shaderc::CompileOptions options;
|
||||
options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_data_conversion.hh"
|
||||
#include "vk_memory.hh"
|
||||
#include "vk_shader.hh"
|
||||
#include "vk_shader_interface.hh"
|
||||
|
||||
#include "BLI_math_vector.hh"
|
||||
|
||||
#include "BKE_global.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
@ -34,8 +37,64 @@ void VKTexture::copy_to(Texture * /*tex*/)
|
|||
{
|
||||
}
|
||||
|
||||
void VKTexture::clear(eGPUDataFormat /*format*/, const void * /*data*/)
|
||||
template<typename T> void copy_color(T dst[4], const T *src)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = src[3];
|
||||
}
|
||||
|
||||
static VkClearColorValue to_vk_clear_color_value(eGPUDataFormat format, const void *data)
|
||||
{
|
||||
VkClearColorValue result = {0.0f};
|
||||
switch (format) {
|
||||
case GPU_DATA_FLOAT: {
|
||||
const float *float_data = static_cast<const float *>(data);
|
||||
copy_color<float>(result.float32, float_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case GPU_DATA_INT: {
|
||||
const int32_t *int_data = static_cast<const int32_t *>(data);
|
||||
copy_color<int32_t>(result.int32, int_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case GPU_DATA_UINT: {
|
||||
const uint32_t *uint_data = static_cast<const uint32_t *>(data);
|
||||
copy_color<uint32_t>(result.uint32, uint_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case GPU_DATA_HALF_FLOAT:
|
||||
case GPU_DATA_UBYTE:
|
||||
case GPU_DATA_UINT_24_8:
|
||||
case GPU_DATA_10_11_11_REV:
|
||||
case GPU_DATA_2_10_10_10_REV: {
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void VKTexture::clear(eGPUDataFormat format, const void *data)
|
||||
{
|
||||
if (!is_allocated()) {
|
||||
allocate();
|
||||
}
|
||||
|
||||
VKContext &context = *VKContext::get();
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
VkClearColorValue clear_color = to_vk_clear_color_value(format, data);
|
||||
VkImageSubresourceRange range = {0};
|
||||
range.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
range.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
|
||||
command_buffer.clear(
|
||||
vk_image_, VK_IMAGE_LAYOUT_GENERAL, clear_color, Span<VkImageSubresourceRange>(&range, 1));
|
||||
}
|
||||
|
||||
void VKTexture::swizzle_set(const char /*swizzle_mask*/[4])
|
||||
|
@ -79,22 +138,41 @@ void *VKTexture::read(int mip, eGPUDataFormat format)
|
|||
command_buffer.submit();
|
||||
|
||||
void *data = MEM_mallocN(host_memory_size, __func__);
|
||||
|
||||
/* TODO: add conversion when data format is different. */
|
||||
BLI_assert_msg(device_memory_size == host_memory_size,
|
||||
"Memory data conversions not implemented yet");
|
||||
|
||||
staging_buffer.read(data);
|
||||
|
||||
convert_device_to_host(data, staging_buffer.mapped_memory_get(), sample_len, format, format_);
|
||||
return data;
|
||||
}
|
||||
|
||||
void VKTexture::update_sub(int /*mip*/,
|
||||
int /*offset*/[3],
|
||||
int /*extent*/[3],
|
||||
eGPUDataFormat /*format*/,
|
||||
const void * /*data*/)
|
||||
void VKTexture::update_sub(
|
||||
int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data)
|
||||
{
|
||||
if (!is_allocated()) {
|
||||
allocate();
|
||||
}
|
||||
|
||||
/* Vulkan images cannot be directly mapped to host memory and requires a staging buffer. */
|
||||
VKContext &context = *VKContext::get();
|
||||
VKBuffer staging_buffer;
|
||||
size_t sample_len = extent[0] * extent[1] * extent[2];
|
||||
size_t device_memory_size = sample_len * to_bytesize(format_);
|
||||
|
||||
staging_buffer.create(
|
||||
context, device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
convert_host_to_device(staging_buffer.mapped_memory_get(), data, sample_len, format, format_);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageExtent.width = extent[0];
|
||||
region.imageExtent.height = extent[1];
|
||||
region.imageExtent.depth = extent[2];
|
||||
region.imageOffset.x = offset[0];
|
||||
region.imageOffset.y = offset[1];
|
||||
region.imageOffset.z = offset[2];
|
||||
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
region.imageSubresource.mipLevel = mip;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
command_buffer.copy(*this, staging_buffer, Span<VkBufferImageCopy>(®ion, 1));
|
||||
command_buffer.submit();
|
||||
}
|
||||
|
||||
void VKTexture::update_sub(int /*offset*/[3],
|
||||
|
@ -115,6 +193,8 @@ bool VKTexture::init_internal()
|
|||
/* Initialization can only happen after the usage is known. By the current API this isn't set
|
||||
* at this moment, so we cannot initialize here. The initialization is postponed until the
|
||||
* allocation of the texture on the device. */
|
||||
|
||||
/* TODO: return false when texture format isn't supported. */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -152,12 +232,12 @@ bool VKTexture::allocate()
|
|||
image_info.format = to_vk_format(format_);
|
||||
image_info.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkResult result;
|
||||
if (G.debug &= G_DEBUG_GPU) {
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
VkImageFormatProperties image_format = {};
|
||||
result = vkGetPhysicalDeviceImageFormatProperties(context.physical_device_get(),
|
||||
image_info.format,
|
||||
|
|
|
@ -7,13 +7,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_utility_mixins.hh"
|
||||
|
||||
#include "gpu_uniform_buffer_private.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKUniformBuffer : public UniformBuf {
|
||||
class VKUniformBuffer : public UniformBuf, NonCopyable {
|
||||
VKBuffer buffer_;
|
||||
|
||||
public:
|
||||
|
|
|
@ -676,12 +676,7 @@ ImBuf *imb_loadtarga(const uchar *mem, size_t mem_size, int flags, char colorspa
|
|||
cmap[count] = cp_data;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
for (int cmap_index = cmap_max - 1; cmap_index > 0; cmap_index >>= 1) {
|
||||
size++;
|
||||
}
|
||||
ibuf->planes = size;
|
||||
|
||||
ibuf->planes = tga.mapbits;
|
||||
if (tga.mapbits != 32) { /* Set alpha bits. */
|
||||
cmap[0] &= BIG_LONG(0x00ffffffl);
|
||||
}
|
||||
|
|
|
@ -332,7 +332,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
|
|||
WM_main_add_notifier(NC_LINESTYLE, linestyle);
|
||||
break;
|
||||
}
|
||||
/* ColorRamp for particle display is owned by the object (see #54422) */
|
||||
/* Color Ramp for particle display is owned by the object (see #54422) */
|
||||
case ID_OB:
|
||||
case ID_PA: {
|
||||
ParticleSettings *part = (ParticleSettings *)ptr->owner_id;
|
||||
|
@ -979,7 +979,7 @@ static void rna_def_color_ramp_element_api(BlenderRNA *brna, PropertyRNA *cprop)
|
|||
|
||||
/* TODO: make these functions generic in `texture.c`. */
|
||||
func = RNA_def_function(srna, "new", "rna_ColorRampElement_new");
|
||||
RNA_def_function_ui_description(func, "Add element to ColorRamp");
|
||||
RNA_def_function_ui_description(func, "Add element to Color Ramp");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm = RNA_def_float(
|
||||
func, "position", 0.0f, 0.0f, 1.0f, "Position", "Position to add element", 0.0f, 1.0f);
|
||||
|
@ -989,7 +989,7 @@ static void rna_def_color_ramp_element_api(BlenderRNA *brna, PropertyRNA *cprop)
|
|||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_ColorRampElement_remove");
|
||||
RNA_def_function_ui_description(func, "Delete element from ColorRamp");
|
||||
RNA_def_function_ui_description(func, "Delete element from Color Ramp");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "element", "ColorRampElement", "", "Element to remove");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
|
||||
|
@ -1069,14 +1069,14 @@ static void rna_def_color_ramp(BlenderRNA *brna)
|
|||
# endif
|
||||
|
||||
func = RNA_def_function(srna, "evaluate", "rna_ColorRamp_eval");
|
||||
RNA_def_function_ui_description(func, "Evaluate ColorRamp");
|
||||
RNA_def_function_ui_description(func, "Evaluate Color Ramp");
|
||||
parm = RNA_def_float(func,
|
||||
"position",
|
||||
1.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
"Position",
|
||||
"Evaluate ColorRamp at position",
|
||||
"Evaluate Color Ramp at position",
|
||||
0.0f,
|
||||
1.0f);
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
|
|
|
@ -26,7 +26,7 @@ DefNode(Node, NODE_REROUTE, 0, "REROUT
|
|||
DefNode(ShaderNode, SH_NODE_RGB, 0, "RGB", RGB, "RGB", "A color picker")
|
||||
DefNode(ShaderNode, SH_NODE_VALUE, 0, "VALUE", Value, "Value", "Used to Input numerical values to other nodes in the tree")
|
||||
DefNode(ShaderNode, SH_NODE_MIX_RGB_LEGACY, def_mix_rgb, "MIX_RGB", MixRGB, "MixRGB", "Mix two input colors")
|
||||
DefNode(ShaderNode, SH_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "Map values to colors with the use of a gradient")
|
||||
DefNode(ShaderNode, SH_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "Color Ramp", "Map values to colors with the use of a gradient")
|
||||
DefNode(ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "Convert a color's luminance to a grayscale value")
|
||||
DefNode(ShaderNode, SH_NODE_SHADERTORGB, 0, "SHADERTORGB", ShaderToRGB, "Shader to RGB", "Convert rendering effect (such as light and shadow) to color. Typically used for non-photorealistic rendering, to apply additional effects on the output of BSDFs.\nNote: only supported for Eevee")
|
||||
DefNode(ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "Generate a normal vector and a dot product")
|
||||
|
@ -128,7 +128,7 @@ DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER
|
|||
DefNode(CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "Color Ramp", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", CurveVec, "Vector Curves", "" )
|
||||
|
@ -231,7 +231,7 @@ DefNode(TextureNode, TEX_NODE_BRICKS, def_tex_bricks, "BRICKS
|
|||
DefNode(TextureNode, TEX_NODE_MATH, def_math, "MATH", Math, "Math", "" )
|
||||
DefNode(TextureNode, TEX_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix RGB", "" )
|
||||
DefNode(TextureNode, TEX_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
|
||||
DefNode(TextureNode, TEX_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
|
||||
DefNode(TextureNode, TEX_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "Color Ramp", "" )
|
||||
DefNode(TextureNode, TEX_NODE_IMAGE, def_tex_image, "IMAGE", Image, "Image", "" )
|
||||
DefNode(TextureNode, TEX_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
|
||||
DefNode(TextureNode, TEX_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
|
||||
|
|
|
@ -135,7 +135,7 @@ void register_node_type_cmp_valtorgb()
|
|||
|
||||
static bNodeType ntype;
|
||||
|
||||
cmp_node_type_base(&ntype, CMP_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
|
||||
cmp_node_type_base(&ntype, CMP_NODE_VALTORGB, "Color Ramp", NODE_CLASS_CONVERTER);
|
||||
ntype.declare = file_ns::cmp_node_valtorgb_declare;
|
||||
node_type_size(&ntype, 240, 200, 320);
|
||||
ntype.initfunc = file_ns::node_composit_init_valtorgb;
|
||||
|
|
|
@ -136,7 +136,7 @@ void register_node_type_sh_valtorgb()
|
|||
|
||||
static bNodeType ntype;
|
||||
|
||||
sh_fn_node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
|
||||
sh_fn_node_type_base(&ntype, SH_NODE_VALTORGB, "Color Ramp", NODE_CLASS_CONVERTER);
|
||||
ntype.declare = file_ns::sh_node_valtorgb_declare;
|
||||
ntype.initfunc = file_ns::node_shader_init_valtorgb;
|
||||
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
|
||||
|
|
|
@ -47,7 +47,7 @@ void register_node_type_tex_valtorgb(void)
|
|||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTER);
|
||||
tex_node_type_base(&ntype, TEX_NODE_VALTORGB, "Color Ramp", NODE_CLASS_CONVERTER);
|
||||
node_type_socket_templates(&ntype, valtorgb_in, valtorgb_out);
|
||||
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
|
||||
ntype.initfunc = valtorgb_init;
|
||||
|
|
|
@ -129,6 +129,11 @@ typedef enum eWM_CapabilitiesFlag {
|
|||
WM_CAPABILITY_CURSOR_WARP = (1 << 0),
|
||||
/** Ability to access window positions & move them. */
|
||||
WM_CAPABILITY_WINDOW_POSITION = (1 << 1),
|
||||
/**
|
||||
* The windowing system supports a separate primary clipboard
|
||||
* (typically set when interactively selecting text).
|
||||
*/
|
||||
WM_CAPABILITY_PRIMARY_CLIPBOARD = (1 << 2),
|
||||
} eWM_CapabilitiesFlag;
|
||||
|
||||
eWM_CapabilitiesFlag WM_capabilities_flag(void);
|
||||
|
|
|
@ -1834,6 +1834,10 @@ eWM_CapabilitiesFlag WM_capabilities_flag(void)
|
|||
if (GHOST_SupportsWindowPosition()) {
|
||||
flag |= WM_CAPABILITY_WINDOW_POSITION;
|
||||
}
|
||||
if (GHOST_SupportsPrimaryClipboard()) {
|
||||
flag |= WM_CAPABILITY_PRIMARY_CLIPBOARD;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue