1. Introduction
This document describes the V-EZ Vulkan wrapper library, what it is, what it abstracts away from the Vulkan API, and how to use it. Comparisons to Vulkan are made with the assumption the reader has a moderate understanding of the Khronos specification. In many sections of this documentation, details of functions calls are omitted since the behavior is nearly identical to Vulkan. The latest specification for the Vulkan API can be found here.
1.1. What is V-EZ?
V-EZ is designed to be a C based light-weight layer around Vulkan which maintains mostly identical semantics but abstracts away the lower level complexities. The motivation behind this design is to accelerate adoption of Vulkan among software vendors outside of the gaming industry, who desire modern graphics API features without all of the low level responsibilities.
1.2. What is Abstracted From Vulkan?
The following is a short list of low level Vulkan API features and responsibilities which are abstracted in V-EZ and no longer a concern of the application.
-
Memory management
-
Swapchain management
-
Render Passes
-
Pipeline permutations
-
Pipeline layouts
-
Pipeline barriers
-
Descriptor pools
-
Descriptor sets
-
Descriptor set layouts
-
Image layouts
-
GLSL compilation
Below is a diagram of the Vulkan API objects and their interactions.
The next image is a diagram of V-EZ. Notice the number of native Vulkan objects which are abstracted and whose responsibility is removed from the application.
1.3. Performance Comparisons
V-EZ incurs only slight overhead compared to native Vulkan API calls. However in most cases the performance overhead is negligible. Existing best practices with respect to Vulkan are still applicable with V-EZ. These include, but are not limited to:
-
Batching queue submissions
-
Multi-threaded command buffer recording
-
Reusing command buffers
-
Minimizing pipeline bindings
-
Minimizing resource bindings
-
Batching draw calls
1.4. Native Vulkan Calls
Most object handles created by V-EZ are the native Vulkan objects. These can be used in native Vulkan. There are only a few exceptions, which are prefixed with vez
rather than vk
. These object handles may only be passed to V-EZ.
-
vezSwapchain
-
vezCommandBuffer
-
vezPipeline
-
vezFramebuffer
Any native Vulkan API functions that do not exist within V-EZ may be used with Vulkan object handles returned by V-EZ.
2. Initialization
This section describes how an application initializes V-EZ, enumerates devices attached to the system and creates one or more handles to those devices for use.
2.1. Instances
The first step to using V-EZ is to create a VkInstance
object by calling vezCreateInstance
with appropriate parameter values set in VezInstanceCreateInfo
and VezApplicationInfo
. These structures allow an application to pass information about itself to V-EZ. Below is a simple example call.
1VezApplicationInfo appInfo = {};
2appInfo.pApplicationName = "MyApplication";
3appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
4appInfo.pEngineName = "MyEngine";
5appinfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
6
7VezInstanceCreateInfo createInfo = {};
8createInfo.pApplicationInfo = &appInfo;
9
10VkInstance instance = VK_NULL_HANDLE;
11VkResult result = vezCreateInstance(&createInfo, &instance);
As with Vulkan, instance layers and extensions can be enabled by passing the relevant string names to VezInstanceCreateInfo::ppEnabledLayerNames
and VezInstanceCreateInfo::ppEnabledExtensionNames
. For example, to enable the LunarG standard validation layer, the above code would be modified to be the following below.
1std::array<const char*> enabledLayers = { "VK_LAYER_LUNARG_standard_validation" };
2
3VezInstanceCreateInfo createInfo = {};
4createInfo.pApplicationInfo = &appInfo;
5createInfo.enabledLayerCount = static_cast<uint32_t>(enabledLayers.size());
6createInfo.ppEnabledLayerNames = enabledLayers.data();
The vezEnumerateInstanceExtensionProperties
and vezEnumerateInstanceLayerProperties
may be used to enumerate available instance extensions and layers. The behavior is identical to native Vulkan. For more information about vkCreateInstance and instance layers and extensions, see the Vulkan spec.
A VkInstance
object is destroyed by calling VezDestroyInstance
when an application terminates.
1vezDestroyInstance(instance);
2.2. Surfaces
V-EZ does not abstract or wrap creation of surfaces in Vulkan. Applications must use the platform specific WSI Vulkan extensions to create the surface. See the Vulkan spec for details.
2.3. Physical Devices
To retrieve a list of physical devices in the system, call vezEnumeratePhysicalDevices
, which behaves identically to its counterpart in Vulkan. Physical device properties and features can be retrieved via vezGetPhysicalDeviceProperties
and vezGetPhysicalDeviceFeatures
. The following code snippet demonstrates enumerating all available physical devices in a system and their properties and features.
1uint32_t physicalDeviceCount;
2vezEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
3
4std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
5vezEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
6
7for (auto physicalDevice : physicalDevices)
8{
9 VkPhysicalDeviceProperties properties;
10 vezGetPhysicalDeviceProperties(physicalDevice, &properties);
11
12 VkPhysicalDeviceFeatures features;
13 vezGetPhysicalDeviceFeatures(physicalDevice, &features);
14}
2.3.1. Extensions Support
All available Vulkan extensions for a physical device may be enumerated by calling vezEnumerateDeviceExtensionProperties
. Each VkExtensionProperties
entry in the output array will contain the string name of the supported extension. If an application needs to quickly check for the existence of a specific extension, it can call vezGetPhysicalDeviceExtensionSupport
.
2.3.2. Layers Support
As with physical device specific extensions, layers can be enumerated with vezEnumerateDeviceLayerProperties
.
2.4. Devices
Device objects represent logical connections to physical devices (see the Vulkan spec). An application must create separate device object handles for each physical device it will use. vezCreateDevice
is used to create a logical connection to a physical device.
An application may specify a list of device level extensions to enable (see the Vulkan spec) by populating vezCreateDeviceInfo::ppEnabledExtensionNames
. Device level layers can be enabled by populating vezCreateDeviceInfo::ppEnabledLayerNames
. The code snippet below demonstrates creating a device with the VK_KHR_swapchain
extension enabled.
1std::array<const char*, 1> enabledExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
2
3VezDeviceCreateInfo deviceCreateInfo = {};
4deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(enabledExtensions.size());
5deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
6
7VkDevice device = VK_NULL_HANDLE;
8VkResult result = vezCreateDevice(physicalDevice, &deviceCreateInfo, &device);
2.5. Swapchains and Present Support
To determine if a physical device supports a particular surface format, call vezGetPhysicalDeviceSurfaceFormats
. This will retrieve an array of VkFormat
and VkColorSpace
values which can be used to check for required compatibility, for example HDR10. In some cases a surface attached to a window handle may not support being presented to, or may only support present with a specific queue family index (see Queues). This can be determined by calling vezGetPhysicalDevicePresentSupport
.
After enumerating supported image formats and color spaces for a given physical device, an application can create one or more swapchains in V-EZ by calling vezCreateSwapchain
with appropriate parameters for VezSwapchainCreateInfo
. In contrast to Vulkan, V-EZ manages most of the responsibilities of an application’s swapchain.
1VezSwapchainCreateInfo swapchainCreateInfo = {};
2swapchainCreateInfo.surface = surface;
3swapchainCreateInfo.format = { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
4
5VezSwapchain swapchain = VK_NULL_HANDLE;
6auto result = vezCreateSwapchain(device, &swapchainCreateInfo, &swapchain);
If the format specified in VezSwapchainCreateInfo
was not supported, V-EZ will choose a default one. An application may query the final image format by calling vezGetSwapchainSurfaceFormat
.
2.6. Putting It All Together
Below is a coding listing demonstrating each preceeding section.
1#include <iostream>
2#define GLFW_INCLUDE_NONE
3#define GLFW_EXPOSE_NATIVE_WIN32
4#include <GLFW/glfw3.h>
5#include <GLFW/glfw3native.h>
6#include <VEZ.h>
7
8GLFWwindow* window = nullptr;
9VkInstance instance = VK_NULL_HANDLE;
10VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
11VkSurfaceKHR surface = VK_NULL_HANDLE;
12VkDevice device = VK_NULL_HANDLE;
13VezSwapchain swapchain = VK_NULL_HANDLE;
14
15bool InitWindow()
16{
17 glfwInit();
18 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
19 window = glfwCreateWindow(800, 600, "MyApplication", nullptr, nullptr);
20 if (!window)
21 return false;
22
23 return true;
24}
25
26bool InitVulkanEZ()
27{
28 // Create the V-EZ instance.
29 VezApplicationInfo appInfo = {};
30 appInfo.pApplicationName = "MyApplication";
31 appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
32 appInfo.pEngineName = "MyEngine";
33 appinfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
34
35 VezInstanceCreateInfo instanceCreateInfo = {};
36 instanceCreateInfo.pApplicationInfo = &appInfo;
37
38 VkResult result = vezCreateInstance(&instanceCreateInfo, &instance);
39 if (result != VK_SUCCESS)
40 return false;
41
42 // Create a surface to render to.
43 result = glfwCreateWindowSurface(instance, window, nullptr, &surface);
44 if (result != VK_SUCCESS)
45 return false;
46
47 // Enumerate and select the first discrete GPU physical device.
48 uint32_t physicalDeviceCount;
49 vezEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
50
51 std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
52 vezEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
53
54 for (auto pd : physicalDevices)
55 {
56 VkPhysicalDeviceProperties properties;
57 vezGetPhysicalDeviceProperties(pd, &properties);
58 if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
59 {
60 physicalDevice = pd;
61 break;
62 }
63 }
64
65 if (physicalDevice == VK_NULL_HANDLE)
66 return false;
67
68 // Create a surface.
69 VezSurfaceCreateInfo createInfo = {};
70 createInfo.hinstance = GetModuleHandle(nullptr);
71 createInfo.hwnd = glfwGetWin32Window(window);
72 result = vezCreateSurface(instance, &createInfo, &surface);
73 if (result != VK_SUCCESS)
74 return false;
75
76 // Create a logical device connection to the physical device.
77 VezDeviceCreateInfo deviceCreateInfo = {};
78 deviceCreateInfo.enabledExtensionCount = 0;
79 deviceCreateInfo.ppEnabledExtensionNames = nullptr;
80 result = vezCreateDevice(physicalDevice, &deviceCreateInfo, &device);
81 if (result != VK_SUCCESS)
82 return false;
83
84 // Create the swapchain.
85 VezSwapchainCreateInfo swapchainCreateInfo = {};
86 swapchainCreateInfo.surface = surface;
87 swapchainCreateInfo.format = { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
88 result = vezCreateSwapchain(device, &swapchainCreateInfo, &swapchain);
89 if (result != VK_SUCCESS)
90 return false;
91
92 return true;
93}
94
95int main(int argc, char** argv)
96{
97 if (!InitGLFW())
98 {
99 std::cout << "Failed to create GLFW window!\n";
100 return -1;
101 }
102
103 if (!InitVulkanEZ())
104 {
105 std::cout << "Failed to initialize V-EZ!\n";
106 return -1;
107 }
108
109 vezDestroyDevice(device);
110 vezDestroyInstance(instance);
111 return 0;
112}
3. Queues
3.1. Queue Families
As discussed in the Vulkan spec, each physical device may have one or more queue families. A physical device’s queue families can be queried with vezGetPhysicalDeviceQueueFamilyProperties
. The returned VkQueueFamilyProperties
array contains the following fields:
-
queueFlags
indicating the capabilities of the queues in the queue family -
queueCount
a count of queues in this queue family
In V-EZ there is no need to explicitly create or request the different queue families. By default, all queue families and the maximum counts are created and accessible to the application. An application can obtain VkQueue
handles to each queue family by calling vezGetDeviceQueue
with the desired queueFamilyIndex
and queueIndex
, which must be less than queueCount
obtained in VkQueueFamilyProperties
. Utility functions are also provided to explicitly request the graphics, compute or transfer queue families.
1void vezGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue);
1void vezGetDeviceGraphicsQueue(VkDevice device, uint32_t queueIndex, VkQueue* pQueue);
2void vezGetDeviceComputeQueue(VkDevice device, uint32_t queueIndex, VkQueue* pQueue);
3void vezGetDeviceTransferQueue(VkDevice device, uint32_t queueIndex, VkQueue* pQueue);
VkQueue
handles do not need to be explicitly destroyed by the application.
3.2. Queue Submission
Queue submission behavior and syntax in V-EZ is nearly identical to Vulkan. An application fills in a VezSubmitInfo
structure as described in the Vulkan spec. Please see 4.3.5 Queue Submission for detailed information on this topic.
The primary differences are with respect to semaphores and fences. In V-EZ, semaphores and fences are never explicitly created by an application. Instead an application requests them to be created when calling VezQueueSubmit
by passing valid, uninitialized, object handles to VezSubmitInfo::pSignalSemaphores
and the final pFence
parameter of VezQueueSubmit
. V-EZ will allocate the objects and store them in these handles. An application is responsible for calling vezDestroyFence
for any VkFence
object handle returned by V-EZ. As in Vulkan, an application must ensure any queue submission has completed and the VkFence
object has been signaled before deletion.
For semaphores returned by V-EZ, an application may only pass them to proceeding calls to VezQueueSubmit
as wait semaphores. V-EZ will ensure the object handles are properly destroyed after the queue submission completes. External semaphores created by native Vulkan may be passed to V-EZ via VezSubmitInfo::pWaitSemaphores
.
1VkSemaphore semaphore = VK_NULL_HANDLE;
2VkFence fence = VK_NULL_HANDLE;
3
4VezSubmitInfo submitInfo = {};
5submitInfo.commandBufferCount = 1;
6submitInfo.pCommandBuffers = &commandBuffer;
7submitInfo.signalSemaphoreCount = 1;
8submitInfo.pSignalSemaphores = &semaphore;
9VkResult result = vezQueueSubmit(queue, 1, &submitInfo, &fence);
10
11// Pass semaphore to another vkQueueSubmit call as a wait semaphore.
12
13// Wait on fence to complete.
14vezWaitForFences(device, 1, &fence, VK_TRUE, ~0ULL);
15vezDestroyFence(device, fence);
More on semaphores and fences will be discussed in Synchronization.
3.3. Queue Presentation
V-EZ alleviates most of the responsibility for managing the Vulkan swapchain from the application. The only operation an application must perform to display a rendered image to a window is call vezQueuePresent
with the VezPresentInfo
parameter correctly set. The semantics of VezPresentInfo
differ quite a bit from Vulkan’s VkPresentInfoKHR
. Namely, in V-EZ an application presents a VkImage
object handle rather than specifying the image index of the Vulkan swapchain. Furthermore, V-EZ allows an application to specify signal semaphores in VezPresentInfo
which can be used to determine when the VkImage
object handle is no longer in use.
More than one swapchain may be presented in a single call. The pImages
array must contains the same number of entries as pSwapchains
.
1typedef struct VezPresentInfo {
2 const void* pNext;
3 uint32_t waitSemaphoreCount;
4 const VkSemaphore* pWaitSemaphores;
5 uint32_t swapchainCount;
6 const VezSwapchain* pSwapchains;
7 const VkImage* pImages;
8 uint32_t signalSemaphoreCount;
9 VkSemaphore* pSignalSemaphores;
10 VkResult* pResults;
11} VkPresentInfo;
The code listing below demonstrates presenting an image the application has rendered into, specifying a single wait semaphore from a previous queue submission and retrieving a signal semaphore.
1VkSemaphore signalSemaphore = VK_NULL_HANDLE;
2
3VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
4VezPresentInfo presentInfo = {};
5presentInfo.waitSemaphoreCount = 1;
6presentInfo.pWaitSemaphores = &semaphore;
7presentInfo.pWaitDstStageMask = &waitDstStageMask;
8presentInfo.swapchainCount = 1;
9presentInfo.pSwapchains = &swapchain;
10presentInfo.pImages = &srcImage;
11presentInfo.signalSemaphoreCount = 1;
12presentInfo.pSignalSemaphores = &signalSemaphore;
13VkResult result = vezQueuePresent(graphicsQueue, &presentInfo);
14
15// Wait on the signal semaphore before using renderedImage again.
16// Ex: pass the semaphore to VezSubmitInfo::pWaitSemaphores.
|
Note
|
Any images passed to VezPresentInfo::pImages must be created with the VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag bit. See Resource Creation for details on image creation and usage flags.
|
3.3.1. Multisampled Images
If any entry in VezPresentInfo::pImages
is multisampled, no additional steps need to be taken before calling vezQueuePresent. V-EZ will automatically resolve the image as its presented to the target window.
4. Synchronization
In contrast to Vulkan, the application’s responsibilities for resource access synchronization is partially alleviated by V-EZ. Namely, Pipeline Barriers and Memory Barriers are no longer explicitly required by the application, but handled by V-EZ. Additionally, fences and semaphores are not explicitly created by the application but requested when calling VkQueueSubmit
or vkQueuePresent
as previously described in Queue Submission.
4.1. Fences
As described in the Vulkan spec, fences are a synchronization primitive that can be used between a queue and the host. In Vulkan, a fence is either signaled, after the execution of a queue submission, or unsignaled after being reset. In V-EZ, fences are never reset. Once a fence is requested, its status may be queried via vezGetFenceStatus
or waited on with vezWaitForFences
. An application must call vezDestroyFence
when the object is no longer used.
1// Submit a command buffer to a queue and request a fence object for the submission.
2VkFence fence = VK_NULL_HANDLE;
3
4VezSubmitInfo submitInfo = {};
5submitInfo.commandBufferCount = 1;
6submitInfo.pCommandBuffers = &commandBuffer;
7vezQueueSubmit(queue, 1, &submitInfo, &fence);
8
9// Wait until the queue submission has finished executing.
10vezWaitForFences(device, 1, &fence, VK_TRUE, ~0);
11
12// Destroy the fence.
13vezDestroyFence(device, fence);
4.2. Semaphores
Semaphores are a synchronization primitive used to insert dependencies between queue submissions within the same queue or between different queues. Like fences, semaphores can be signaled or unsignaled. For a more detailed explanation of semaphores, see the Vulkan spec.
An application may obtain semaphore objects when calling vkQueueSubmit
or vkQueuePresent
. In both cases, the semaphores are set to be signaled when either operation completes and may be passed as wait semaphores to a proceeding queue submission or present operation. In V-EZ, semaphores are never explicitly destroyed by the application, rather once they are passed as wait semaphores to a proceeding queue operation, the application no longer maintains ownership. See the previous code listing in Queue Presentation.
The only exception to this behavior is if a semaphore created by VEZ is then passed as a wait semaphore to a native Vulkan queue submission. In this case, the application must call vezDestroySemaphore once the native Vulkan queue submission completes and the semaphore has been waited on.
4.3. Events
Events in V-EZ have identical behavior and operation as in Vulkan. See the Vulkan spec for more information.
4.4. Wait Idle Operations
Wait idle operations in V-EZ have identical behavior and operation as in Vulkan. See the Vulkan spec for more information.
5. Pipelines
Pipeline creation and management in V-EZ has been significantly simplified compared to Vulkan. When creating a pipeline in Vulkan, the following graphics state and object handles must be passed to vkCreateGraphicsPipeline
.
-
Vertex input state
-
Input assembly state
-
Viewport state
-
Rasterization state
-
Multisample state
-
Depth stencil state
-
Color blend state
-
Pipeline layout
-
Render passed
-
Subpass index
V-EZ alleviates the need to specify any of this information at creation time, thus allowing an application the flexibility to use the same VezPipeline
object with different graphics state permutations, vertex attribute bindings and render passes.
5.1. Shader Modules
Shader modules represent the different shader stages of a pipeline. In Vulkan shader modules can only be created from SPIR-V binaries. However V-EZ allows shader module creation from both SPIR-V and GLSL source. To create a shader module, vezCreateShaderModule
is called with VezShaderModuleCreateInfo
specifying the stage and GLSL source or SPIR_V binary. The behavior and syntax remain largely the same as Vulkan, with the exception of added GLSL support. The code listing below shows a shader module being created from GLSL source.
1std::string glslSource = ReadFile("shader.vert");
2
3VezShaderModuleCreateInfo createInfo = {};
4createInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
5createInfo.codeSize = static_cast<uint32_t>(glslSource.size());
6createInfo.pGLSLSource = glslSource.c_str();
7createInfo.pEntryPoint = "main";
8
9VkShaderModule shaderModule = VK_NULL_HANDLE;
10VkResult result = vezCreateShaderModule(device, &createInfo, &shaderModule);
The VezShaderModuleCreateInfo::pEntryPoint
field is only required when creating a shader module from GLSL source. For more information on shader modules, please see the Vulkan spec.
5.2. Graphics Pipelines
To create a graphics pipeline, call vezCreateGraphicsPipeline
with an array of VezPipelineShaderStageCreateInfo
entries, one for each shader stage the pipeline will use. The code listing below assumes vertex and fragment shader modules have already been created.
1std::array<VezPipelineShaderStageCreateInfo, 2> stages = { { {}, {} } };
2stages[0] = {};
3stages[0].module = vertexStageShaderModule;
4stages[0].pEntryPoint = nullptr;
5stages[1] = {};
6stages[1].module = fragmentStageShaderModule;
7stages[1].pEntryPoint = nullptr;
8
9VezGraphicsPipelineCreateInfo createInfo = {};
10createInfo.stageCount = static_cast<uint32_t>(stages.size());
11createInfo.pStages = stages.data();
12
13VezPipeline pipeline = VK_NULL_HANDLE;
14VkResult result = vezCreateGraphicsPipeline(device, &createInfo, &pipeline);
The VezPipelineShaderStageCreateInfo::pEntryPoint
allows an application to re-specify alternate entry points for a shader module. This is useful in the case where a single shader module contains multiple entry points for a given shader stage and used between more than one pipeline.
5.3. Compute Pipelines
Compute pipelines are created with a single VezPipelineShaderStageCreateInfo
object and a call to vezCreateComputePipeline
.
5.4. Specialization Constants
Specialization constants in V-EZ work the same as they do in Vulkan. An application sets VezPipelineShaderStageCreateInfo::pSpecializationInfo
accordingly. For more information on specialization constants, please see the Vulkan spec.
5.5. Push Constants
Push constants are a "high speed path to modify constant data in pipelines that is expected to out perform memory-backed resource updates". For more information on push constants, please see the Vulkan spec.
V-EZ simplifies the use of push constants by only requiring an application call vezCmdPushConstants
to update the memory, requiring only an offset, size and pointer to host data to update the push constants memory with. A valid pipeline must be bound before calling vezCmdPushConstants
.
1void vezCmdPushConstants(VezCommandBuffer commandBuffer, uint32_t offset, uint32_t size, const void* pValues);
In the case where multiple shader stages within a pipeline define push constants at different byte offsets, an application may query these offsets and sizes with V-EZ’s pipeline reflection described in the next section.
5.6. Pipeline Reflection
Unlike Vulkan, V-EZ allows full pipeline shader stage reflection if the shader stages were created from GLSL source, or the SPIR-V binary source contains the relevant meta-data. To enumerate all pipeline resources call vezEnumeratePipelineResources
, which returns an array of VkPipelineResource
entries.
1typedef struct VezMemberInfo
2{
3 VezBaseType baseType;
4 uint32_t offset;
5 uint32_t size;
6 uint32_t vecSize;
7 uint32_t arraySize;
8 char name[VK_MAX_DESCRIPTION_SIZE];
9 const VezMemberInfo* pNext;
10 const VezMemberInfo* pMembers;
11} VezMemberInfo;
12
13typedef struct VezPipelineResource {
14 VkShaderStageFlags stages;
15 VezPipelineResourceType resourceType;
16 VezBaseType baseType;
17 VkAccessFlags access;
18 uint32_t set;
19 uint32_t binding;
20 uint32_t location;
21 uint32_t inputAttachmentIndex;
22 uint32_t vecSize;
23 uint32_t arraySize;
24 uint32_t offset;
25 uint32_t size;
26 char name[VK_MAX_DESCRIPTION_SIZE];
27 const VezMemberInfo* pMembers;
28} VezPipelineResource;
The stages field is a bitmask of all shader stages the resource is used in. For example, a the same uniform buffer binding might be bound and accessed in both the vertex and fragment shader stages.
The resourceType field specifies one of the following values:
1typedef enum VezPipelineResourceType {
2 VEZ_PIPELINE_RESOURCE_TYPE_INPUT = 0,
3 VEZ_PIPELINE_RESOURCE_TYPE_OUTPUT = 1,
4 VEZ_PIPELINE_RESOURCE_TYPE_SAMPLER = 2,
5 VEZ_PIPELINE_RESOURCE_TYPE_COMBINED_IMAGE_SAMPLER = 3,
6 VEZ_PIPELINE_RESOURCE_TYPE_SAMPLED_IMAGE = 4,
7 VEZ_PIPELINE_RESOURCE_TYPE_STORAGE_IMAGE = 5,
8 VEZ_PIPELINE_RESOURCE_TYPE_UNIFORM_TEXEL_BUFFER = 6,
9 VEZ_PIPELINE_RESOURCE_TYPE_STORAGE_TEXEL_BUFFER = 7,
10 VEZ_PIPELINE_RESOURCE_TYPE_UNIFORM_BUFFER = 8,
11 VEZ_PIPELINE_RESOURCE_TYPE_STORAGE_BUFFER = 9,
12 VEZ_PIPELINE_RESOURCE_TYPE_ATOMIC_COUNTER = 10,
13 VEZ_PIPELINE_RESOURCE_TYPE_PUSH_CONSTANT_BUFFER = 11,
14} VezPipelineResourceType;
The baseType field specifies the data type. For GLSL vec4, baseType would be VEZ_PIPELINE_RESOURCE_BASE_TYPE_FLOAT for example.
1typedef enum VezBaseType {
2 VEZ_BASE_TYPE_BOOL = 0,
3 VEZ_BASE_TYPE_CHAR = 1,
4 VEZ_BASE_TYPE_INT = 2,
5 VEZ_BASE_TYPE_UINT = 3,
6 VEZ_BASE_TYPE_UINT64 = 4,
7 VEZ_BASE_TYPE_HALF = 5,
8 VEZ_BASE_TYPE_FLOAT = 6,
9 VEZ_BASE_TYPE_DOUBLE = 7,
10 VEZ_BASE_TYPE_STRUCT = 8,
11} VezBaseType;
The access field specifies whether the resource has read and/or write access.
The set and binding fields specify the set number and binding point in the shader as declared in the GLSL source or SPIR-V binary. For additional information on this, please see the GLSL Guide at the end of this document.
For shader stage inputs and outputs, the location field specifies the location binding. Examples include fragment stage output, inputs and outputs between shader stages, etc.
For renderpass subpasses, the inputAttachmentIndex specifies the index the attachment is bound to.
The vecSize field specifies the number of components. If the shader resource is vec3, vecSize will equal 3. For scalar pipeline resources, vecSize will be 1.
The 'arraySize' field specifies the number of elements in the pipeline resource’s array declaration. For example, in the code listing below, the arraySize would be 10.
1layout (set=0, binding=0) uniform sampler2D textures[10];
The 'offset' and 'size' specify the byte offset and byte size of a resource when declared inside of a struct.
If an application knows the name of the pipeline resource to query, vkGetPipelineResource
may be used.
For uniform and shader storage buffer objects, the pMembers field forms a multi-level linked list of members of these structured bindings. See the PipelineReflection sample for how to iterate over these.
5.7. Pipeline Binding
Graphics pipelines must be bound between vezCmdBeginRenderPass
and vezCmdEndRenderPass
calls. Compute pipelines must be bound outside of a render pass. To bind a pipeline, call vezCmdBindPipeline
.
6. Vertex Input Formats
In Vulkan the expected vertex input state must be specified at graphics pipeline creation time. The downside to this is that an application must manage different permutations of the same pipeline if it’s used with more than one vertex input format. The vertex input format consists of an array of vertex binding descriptions, via VkVertexInputBindingDescription
, and vertex attribute descriptions, via VkVertexInputAttributeDescription
.
V-EZ alleviates this requirement, as graphics pipeline creation only requires an array of shader modules (Graphics Pipelines). Instead, the desired vertex input format is set during command buffer recording by calling vezCmdSetVertexInputFormat
.
1void vezCmdSetVertexInputFormat(VkCommandBuffer commandBuffer, VezVertexInputFormat format);
6.1. Creation
An application now only needs to manage vertex input formats at the mesh or object level. V-EZ moves the specification of the VkVertexInputBindingDescription
and VkVertexInputAttributeDescription
arrays to the VkVertexInputFormat
object creation. In the code listing below, a vertex input format is created specifying a single binding point and two vertex attributes.
1// All vertex attributes bound using a single buffer binding point.
2VkVertexInputBindingDescription bindingDescription = {};
3bindingDescription.binding = 0;
4bindingDescription.stride = sizeof(float) * 5;
5bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
6
7// XYZ position and XY texture coordinate attributes declared.
8std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions;
9attributeDescriptions[0].location = 0;
10attributeDescriptions[0].binding = 0;
11attributeDescriptions[0].offset = 0;
12attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
13attributeDescriptions[1].location = 1;
14attributeDescriptions[1].binding = 0;
15attributeDescriptions[1].offset = sizeof(float) * 3;
16attributeDescriptions[1].format = VK_FORMAT_R32G32_SFLOAT;
17
18VezVertexInputFormatCreateInfo createInfo = {};
19createInfo.vertexBindingDescriptionCount = 1;
20createInfo.pVertexBindingDescriptions = &bindingDescription;
21createInfo.vertexAttributeDescriptionCount = static_cast<uin32_t>(attributeDescriptions.size());
22createInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
23
24VezVertexInputFormat vertexInputFormat = VK_NULL_HANDLE;
25VkResult result = vezCreateVertexInputFormat(device, &createInfo, &vertexInputFormat);
The rules and semantics of specifying VkVertexInputBindingDescription
and VkVertexInputAttributeDescription
follow the same rules as specified in the Vulkan spec.
6.2. Destruction
When an application no longer requires a VezVertexInputFormat
it should be destroyed by calling vezDestroyVertexInputFormat
.
7. Resource Creation
Like Vulkan, V-EZ supports two low-level resource types: buffers and images. However V-EZ does not require an application to manage the underlying memory, which is completely abstracted away. All the application sees are VkBuffer
and VkImage
objects. For more information on resource creation and memory, see the Vulkan spec.
Since memory management is hidden from the application, V-EZ exposes VezMemoryFlags
when creating buffers and images. These flags allow an application to specify how the memory will be used and where the it should reside.
1typedef enum VezMemoryFlagsBits {
2 VEZ_MEMORY_GPU_ONLY = 0x00000000,
3 VEZ_MEMORY_CPU_ONLY = 0x00000001,
4 VEZ_MEMORY_CPU_TO_GPU = 0x00000002,
5 VEZ_MEMORY_GPU_TO_CPU = 0x00000004,
6 VEZ_MEMORY_DEDICATED_ALLOCATION = 0x00000008,
7} VezMemoryFlagsBits;
VEZ_MEMORY_GPU_ONLY specifies a buffer or image memory backing should reside in a device’s local memory only.
VEZ_MEMORY_CPU_ONLY specifies a buffer or image memory backing should reside in host memory.
VEZ_MEMORY_CPU_TO_GPU specifies a buffer or image memory backing should be optimized for data transfers from the host to the device.
VEZ_MEMORY_GPU_TO_CPU specifies a buffer or image memory backing should be optimized for data transfers from the device to the host.
VEZ_MEMORY_DEDICATED_ALLOCATION specifies that the buffer or image should use a unique memory block.
V-EZ’s internal memory management sub-allocates memory blocks by default. If an application prefers that a particular buffer or image have its own dedicated memory block, VEZ_MEMORY_DEDICATED_ALLOCATION can be used.
7.1. Buffers
Buffers are represented by VkBuffer
handles and created by calling vkCreateBuffer
. The code listing below demonstrates creating a buffer to be used for staging, or data transfers optimized for host to device.
1VezBufferCreateInfo createInfo = {};
2createInfo.size = (32 << 20ULL) // 32 megabytes
3createInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
4
5VkBuffer buffer = VK_NULL_HANDLE;
6VkResult result = vezCreateBuffer(device, VEZMEMORY_CPU_TO_GPU, &createInfo, &buffer);
The application must always specify the intended usage for a buffer using the VezBufferUsageFlagBits
enumeration values. In the code listing above, the buffer is only used as a source for data transfers.
Like Vulkan, V-EZ allows an application to specify an array of queue family indices the buffer will be used with. If an application sets queueFamilyIndexCount
to 0, V-EZ defaults the buffer to being accessible to all queue families.
When a VkBuffer
handle is no longer used by an application, it should be destroyed with vezDestroyBuffer
.
7.2. Buffer Views
Creating buffer views from buffers has nearly identical syntax to Vulkan. An application calls vezCreateBufferView
with appropriate values for fields in VezBufferViewCreateInfo
. Buffer views are destroyed by calling vezDestroyBufferView
. For more information on buffer views, see the Vulkan spec.
7.3. Images
Images are represented by VkImage
handles and created by calling vezCreateImage
. Like buffers, VezMemoryFlags
is passed to vezCreateImage
allowing an application to specify how the memory will be used and where the it should reside. The syntax and behavior of vezCreateImage
and VezImageCreateInfo
in V-EZ are nearly identical to Vulkan, see the Vulkan spec for more information.
As with buffers, if the queueFamilyIndexCount in VezImageCreateInfo
is set to 0, then V-EZ assumes the image will be used with all available queue families.
7.4. Image Views
See the Vulkan spec for more information on image views. The behavior and syntax in V-EZ is nearly identical to Vulkan.
7.5. Framebuffers
In Vulkan, an application must specify an array of VkImageView
attachments, a compatible Render Pass, and the dimensions when creating a framebuffer. V-EZ simplifies this to only requiring the array of attachments and the dimensions. Render passes are never explicitly created by applications V-EZ (see Render Passes), and therefore are not required when creating a framebuffer.
The coding listing below demonstrates creating a simple framebuffer from a color and depth image. Note that the usage parameter for the color image has the VK_IMAGE_USAGE_TRANSFER_SRC_BIT set. This is required for any image presented to a window when calling vezQueuePresent
.
1// Create the color image.
2VezImageCreateInfo imageCreateInfo = {};
3imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
4imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
5imageCreateInfo.extent = { width, height, 1 };
6imageCreateInfo.mipLevels = 1;
7imageCreateInfo.arrayLayers = 1;
8imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
9imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
10imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
11
12VkImage colorImage = VK_NULL_HANDLE;
13vezCreateImage(device, VEZ_MEMORY_GPU_ONLY, &imageCreateInfo, &colorImage);
14
15// Create the image view.
16VezImageViewCreateInfo imageViewCreateInfo = {};
17imageViewCreateInfo.image = colorImage;
18imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
19imageViewCreateInfo.format = imageCreateInfo.format;
20imageViewCreateInfo.subresourceRange.layerCount = 1;
21imageViewCreateInfo.subresourceRange.levelCount = 1;
22
23VkImageView colorImageView = VK_NULL_HANDLE;
24vezCreateImageView(device, &imageViewCreateInfo, &colorImageView);
25
26// Create the depth image attachment.
27imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
28imageCreateInfo.format = VK_FORMAT_D32_SFLOAT;
29imageCreateInfo.extent = { width, height, 1 };
30imageCreateInfo.mipLevels = 1;
31imageCreateInfo.arrayLayers = 1;
32imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
33imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
34imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
35
36VkImage depthImage = VK_NULL_HANDLE;
37vezCreateImage(device, VEZ_MEMORY_GPU_ONLY, &imageCreateInfo, &depthImage);
38
39// Create the image view.
40imageViewCreateInfo.image = depthImage;
41imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
42imageViewCreateInfo.format = imageCreateInfo.format;
43imageViewCreateInfo.subresourceRange.layerCount = 1;
44imageViewCreateInfo.subresourceRange.levelCount = 1;
45
46VkImageView depthImageView = VK_NULL_HANDLE;
47vezCreateImageView(device, &imageViewCreateInfo, &depthImageView);
48
49// Create the framebuffer.
50std::array<VkImageView, 2> attachments = { colorImageView, depthImageView };
51VezFramebufferCreateInfo framebufferCreateInfo = {};
52framebufferCreateInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
53framebufferCreateInfo.pAttachments = attachments.data();
54framebufferCreateInfo.width = width;
55framebufferCreateInfo.height = height;
56framebufferCreateInfo.depth = 1;
57VezFramebuffer framebuffer = VK_NULL_HANDLE;
58vezCreateFramebuffer(device, &framebufferCreateInfo, &framebuffer);
Framebuffers are destroyed by calling vezDestroyFramebuffer
.
7.5.1. Multisampled Framebuffers
An application may create a multisampled framebuffer by setting VezImageCreateInfo::samples
to the appropriate value when creating the color and depth stencil attachments. Then the multisample state block must be set appropriately to enable multisampled rendering (see Graphics State).
7.5.2. Framebuffers With No Attachments
As described in the Vulkan specification, framebuffers with no attachments but valid dimensions may still be created. To create a framebuffer with no attachments in V-EZ, simply set VezFramebufferCreateInfo::pAttachments
to null and VezFramebufferCreateInfo::attachmentCount
to 0. Then set appropriate values for width, height, depth and samples.
8. Samplers
Sampler creation and usage in V-EZ is identical to Vulkan. For more information, see the Vulkan spec.
9. Command Buffers
The primary differences between Vulkan and V-EZ with respect to command buffers are the removal of command pools and secondary command buffers in V-EZ. An application need no longer manage individual command pools across threads. Only VkCommandBuffer
handles are created by an applications in V-EZ.
A secondary difference is with respect to pipeline barriers. As previously stated in Synchronization, V-EZ does not expose pipeline barriers. Within a command buffer, and between command buffer submissions, pipeline barriers are inserted automatically. An application is no longer responsible for managing this level of synchronization.
Other aspects of command buffers, such as state persistence within a command buffer, is identical to Vulkan. Existing Vulkan command buffer commands are also present, along with additional ones (see Resource Binding).
9.1. Allocation and Management
To create a command buffer an application calls vezAllocateCommandBuffers
. The intended queue the command buffer will be used on must be specified.
1VkQueue graphicsQueue = VK_NULL_HANDLE;
2vezGetDeviceGraphicsQueue(device, 0, &graphicsQueue);
3
4VezCommandBufferAllocateInfo allocInfo = {};
5allocInfo.queue = graphicsQueue;
6allocInfo.commandBufferCount = 1;
7VezCommandBuffer commandBuffer = VK_NULL_HANDLE;
8VkResult result = vezAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
A command buffer must be destroyed by calling vezFreeCommandBuffers
.
9.2. Recording
An application may begin recording commands to a VkCommandBuffer
handle by calling vezBeginCommandBuffer
. The only required parameter is VkCommandBufferUsageFlags
which gives hints to the driver about how it will be used. See the Vulkan spec for more details. Unlike native Vulkan, V-EZ’s equivalent command buffer functions do not require the VkCommandBuffer handle be passed in. Rather, all vezCmd* functions are associated with the VkCommandBuffer passed to vezBeginCommandBuffer within the same application thread. Commands recorded across threads must indepdently call vezBeginCommandBuffer. An application ends recording by calling vezEndCommandBuffer
.
Like Vulkan, an application must wait for a previously submitted VkCommandBuffer
object handle to not be in use before re-recording. Applications should track queue submissions with fences and query the fence status, or wait, before re-recording commands. See fences under Synchronization.
9.3. Graphics State
As described in Pipelines, V-EZ removes all graphics state specification from pipeline creation. In V-EZ, graphics state is set dynamically while recording a command buffer. Furthermore, all available dynamic states from Vulkan are enabled by default and their corresponding command buffer functions made available in V-EZ. States are not required to be set within a render pass. The following is a list of states available to be set.
1typedef struct VezInputAssemblyState {
2 VkPrimitiveTopology topology;
3 VkBool32 primitiveRestartEnable;
4} VezInputAssemblyState;
5
6typedef struct VezRasterizationState {
7 VkBool32 depthClampEnable;
8 VkBool32 rasterizerDiscardEnable;
9 VkPolygonMode polygonMode;
10 VkCullModeFlags cullMode;
11 VkFrontFace frontFace;
12 VkBool32 depthBiasEnable;
13 float depthBiasConstantFactor;
14 float depthBiasClamp;
15 float depthBiasSlopeFactor;
16} VezRasterizationState;
17
18typedef struct VezMultisampleState {
19 VkSampleCountFlagBits rasterizationSamples;
20 VkBool32 sampleShadingEnable;
21 float minSampleShading;
22 const VkSampleMask* pSampleMask;
23 VkBool32 alphaToCoverageEnable;
24 VkBool32 alphaToOneEnable;
25} VezMultisampleStateCreateInfo;
26
27typedef struct VezStencilOpState {
28 VkStencilOp failOp;
29 VkStencilOp passOp;
30 VkStencilOp depthFailOp;
31 VkCompareOp compareOp;
32} VezStencilOpState;
33
34typedef struct VezDepthStencilState {
35 VkBool32 depthTestEnable;
36 VkBool32 depthWriteEnable;
37 VkCompareOp depthCompareOp;
38 VkBool32 depthBoundsTestEnable;
39 VkBool32 stencilTestEnable;
40 VkStencilOpState front;
41 VkStencilOpState back;
42} VezDepthStencilState;
43
44typedef struct VezColorBlendAttachmentState {
45 VkBool32 blendEnable;
46 VkBlendFactor srcColorBlendFactor;
47 VkBlendFactor dstColorBlendFactor;
48 VkBlendOp colorBlendOp;
49 VkBlendFactor srcAlphaBlendFactor;
50 VkBlendFactor dstAlphaBlendFactor;
51 VkBlendOp alphaBlendOp;
52 VkColorComponentFlags colorWriteMask;
53} VezColorBlendAttachmentState;
54
55typedef struct VezColorBlendState {
56 VkBool32 logicOpEnable;
57 VkLogicOp logicOp;
58 uint32_t attachmentCount;
59 const VkPipelineColorBlendAttachmentState* pAttachments;
60} VezColorBlendState;
An application is not required to set these, as V-EZ sets default values when an application calls vezBeginCommandBuffer
. The following tables list the default values for each state.
| Field name | Default value |
|---|---|
topology |
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST |
primitiveRestartEnable |
VK_FALSE |
| Field name | Default value |
|---|---|
depthClampEnable |
VK_FALSE |
rasterizerDiscardEnable |
VK_FALSE |
polygonMode |
VK_POLYGON_MODE_FILL |
cullMode |
VK_CULL_MODE_NONE |
frontFace |
VK_FRONT_FACE_COUNTER_CLOCKWISE |
depthBiasEnable |
VK_FALSE |
depthBiasConstantFactor |
0.0 |
depthBiasClamp |
1.0 |
depthBiasSlopeFactor |
1.0 |
| Field name | Default value |
|---|---|
rasterizationSamples |
VK_SAMPLE_COUNT_1_BIT |
sampleShadingEnable |
VK_FALSE |
minSampleShading |
1.0 |
pSampleMask |
NULL |
alphaToCoverageEnable |
VK_FALSE |
alphaToOneEnable |
VK_FALSE |
| Field name | Default value |
|---|---|
depthTestEnable |
VK_FALSE |
depthWriteEnable |
VK_TRUE |
depthCompareOp |
VK_COMPARE_OP_LESS_OR_EQUAL |
depthBoundsTestEnable |
VK_FALSE |
stencilTestEnable |
VK_FALSE |
front |
N/A |
back |
N/A |
| Field name | Default value |
|---|---|
logicOpEnable |
VK_FALSE |
logicOp |
VK_LOGIC_OP_SET |
attachmentCount |
0 |
pAttachments |
NULL |
All state blocks are set together, therefore default values must still be set when the application only needs to set a single field. For example, when enabling backface culling, the polygonMode should still be set. The code listing below demonstrates setting setting the viewport, expected primitive topology and enabling backface culling and depth testing.
1vezBeginCommandBuffer(commandBuffer, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
2
3VkViewport viewport = { 0.0f, 0.0f, width, height, 0.0f, 1.0f };
4vezCmdSetViewport(0, 1, &viewport);
5vezCmdSetViewportState(1);
6
7VezInputAssemblyState inputAssemblyState = {};
8inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
9inputAssemblyState.primitiveRestartEnable = VK_FALSE;
10vezCmdSetInputAssemblyState(&inputAssemblyState);
11
12VezRasterizationState rasterizationState = {};
13rasterizationState.polygonMode = VK_POLGYON_MODE_FILL;
14rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;
15rasterizationState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
16vezCmdSetRasterizationState(&rasterizationState);
17
18VezDepthStencilState depthStencilState = {};
19depthStencilState.depthTestEnable = VK_TRUE;
20depthStencilState.depthWriteEnable = VK_FALSE;
21depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
22vezCmdSetDepthStencilState(&depthStencilState);
23
24// Draw commands
25
26vezEndCommandBuffer();
9.4. Resource Binding
In Vulkan descriptor sets are required for binding resources to different bindings for use in a pipeline. The complexities of descriptor set layouts, descriptor pools and updating descriptor set objects has been abstracted away in V-EZ. Instead a simplified interface of explicitly binding buffers, bufferViews, and images to set and binding indices during command buffer recording is exposed. These bindings are persistent only with a command buffer, but maintain persistence across pipeline bindings.
Each binding function for different resource types requires the set number, binding, and array element index. The following functions are available for binding each resource type.
void vezCmdBindBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32_t set, uint32_t binding, uint32_t arrayElement)
void vezCmdBindBufferView(VkBufferView bufferView, uint32_t set, uint32_t binding, uint32_t arrayElement)
void vezCmdBindImageView(VkImageView imageView, VkSampler sampler, uint32_t set, uint32_t binding, uint32_t arrayElement);
void vezCmdBindSampler(VkSampler sampler, uint32_t set, uint32_t binding, uint32_t arrayElement);
|
Note
|
The preprocessor macro VK_WHOLE_SIZE may be passed to the range parameter of vezCmdBindBuffer when an application desires to bind the entire buffer and not a sub range.
|
vkCmdBindImageView
allows an application to specify a sampler alongside the image view. When sampler is VK_NULL_HANDLE, the binding represents a sampled image or texture2D in GLSL. When sample is not VK_NULL_HANDLE, it represents a combined image sampler or 'sampler2D' in GLSL. See 13.1.3 Sampled Image in the Vulkan spec for more details.
10. Render Passes
Render passes in Vulkan are used to encapsulate all draw commands. No draw command may occur outside of a render pass. Render passes allow an application to define a sequence of dependent stages within an application’s rendering pipeline that should be synchronized and may access the same framebuffer attachments. Desktop applications may not benefit as much from this feature as mobile applications, however use of render passes is still encouraged as AMD’s driver can make specific optimizations under many circumstances.
Render passes are greatly simplified in V-EZ. Applications are no longer required to:
-
Explicitly create render pass objects
-
Manage render pass compatibility with pipelines and framebuffers
-
Define attachment image layouts and transitions
-
Define input attachments
-
Define all subpasses up front
-
Define subpass dependencies
These tasks are handled automatically by V-EZ, and in some cases inferred from the SPIR-V of bound pipeline shader stages. To learn more about render passes and their use cases, please see the Vulkan spec.
10.1. Begin A Render Pass
To begin a render pass, an application may call vkCmdBeginRenderPass
. The VezRenderPassBeginInfo
structure requires a target framebuffer to be specified, an array of VezAttachmentReference
structures which define load operations, store operations and clear values. The code listing below demonstrates beginning a render pass with two attachments, namely a single color attachment and a depth stencil attachment. Both attachments are cleared and any values written by the fragment shader stage stored.
1// Clear the framebuffer's color and depth attachments (set clear color to red).
2// Always store the fragment stage results.
3std::array<VezAttachmentReference, 2> attachmentReferences = {};
4attachmentReferences[0].clearValue.color = { 0.3f, 0.3f, 0.3f, 0.0f };
5attachmentReferences[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6attachmentReferences[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
7attachmentReferences[1].clearValue.depthStencil.depth = 1.0f;
8attachmentReferences[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
9attachmentReferences[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
10
11// Begin a render pass.
12VezRenderPassBeginInfo beginInfo = {};
13beginInfo.framebuffer = framebuffer;
14beginInfo.attachmentCount = static_cast<uint32_t>(attachmentReferences.size());
15beginInfo.pAttachments = attachmentReferences.data();
16vezCmdBeginRenderPass(commandBuffer, &beginInfo);
10.2. Next Subpass
By default, calling vkCmdBeginRenderPass starts the first subpass. To transition to a proceeding one, an application may call vezCmdNextSubpass
. No parameters are required except the command buffer the call is being recorded to.
As previously stated, V-EZ determines which framebuffer attachments are written to within each subpass based on the pipeline objects that are bound and draw calls made.
10.3. End A Render Pass
To end a render pass, call vezCmdEndRenderPass
.
10.4. Input Attachments
Vulkan allows framebuffer attachments to be used as inputs or outputs within a render pass. One subpass may write to a color attachment while a proceeding subpass may read from it. V-EZ infers this information from the bound pipeline shader stages, specifically the GLSL subpassInput
uniform type (see 13.1.11. Input Attachment in the Vulkan spec for more details. In the code snippet below, the first subpass outputs to two attachments for color and surface normals.
1#version 450
2#extension GL_ARB_separate_shader_objects : enable
3
4layout(location = 0) in VS_OUT
5{
6 vec3 worldNormal;
7} ps_in;
8
9layout(location = 0) out vec4 albedo;
10layout(location = 1) out vec4 normals;
11
12void main()
13{
14 albedo = ...
15 normals = ps_in.worldNormal;
16}
In the next subpass, the framebuffer attachment storing the normals, index 1, is bound as an input attachment within the shader.
1#version 450
2#extension GL_ARB_separate_shader_objects : enable
3
4layout(input_attachment_index = 1, set = 0, binding = 0) uniform subpassInput normals;
5layout(location = 0) out vec4 finalColor;
6
7void main()
8{
9 vec4 normal = subpassLoad(normals);
10 finalColor = ...
11}
The input_attachment_index
value used in the shader should match the index of the attachment when the framebuffer was created. In V-EZ these must be absolute indices. The same applies for the location
index for output attachments.
11. Updating Memory
Since V-EZ does not explicitly expose underlying memory handles as in Vulkan, applications update buffer and image data using the VkBuffer
and VkImage
handles directly.
11.1. Map and Unmap
V-EZ exposes map and unmap operations for VkBuffer
handles only. An application must ensure that the target VkBuffer
handle was created with the correct VezMemoryFlags
. The VEZ_MEMORY_GPU_ONLY is the only enumeration value which cannot be mapped.
To map and unmap a buffer, an application calls VezMapBuffer
and vezUnmapBuffer
. Care must be taken to call vezFlushMappedBufferRanges
to guarantee writes by the host are made available to the device. The behavior remains nearly indentical to Vulkan’s vkMapMemory
function. See the Vulkan spec for more details.
11.2. Utility Functions
V-EZ simplifies host to device data transfers by providing two utility functions. Both are synchronous function calls on the host and block the calling thread until completion.
1VkResult vezBufferSubData(VkDevice device, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, const void* pData);
2
3typedef struct VezImageSubDataInfo {
4 uint32_t dataRowLength;
5 uint32_t dataImageHeight;
6 VezImageSubresourceLayers imageSubresource;
7 VkOffset3D imageOffset;
8 VkExtent3D imageExtent;
9} VezImageSubDataInfo;
10
11VkResult vezImageSubData(VkDevice device, VkImage image, const VezImageSubDataInfo* pSubDataInfo, const void* pData);
12. GLSL Guide
TODO


Not submitted yetRegistration has been acceptedDisabled by StripeRequires additional informationPending submissionRejected by Stripe, see common reasonsRejected by Stripe, see common reasonsRejected by Stripe, see common reasonsRejected by Stripe, see common reasonsMore information is requiredUnder review by StripeUnder review by StripeDisabled by Stripe, see common reasonsRequires additional information


Saskatoon vegan restaurant Gud Eats expanding to Regina, acquired by Leo's Group
“His goal is not to convert or judge any dietary choices, but rather demonstrate how satisfying plant-based eating can be.”
by Ashley MartinSaskatoon vegan restaurant Gud Eats is expanding to Regina, and the brand has been acquired by Leo’s Group.
The Regina location at 1810 Smith St., behind Norwood on the corner of 11th Avenue downtown, will be Gud Eats’ second storefront.
“Chef and founder Chris Cole has been in the hospitality industry for over 20 years. Gud Eats Inc. is the culmination of Chris’ culinary creativity and personal lifestyle,” Leo’s Group stated on social media.
“His goal is not to convert or judge any dietary choices, but rather demonstrate how satisfying plant-based eating can be.”
Gud Eats’ pub-style menu includes meatless versions of fried chicken, hotdogs, burgers (Beyond and housemade) and shrimp, and dairy/cheese-free versions of ice cream, cheesecake, macaroni and poutine.
Having started as a food truck in August 2017 as Saskatchewan’s first-ever totally plant-based fast food vendor, Gud Eats’ first storefront opened in Saskatoon’s Brevoort Park neighbourhood in November 2017.
The Saskatoon location also includes a mini-market that sells housemade faux-chicken and “skrimp,” as well as known brands like Miyoko’s, Beyond and Earth Island.
Leo’s Group began in 2013 with the “OG” Leopold’s Tavern on Albert Street in Regina. It has since expanded to include 12 restaurants in Regina, Saskatoon, Warman, Winnipeg and Calgary, and is setting up shop in Victoria. Now, it has acquired a controlling interest in Gud Eats.
The Leo’s Group restaurants already include a plant-based section on their menus.
“It was essential to me that they saw the importance of plant-based eating, not only as a fiscal and viable investment, but as an ethical, environmental, and sustainable foundation,” Cole said in a news release.
“I am very impressed and inspired by the growth and success they have accomplished in such a short time. It is endearing that both of our roots are here in Saskatchewan, choosing our home province as a starting point for our businesses.”
The Regina location is currently under construction, according to a neighbouring tenant.


Community Packages
This page lists CodeMirror-related packages maintained by the wider community. Note that the CodeMirror maintainers make no claims about the quality or fitness-for-purpose of any of these. See below for instructions on helping maintain this page.
Key Bindings
| Name | Package |
|---|---|
| Emacs | @replit/codemirror-emacs |
| Vim | @replit/codemirror-vim |
| VS Code | @replit/codemirror-vscode-keymap |
Language Support
Themes
- thememirror
- Large collection of editor themes. With theme editor.
- @ddietr/codemirror-themes
- A collection (material, solarized, dracula, github, aura) of themes.
- @codemirror/theme-one-dark
- One-dark theme. Also suitable as an example for writing a new theme.
Editor Extensions
- @uiw/codemirror-extensions-color
- Pops up an interactive color picker over color codes in the document.
- @uiw/codemirror-extensions-hyper-link
- Make links inside the editor followable.
- @replit/codemirror-indentation-markers
- Displays indentation guides/markers on indented lines.
- codemirror-languageserver
- Integrate the editor with an LSP server over a web socket.
- @uiw/codemirror-extensions-line-numbers-relative
- Count line numbers relative to the line that has the cursor.
- @lqv/codemirror
- CodeMirror plugin for the Liqvid web-based video format. See also @lqv/codebooth.
- @uiw/codemirror-extensions-mentions
- Add completable @-mentions in CodeMirror.
- @emmetio/codemirror6-plugin
- Emmet HTML and CSS expansion.
- y-codemirror.next
- Yjs-based collaborative editing plugin.
Wrappers and Framework Integration
- prosemirror-codemirror-block
- Editor code blocks in a ProseMirror editor using CodeMirror.
- @uiw/react-codemirror
- React component wrapping an editor view.
- @remirror/extension-codemirror6
- Integration of CodeMirror into the Remirror rich text editor.
- solid-codemirror
- CodeMirror integration for SolidJS.
- svelte-codemirror-editor
- Svelte component for CodeMirror.
- vue-codemirror
- Vue 3 component for CodeMirror.
- @A99US/CM6-Browser-Wrapper
- Utility for loading CodeMirror without bundling, as a separate
<script>
tag.
Contributing to this Page
If you spot a problem or want to add a link to this page, please open a pull request on GitHub updating this HTML document.
Welcome additions are open source packages that implement some non-trivial functionality around CodeMirror 6 and that are maintained and fully implemented. If you have some hot new half-baked idea, please let it mature a bit before submitting here.
Note that this page sets a noindex/nofollow meta tag so submitting links in the hope of improving your search rankings is futile.


PPR Nav Case Test Result
This test tests the partial page navigation with an extreme
condition, of issuing a full update but with a render of a single element.
The result should be a full ViewRoot replacement in that case, due to
the ppr navigation being issued.


UHF A film review by John S. Travis Copyright 1989 John S. Travis
Just saw UHF last night at a packed sneak preview at MIT. I always wonder if the free ticket and the rowdy crowd influences me at such previews, but I truly enjoyed the film.
The movie was very funny with lots of sight gags, and it didn't stall very often (in my humble opinion). The beginning is very funny, with his parody of Indy Jones, and of course one of the best moments had to be a song. Weird Al's version of "Money for Nothing" will leave you rolling, one of his best yet.
Plot is simple: Weird Al takes over a loser TV station and makes it a winner with such programs as "Wheel of Fish," "Wide World of Phlegm," and "The Young and the Dyslexic." Their star is the former janitor at the dreaded Channel 8 which tries to put them out of business. As in AIRPLANE, the plot is a parody--"Just stand up and tell them ... .we're not going to take any dirty floors!"
Of course the crowd fave at MIT was the engineer! And everyone went berserk over a line which most others will think mildly amusing : "Congrats: You just won a drink from the firehose." Explanation: getting an education at MIT is often likened to trying to drink from a firehose!
Well, overall this was as good as AIRPLANE, but I'm sure a lot of people won't like the silly type of humor, and might feel their 6 bucks wasted. Who cares! It was free for me, and I laughed the whole night.
Raul:Today, we teach poodles to fly.
John Travis
.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Gemma Collins announces plan to sell her soul to the devil and join Illuminati
The Towie star now believes in mind control because of her unusual “energy vibration” - and would welcome being brainwashed if it meant enjoying riches and success like her idols, Rihanna, Jay-Z and Cardi B
by Charles Wade-PalmerTowie diva Gemma Collins has decided it is time to join a more exclusive club – the Illuminati.
The star has revealed she is hooked on conspiracy theories that a secret society is using top celebrities like puppets as it slowly builds its totalitarian “New World Order”.
And she says she is prepared to “sell her soul to the devil” to sign up.
Gemma, 38, said: “I’m now thinking should I become Illuminati? Who do I need to call to become Illuminati?
"As you know, Rihanna, Britney Spears, Cardi B, the Kardashians apparently, Angelina Jolie, Katie Perry are all part of this – Jay Z and Beyoncé.
“I believe this and have always said there is more to life than we know.”
Speaking on her BBC Sounds podcast, Gemma even invited the group to get in touch.
She said: “They are giving a subliminal message. It all comes back to mind control. Any members of the IIluminati, feel free to come on my podcast. I’m not scared of it, I’d like to know more.
“Apparently, they offer wealth, power and world domination – but in return you sell your soul to the devil. I did ask someone once – I won’t mention their name – how I join and he said I had to call Jay-Z.”
Gemma added that she believes in mind control because of her unusual “energy vibration”.
She said: “I radiate on a different frequency – or you can call it energy – than most. I vibrate at a different energy force.
"The reason I know I’m different to other people is I’m awake in the night, like all mythical creatures.”


Instructions
Back
For this exercise you must select the bubble which best represents the value of the shown fraction, an image of this is shown below. You must get 80% of the problems correct to pass this exercise. You will have 20 seconds per problem.


Full Service General Contractors Since 1977
At this multi client service web site, we believe there is more to value than just the lowest price. That’s why we provide our clients with the highest quality product for the most economical price.
As a full service contractor we provide the complete range of construction services to diverse industries, including commercial, industrial, institutional, and medical. We can either work with your existing plans or provide you with the comprehensive design/build solution.
"To provide our clients with professional service that ensures quality and value in a timely manner while maintaining a safe and healthy workplace for employees."
It goes without saying that safety is one of our key concerns at Avis Construction. We’ve put a safety program in place in order to establish a productive workforce and deliver an ultimately higher quality product. A drug-free workplace, we enforce strict compliance to all federal, state, local and customer regulations.
We’ve earned a reputation for our quality work and our integrity in dealing with clients, architects, suppliers and subcontractors. We work hard to earn your satisfaction and respect. It’s our goal to develop a long lasting relationship with you through honesty and professionalism, so that we can continue to be the sole source for all your contracting needs.
We’re all over the place.
Cleveland is a national construction company specializing in general contracting, construction management, design-build, and self-performing interior trades services. What’s that all mean? Throughout our history, we’ve succeeded by providing a wide range of construction solutions to our clients and delivering a whole lot of quality work.
Family-owned, nationally known.
In business since 1980, Cleveland Construction is a family-owned construction firm with offices and jobsites throughout the United States. We provide the full spectrum of construction services including project planning, logistics, constructability review, value engineering, scheduling, cost estimating and budgeting, quality management, contract administration, and safety management. We are best known for our high level of client satisfaction in the preconstruction phase through our ability to strike the right balance between our schedule, budget and project goals.
Our excellent reputation in the industry comes from our unyielding commitment to delivering on our Make It True® mission. While we approach every construction project with the same guiding operating philosophy — True Safety, True Quality, True Partnerships, and True Management — no two projects are alike. Through tried and tested construction processes, including a comprehensive quality control plan, we ensure a “True” level of finish and consistency throughout.
We’re confident that, given the opportunity, our construction team members will quickly impress you with their industry expertise and passion to get the job done.
|


TXMPMeta
provides the fundamental methods for manipulating XMP metadata. TXMPIterator
provides methods to iterate over existing XMP metadata. TXMPUtils
provides additional utilities layered on top of TXMPMeta
. Use a string class to instantiate the templates; you can use std::string
. The string class is a template parameter, which simplifies its use for clients that have an existing string model different from std::string
.
WXMPMeta
, WXMPIterator
, and WXMPUtils
. They provide wrappers between the top client layer and the actual implementation. The middle layer is responsible for acquiring the threading lock, basic parameter checking, catching propagated exceptions, and releasing the threading lock when appropriate. XMPMeta
, XMPIterator
, and XMPUtils
.TXMP_STRING_TYPE
must be defined first to provide the string class.
The string class used to instantiate the templates must have the following member functions, which match those of std::string:
assign ( const char * str, size_t len ) size_t size() const const char * c_str() const
assign
does not matter, it is always ignored.Use of the XMP Toolkit is reasonably straightforward once you understand the XMP data model. Some tips to keep in mind:
Get/SetStructField
or ComposeStructFieldPath
. Get/SetLocalizedText
when dealing with language alternative (alt-text) arrays.GetProperty
provides a good illustration of the toolkit layering. The declaration below for TXMPMeta::GetProperty
is simplified by hardwiring std::string
. The XMP_StringPtr
type is simply const char *
.
bool TXMPMeta::GetProperty ( XMP_StringPtr schemaNS, XMP_StringPtr propName, std::string * propValue, XMP_OptionBits * options ) const { XMP_StringPtr resultPtr = 0; XMP_StringLen resultLen = 0; bool found = this->xmpObj.GetProperty ( schemaNS, propName, &resultPtr, &resultLen, options ); if ( found ) { if ( propValue != 0 ) propValue->assign ( resultPtr, resultLen ); this->xmpObj.UnlockObject ( kXMP_NoOptions ); } return found; }
The template object contains a data member pointer to the underlying WXMPMeta
object. This is used to dispatch the call to the middle layer. The actual implementation of the XMP toolkit returns string values as a pointer and length, the pointer references private internal storage of the toolkit. The client code copies the string value to the client's string object. This minimizes the amount of string copying, and should the XMP toolkit be built as a DLL ensures that any memory allocation for the client's value is done on the client side. The call to WXMPMeta::UnlockObject
is explained below.
bool WXMPMeta::GetProperty ( XMP_StringPtr schemaNS, XMP_StringPtr propName, XMP_StringPtr * propValue, XMP_StringLen * valueSize, XMP_OptionBits * options ) const { XMP_Bool found; XMP_ENTER_WRAPPER ( "WXMPMeta::GetProperty" ) if ( (schemaNS == 0) || (*schemaNS == 0) ) { XMP_Throw ( "Empty schema namespace URI", kXMPErr_BadSchema ); } if ( (propName == 0) || (*propName == 0) ) { XMP_Throw ( "Empty property name", kXMPErr_BadXPath ); } if ( propValue == 0 ) propValue = &voidStringPtr; if ( valueSize == 0 ) valueSize = &voidStringLen; if ( options == 0 ) options = &voidOptionBits; const XMPMeta & meta = WtoXMPMeta_Ref ( *this ); found = meta.GetProperty ( schemaNS, propName, propValue, valueSize, options ); XMP_EXIT_WRAPPER_KEEP_LOCK ( found ) return found; }
The entry and exit macros in the WXMPMeta
layer acquire the threading lock on entry and usually release it on exit. The lock is kept on exit whenever a string value is returned. Since a pointer to internal data is returned, the threading lock can't be released until after the template code in the client copies the string. The entry and exit macros also prevent uncontrolled exception propagation from the lower layer back to the client. This is not critical for use of the XMP Toolkit as a static library. But it is generally not safe to propagate C++ exceptions across DLL boundaries.


On Tap in Hawaii: Kakaako welcomes Hana Koa Brewing Co. | Honolulu Star-Advertiser
It’s not easy opening a brewery, and extra tough to do so in Hawaii, but today one of those new breweries opens right here on Oahu. Read more
Mahalo for reading the Honolulu Star-Advertiser!
You're reading a premium story. Read the full story with our Print & Digital Subscription.
Already a subscriber? Log in now to continue reading this story.
Print subscriber but without online access? Activate your Digital Account now.


retractall/1
retractall(
+Head)
Removes every clause in module M whose head matches Head.
Head of a Prolog clause.
Head must be instantiated to a term that looks
like a call to a dynamic procedure.
For example, to retract all the clauses of foo/3
, you would write
| ?- retractall(foo(_,_,_)).
Head may be preceded by a M: prefix, in which case the clauses are retracted from module M instead of the calling module.
retractall/1
is useful for erasing all the clauses of a dynamic
procedure without forgetting that it is dynamic; abolish/1
will
not only erase all the clauses, but will also forget absolutely
everything about the procedure. retractall/1
only erases the
clauses. This is important if the procedure is called later on.
Since retractall/1
erases all the dynamic clauses whose
heads match Head, it has no choices to make, and is
determinate. If there are no such clauses, it succeeds trivially.
None of the variables in Head will be instantiated by this
command.
instantiation_error
type_error
permission_error
retract/1
, ref-mdb-rcd.


Last Of The Summer Wine actress Jean Fergusson dies at 74
Last Of The Summer Wine star Jean Fergusson, known for playing the feisty Marina, has died at the age of 74.
Fergusson, described as “the life and soul of any gathering”, died at home on Thursday morning.
With an acting career spanning more than 50 years, she was best known for playing Marina in the long-running sitcom from 1985 until it ended in 2010.
She was also known for appearing in Coronation Street as Dorothy Hoyle from 2010 until 2011.
A statement from her agents, Scott Marshall Partners, said: “It is with great sadness that we announce the death of actress Jean Fergusson, known to millions as flirtatious Marina in the long running BBC comedy Last Of The Summer Wine.
“Jean was a much-loved and respected actress, a brilliant comedienne, raconteur, and the life and soul of any gathering. She will be much missed by her many friends and colleagues.
“Jean passed away, at home, in the early hours of Thursday November 14.
“She is survived by her beloved sister Marjorie, brother-in-law Roger and her nephews Daniel and William.”
‘Allo ‘Allo! actress Vicki Michelle paid tribute to Fergusson, sharing a picture of the two of them together on Twitter.
She wrote: “Shocked & saddened to hear Jean Fergusson has passed Lovely lady, fabulous actress. Saw her Sunday at #SuPollard’s birthday, said she wasn’t feeling well. @benstockbiz and I planned to take her out next week.
“Can’t believe she’s gone #LastoftheSummerWine #SheKnowsYouKnow #Corrie.”
Fergusson’s death comes just over a month after the death of her Last Of The Summer Wine co-star Juliette Kaplan, who played battleaxe Pearl Sibshaw.
Kaplan was 80 when she died from cancer in October.
Wakefield-born actress Fergusson was familiar in households across the UK for her role as the opinionated and attractive Marina in the popular BBC comedy series, which ran from 1973 until 2010 and was set in the Yorkshire Dales.
She joined the sitcom in 1985 as the peroxide blonde love interest of Howard Sibshaw (Robert Fyfe), the pair conducting their affair behind his wife Pearl’s back.
Fergusson first played the character in a stage version of the show in 1984 before joining the TV series.
Prior to starring in Corrie as Dorothy Hoyle, which saw her involved in a kidnapping storyline, she had previously appeared in two minor roles in the soap in 1987 and 1999.
Away from the small screen, Fergusson enjoyed a successful career on the stage, most notably the play She Knows You Know, which she wrote and starred in.
Her role as the comic Hylda Baker at London’s Vaudeville Theatre saw her nominated for a Laurence Olivier Award in 1998.
In recent years, Fergusson appeared on a variety of celebrity quiz shows, including Pointless, and she was also a pantomime headliner.


surveys, analytics, market research
job shadow, user diaries
Encapsulate user goals, based on patterns.
Describe user experience from a workflow perspective.
Tried-and-true patterns are very helpful.
Avoid aesthetic treatment and focus on the essentials.
Designs address persona needs and are validated by testing.
*Scenarios are useful for creating test script.
Especially if they resist user-centered design.
Keep the design simple.
Again, validate design with usability testing.


Once upon a time, a brave adventurer sought fame and fortune.
Little did the adventurer know that others sought the same and soon their paths would cross.


Status of ISBN<PHONE_NUMBER>:
0805367802 is
not
on order.
0805367802
does not have
a pending order needed.
Request status of another ISBN.
Validate by pasting .xhtml copy's URL into
https://html5.validator.nu/


Pirate (ARRR) is a cryptocurrency that solves the issue of financial privacy on the blockchain through forced anonymous transactions. Protect your wallet and transactions with Pirate’s completely anonymous network. With forced private transactions, your privacy cannot be compromised by another users’ activity on the network. If you wish to learn more, please join the official Pirate Discord at https://pirate.black/discord/ or message FishyGuts#5085, who will be happy to help out.
100 messages
Before 05-Dec-19 12:00 AM
jl777c07-Oct-18 08:41 AM
realistically, mining I think is only illegal in bolivia?
so if funds are mined into a publicly known zaddr, then send to a private zaddr in a different wallet. dont do criminal things that gets your wallet.dat confiscated in police raids. that is the best defense
ComputerGenie 👴👴👴07-Oct-18 08:43 AM
dont do criminal things that gets your wallet.dat confiscated in police raids.
house07-Oct-18 08:45 AM
damn ... I guess I need a new career now
Anyone here wanna buy some flowers ?
1
ComputerGenie 👴👴👴07-Oct-18 08:50 AM
fek it's dam'd near 4 am, why do you people not let me sleep?
Flexatron07-Oct-18 09:46 AM
Yo how many more Msol do we need to become #2(edited)
133.4 now
polycryptoblog07-Oct-18 09:51 AM
212
snowdamn07-Oct-18 09:55 AM
interesting discussion
reminds me of something
haha
Flexatron07-Oct-18 10:02 AM
141
212 extra or total?
polycryptoblog07-Oct-18 10:03 AM
Total
Flexatron07-Oct-18 10:03 AM
Damn..getting closer then..
polycryptoblog07-Oct-18 10:03 AM
Zen was 211 last I checked
Flexatron07-Oct-18 10:03 AM
145
rrrj28807-Oct-18 10:05 AM
@jl777c got confused about about your statement ' yes, it is 100% privacy if nobody knows your zaddr '. Coz people will know your zaddr as you trade like through OTC WHICH you have to provide your zaddr to receive, so does this mean it's not 100% privacy ?
Flexatron07-Oct-18 10:06 AM
Just make a new adress then lmao(edited)
Oszy07-Oct-18 10:06 AM
send it to another
passcombo.com 🏴☠🏴07-Oct-18 10:06 AM
just did my first z transfer, 10 utxo's took about 5 min to send using Agama
@rrrj288 there is huge difference when somebody you make transaction with knows your info, and when it is public on the network, agree ?
of course when you do transaction with someone - to that person the transaction cannot be anonymous, how you imagine different ?
Flexatron07-Oct-18 10:08 AM
Uptrend is real
passcombo.com 🏴☠🏴07-Oct-18 10:08 AM
tech will not protect you from yourself at this stage yet
rrrj28807-Oct-18 10:11 AM
@passcombo.com 🏴☠🏴 noob Q what does ' public on the network ' mean here ? Using tortuga instead of trade direct with someone ?
passcombo.com 🏴☠🏴07-Oct-18 10:12 AM
you understand that blockchain like BTC is public ?
rrrj28807-Oct-18 10:13 AM
Oh I see.
 I keep getting "status": "executing", and it's been like that for an hour.
Not in awhile. Can I do that with an executing tx?

All hands on deck, All hands on deck*
"Arrrgh ! she be blowing a gale Cap'n"!
"Right the stern me buckeroos 'n bring her round portside fur a dogleg lest we gravel her rump o'er these treacherous seas"
Stand aside ye pox-faced swab [backhands the provost]
Oszy07-Oct-18 11:06 AM
14156544? blockheight * 256 ?
ComputerGenie 👴👴👴07-Oct-18 11:06 AM
fek @grewalsatinder You could have warned my dumbass that it would peg CPU
Many people must have misunderstanding that the Z (private) address show on blockchain/explorers just like T (transparent) addresses.
@KomodoPlatform @zcashco @PirateChain
What I'm wondering from your tweet:
If somebody manages to saturate the network with z trx will that affect each network node ( because it scans) or is it so optimized that it has no effect like a t transaction?(edited)
ComputerGenie 👴👴👴07-Oct-18 11:16 AM
fek me; my vm is still trying to process coinsupply
CHMEX07-Oct-18 11:16 AM
takes about 15 to 20 mins
grewalsatinder07-Oct-18 11:17 AM
@CHMEX@jl777c can answer better I think
mato12107-Oct-18 11:18 AM
nice post @grewalsatinder
$PIRATE is ~99.82% just shielded transactions. In @PirateChain it is just not possible to send Z (shielded) address transactions to T (transparent) address. Once it's shielded, it's gonna be in shielded transactions
so you cant send coins from z to t if i understand correctly
Flexatron07-Oct-18 11:19 AM
Yes
grewalsatinder07-Oct-18 11:19 AM
correct
mato12107-Oct-18 11:19 AM
but ofc the only transaction
that is on exlorer
is from t to z
but the z adress is not visible
?
ComputerGenie 👴👴👴07-Oct-18 11:21 AM
correct
mato12107-Oct-18 11:21 AM
i think that for noobs like me, this should be stated more plastically
people belive only what they see
sadlly
CHMEX07-Oct-18 11:22 AM
also the amount is not visible
You only know that something happened but not what
ComputerGenie 👴👴👴07-Oct-18 11:22 AM
actually the explorer will show z to z; that some tx did occur, but not info(edited)
that could be a 10000 PIRATE transaction or a 0 PIRATE transaction no way to tell for non wallet owners
mato12107-Oct-18 11:24 AM
Got it!
ComputerGenie 👴👴👴07-Oct-18 11:27 AM
$ komodo-cli coinsupply
error: couldn't connect to server: timeout reached (code 0)
Seems 2 core vm is too weak for that
And in mining news:
[PoolWorker][Thread 0][10/07 06:29:25] Current diff: 1206452.315011298
9.575x higher than KMD diff
grewalsatinder07-Oct-18 11:31 AM
yeh got the same on my system too after long wait
SHossain07-Oct-18 11:36 AM
trying with my alien server. seems the daemon is using only 1 thread
ComputerGenie 👴👴👴07-Oct-18 11:36 AM
I haven had need for such a thing, but with all the trades of PIRATE thus far being OTC I wondered....
Is there a tutorial somewhere to show folks how to intentionally show a 3rd party the details of a tx should a dispute arise?
CHMEX07-Oct-18 11:38 AM
you can go in steps:
komodo-cli coinsupply 100000
komodo-cli coinsupply 200000
komodo-cli coinsupply 300000
...
komodo-cli coinsupply 1000000
komodo-cli coinsupply


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.apache.hivemind.impl.InterceptorStackImpl
public final class InterceptorStackImpl
Implementation of the InterceptorStack
interface; localizes
error checking in one place.
| Constructor Summary | |
|---|---|
InterceptorStackImpl(org.apache.commons.logging.Log log,
ServicePoint sep,
java.lang.Object root)
|
| Method Summary | |
|---|---|
java.lang.String |
getServiceExtensionPointId()
Return the full id of the service extension point for which interceptors are being fabricated. |
java.lang.Class |
getServiceInterface()
Returns the interface for the service; the same as ServicePoint.getServiceInterface() . |
org.apache.commons.logging.Log |
getServiceLog()
Returns the Log instance that should be used to log any information about the service, or the construction of the service. |
Module |
getServiceModule()
Returns the module which contains the service extension point. |
java.lang.Object |
peek()
Returns the current top object on the stack. |
void |
process(InterceptorDefinition interceptorDefinition)
Invoked to process the next interceptor contribution; these should be processed in ascending order. |
void |
push(java.lang.Object interceptor)
Pushes a new instance onto the stack. |
java.lang.String |
toString()
|
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Constructor Detail |
|---|
public InterceptorStackImpl(org.apache.commons.logging.Log log, ServicePoint sep, java.lang.Object root)
| Method Detail |
|---|
public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String getServiceExtensionPointId()
InterceptorStack
getServiceExtensionPointId
in interface InterceptorStack
public Module getServiceModule()
InterceptorStack
getServiceModule
in interface InterceptorStack
public java.lang.Class getServiceInterface()
InterceptorStack
ServicePoint.getServiceInterface()
.
getServiceInterface
in interface InterceptorStack
public java.lang.Object peek()
InterceptorStack
peek
in interface InterceptorStack
public void push(java.lang.Object interceptor)
InterceptorStack
InterceptorStack.peek()
, and should
implement the service extension point's interface.
The stack checks that the interceptor is not null, and that the interceptor implements the service interface.
push
in interface InterceptorStack
public void process(InterceptorDefinition interceptorDefinition)
public org.apache.commons.logging.Log getServiceLog()
InterceptorStack
getServiceLog
in interface InterceptorStack
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


|
Aaron's
Party (Come Get It)
(Aaron Carter) |
|
Talking:
Here's a little bit of old school for ya, That goes a little something like this... I always tried to be the flyest kid in the block The popular one with the rising stocks So that's when I had this bright idea Throw the party of the month No, the party of the year All the fine girls couldn't turn it down Now all I gotta do is get my parents out Should I send them to a movie No, send them to a show Let me think, hmmmmmm It's gotta be long though I said Mom, Dad, yo why ya sittin home It's a Friday night have you seen Aunt Jo And don't worry about stayin' out too long Don't fuss over me, I'll be fine alone Have a good time...  (Come get it) Say it again (Come get it) People all around you gotta (Come get it) From the left to the right, make noise (Come get it) Here we go now, come on Uh uh what what Na na na na... Na na na na... Things are goin' great Then to my surprise Some people walked in, I didn't recognize I said fellows yo ya gotta get out (Hey man I heard this was an open house) Open house? (Yeah that's what the flyers said) I didn't put out flyers! (Well somebody did) Lynn walked in The girl I'm crushin' And the kid spilled juice On my Mom's new cushion I turned around and Another kid broke the lamp (I hope they weren't expensive) They got them from France For now I won't sweat it I'll clean it up later There's a honey over there And I really wanna meet her People all around you gotta (come get it) Everyone together sing it loud (come get it) Jump all around come on (come get it) What? (come get it) Say it again here we go, uh (come get it) People all around you gotta (come get it) From the left to the right, make noise (come get it) Here we go now, come on Uh uh what what Aaron C's in the house, here we go Come with it Break it down (go go go go go...) Is that a car door Oh dang I'm in trouble Everybody get out now On the double I'm dead (your done) that's it for me I'm gonna be picked off my family tree Once Mom finds out 'bout this party I had I don't wanna even start thinkin' about dad I'm hustlin around the house Trying to clean up the mess I sure put my new white Nikes to the test The car door slammed And they're walking up the steps I guess life is good with 10 seconds left (AARON!!!???!!!) Grounded Chorus Aaron C's in the house, come on (come get it) Uh uh what what Fades... |


Download and Watch Gold 2018 Full movie Akshay Kumar !!
Gold (2018)
Duration : 2h 31min
Type : Drama, History, Sport (UA)
Release Date : 15 August 2018
Critic's Rating : 3.5/5
IMDB :8.6/10
Gold Story :
A fictional account, inspired by true events and people, of India’s first gold medal
win as an independent nation at the 1948 Olympics in London. Tapan Das (Akshay Kumar),
the team manager, leads the charge to assemble the country’s first all-Indian hockey
team. His aim is to beat the Britishers at their own game, on their own turf.
Trivia :
The Bradford Bulls rugby league stadium in Odsal, Bradford, West Yorkshire,
doubled for London's Wembley Stadium for the shooting of the Olympics hockey
final.
This is the 1st Akshay Kumar's film to do over 20cr Nett in India on the
Opening Day. The Opening Day Domestic (India) Nett of this film is around
25.3cr.
The speech delivered by Rory Kinnear as Henry Hunt, at the London meeting,
was written by Kinnear himself.
It was rumoured to be a biopic based on the life of hockey player Balbir
Singh Sr., who was on the team that won the first Olympic medal for India
as a free nation in 1948.
Gold Reviews :
There’s no greater pride in sport than to see your country’s flag being hoisted on an international stage. That sentiment gets amplified, when the setup is at the 1948 Olympics in London, where the Indian hockey team had to prove that their dominance in the sport from 1936 to 1948, wasn’t by mere chance. And what makes this sentiment stronger and the win historic, is the fact that the game was played just a year after India became a free country. ‘Gold’ recreates the journey of this spirited and lesser-known team that upstaged the British at the 1948 Olympics and made a statement against the English subjugation of 200 years.
The film begins in 1936, when India made big impact in world hockey and won its third consecutive gold at the Berlin Olympics. This team was called British India team and was managed by the British Raj. One wily and determined Bengali junior manager of the British India team, took on the audacious task to form a new team for free India to participate at the 1948 Olympics in London. His dream was to see the Indian flag furling high on British soil, which would be a moment of pride for every Indian.
The emotions run high in the film, as a handful of Indians put their personal differences aside to make the country proud. As we witness India winning its first gold as a free nation, you also see the Pakistani players cheer for Indians playing on the field. Moments like this, make ‘Gold’ a film which is more just a sports drama. This one is surely worth its weight in gold.
Photo's from the movie :
Download :
You may also like
Subscribe to my weekly newsletter


When any pepper is dried and smoked, it is referred to as a Chipotle. Usually with a wrinkled, drak brown
appearance, the Chipotle delivers a smokey...
When any pepper is dried and smoked, it is referred to as a Chipotle. Usually with a wrinkled, drak brown
appearance, the Chipotle delivers a smokey...
When any pepper is dried and smoked, it is referred to as a Chipotle. Usually with a wrinkled, drak brown
appearance, the Chipotle delivers a smokey...
When any pepper is dried and smoked, it is referred to as a Chipotle. Usually with a wrinkled, drak brown
appearance, the Chipotle delivers a smokey...


| DOSE: |
repeated |
oral |
GBL |
(daily) |
It all started when I was out at an event with my friends. I’d heard of GBL (GHB) and that they’d tried it, and it was good, but I was reluctant to try it myself. This particular day, although very apprehensive, I did try it and once I knew what I was looking for I really enjoyed the experience. This was in the back end of 2008.
Since then my use of it was sporadic, recreational and enjoyable, if not somewhat reckless at times. Then my tolerance went up and then for a while even 1-2ml of GBL would make me drowsy or pass out. I was usually drinking at the time but that never mattered before. So I laid off it for a while, settled down, worked and got on with my girlfriend at the time. Like I said, my use was sporadic, I’d buy a 125ml bottle and it’d last me ages. I was well aware it was addictive and I never went a whole week on it or have it all day, and I enjoyed it all the time I used it. It was more of a release than a high for me, I’ve got my share of emotional and mental problems - but this story is about drugs, right?
Over the festive season I usually get really depressed for some reason, and try and hide away. I did so that particular Christmas with an Xbox and a bottle of GBL, my standard dose was 2ml or 1.5 and that would get me high for a few hours. I became reclusive, even to my girlfriend, but I was still not addicted.
As many of us have felt, the recession hit. I lost my job in January and my girlfriend shortly after that, about a month or so. For a while, after I figured out what had been going on, I was on top of the world… For some reason. Call it denial, whatever… I started eating healthily, staying away from drugs, body-building, exercising, everything a physically fit 19-year-old guy should be doing. Then I slowly started to slip back into the depression that I’ve been in and out of for 5 years or so. I started using GBL again but it was still recreational at that point. My release, if you like. It made it seem ok to feel how I was feeling, even though I try to hide it from everybody else. Then, I can’t remember specifically, things got worse.
Of course I’d go out and see my friends, socialize, take a myriad of drugs in unusual circumstances (bowling alleys, etc) and GBL was always there for the comedown. It was my saviour when we had about £30 of speed and a few E’s. The next day would have been horrendous, but luckily my best friend was there to help us out. It was a slow slope down to addiction but it took a couple of months.
The first time I realised I was addicted was when I was working at a DIY shop for an old man. I never brought any into work, I had the shakes and I was a paranoid wreck all day. I panicked, but I got through the day.  In retrospect I should have quit and stuck it out then when the withdrawal symptoms weren’t so severe. Retrospect is a marvellous, useless thing isn’t it? Well not so useless as I’ll ever touch GBL again but I can still kick myself. In the coming months my usage was going up every order. A 125ml bottle would last me 5 days, and at one point I was so reckless I was using over 60ml a day and still using other drugs like speed, ecstasy…  Then again, I didn’t exactly want to live my life either so what did I care?
Then the REAL addiction came along. I went to doctors, drugs counsellors, you name it - I went there and got the same response.
“Uhhh GBH? What’s that?”
So I compiled the research myself and pointed the professionals in the right direction, but of course doctors know everything and drugs counsellors know what’s best. “Try and cut down” this and “Can you not just quit?”
I was using 3ml every hit, going up and up to 5ml, 12 times a day or more(every 1-2 hours), and that was just to keep me from feeling the withdrawal symptoms (extreme anxiety/paranoia, panic attacks, and that was just the start.) I still nearly passed out places and shit like that, and it was going to take another month for the funding to come through (that was if it was approved) for me to have an in-patient detox. I’d already had to steal money to feed my habit which I couldn’t break, no matter how hard I tried, and I’m still ashamed of it to this day. I’d tried coming off it and tapering numerous times. At first the panic attacks were the main problem and so I went to the doctors to get some beta-blockers, thus stopping the pounding heart.  I couldn’t have handled it with just the beta blockers, a bad acid trip for a week with no sleep? No thanks.
 My hands and legs were going numb, I could barely focus, remember anything. I was a zombie, almost. That’s when I decided to contact the hospital directly and see if they would detox me.
They agreed, and I gave them all the relevant information regarding withdrawal, and of course being doctors they know everything, quickly scanned the info and put me on a ward with a saline drip and benzodiazepines. Insufficient amounts and of course, I needed other drugs like Haloperidol, an anti-psychotic, if it was going to be anything like last time. The benzo’s seemed to hold off most of the withdrawal and keep me steady, but by the first night I was already hallucinating. I got anxious, paranoid, nearly signed myself out of the hospital and then I went psychotic.
The next 48 hours I only remember parts of, but I was always trying to escape. First I thought it was a joke, and you had to press the correct series of buttons to escape, like one of those stitch-up programs on TV because there was a camera in the top corner of the cell.   I could feel it sinking and hear the pressure building up on the outside, I thought it had been shoved off the back of a ship, or fired into space.
Then there was a whole ordeal of people who were a sect from normal society. You had the normal people like you and me and the other people who were being locked away. I was being confined and bound because I was depressed and didn’t want to live… Something like that, there was a blur of hallucinations. At one point I thought I had actually committed suicide, and my mother as well. There was no heaven or hell, just these “pods” that we were floating around in and we could earn the right to be re-integrated into society. People didn’t age once they became “pure human beings” - maybe I was close to death then and that is the afterlife, who knows. I tried to go into nothingness, but came back because I felt there was something here still I needed to do…. I had a lot of strange hallucinations.
I thought I was in some sort of government research facility and being irradiated in the cell, and what I can only describe as “nanoids” would attack me constantly. I smashed my head against the wall repeatedly to knock myself out so someone would come to check on me and I’d have another chance to escape, and it worked but I failed and ended up in another cell with more nanoids and a higher level of radiation. They were grafting onto my skin, using my skin cells to generate more of themselves… I was terrified. I thought I was going to die alone in a police cell with no-one knowing where I was.
  I met some interesting characters and had some interesting conversations. I was a mess when I went in but now I’m on the way to getting my life back. This has been invaluable life-experience for me, it’s taught me that life is too short to waste and changed me for the better.
 I was lucky, you might not be. In moderation it can be the best thing on the planet, but if you’re down and you go on a bender… Don’t do it with GHB or any of it’s precursors. Get some anti-depressants and some counselling. Have a few nights on the beer, whatever. Just don’t end up where I did, you may not be as lucky to have such supportive family in your life as I have.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.