vulkan/meta: Add a concept of rect pipelines
Most hardware supports some sort of rectangle primitive. This adds a new VK_PRIMITIVE_TOPOLOGY_RECT_LIST_MESA which will be used by the vast majority of (if not all) meta commands. Drivers can key off of of this to build pipelines differently and implement their own cmd_draw_rects and cmd_draw_volume hooks or they can map it to TRIANGLE_LIST and use the provided helpers. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:

committed by
Marge Bot

parent
8418d6c97a
commit
514c10344e
@@ -70,6 +70,7 @@ vulkan_runtime_files = files(
|
||||
'vk_log.h',
|
||||
'vk_meta.c',
|
||||
'vk_meta.h',
|
||||
'vk_meta_draw_rects.c',
|
||||
'vk_nir.c',
|
||||
'vk_nir.h',
|
||||
'vk_nir_convert_ycbcr.c',
|
||||
|
@@ -21,10 +21,11 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "vk_meta.h"
|
||||
#include "vk_meta_private.h"
|
||||
|
||||
#include "vk_command_buffer.h"
|
||||
#include "vk_device.h"
|
||||
#include "vk_pipeline.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "util/hash_table.h"
|
||||
@@ -110,6 +111,9 @@ vk_meta_device_init(struct vk_device *device,
|
||||
cache_key_equal);
|
||||
simple_mtx_init(&meta->cache_mtx, mtx_plain);
|
||||
|
||||
meta->cmd_draw_rects = vk_meta_draw_rects;
|
||||
meta->cmd_draw_volume = vk_meta_draw_volume;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -228,6 +232,66 @@ vk_meta_create_pipeline_layout(struct vk_device *device,
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
create_rect_list_pipeline(struct vk_device *device,
|
||||
struct vk_meta_device *meta,
|
||||
const VkGraphicsPipelineCreateInfo *info,
|
||||
VkPipeline *pipeline_out)
|
||||
{
|
||||
const struct vk_device_dispatch_table *disp = &device->dispatch_table;
|
||||
VkDevice _device = vk_device_to_handle(device);
|
||||
|
||||
VkGraphicsPipelineCreateInfo info_local = *info;
|
||||
|
||||
STACK_ARRAY(VkPipelineShaderStageCreateInfo, stages, info->stageCount + 1);
|
||||
for (uint32_t i = 0; i < info->stageCount; i++) {
|
||||
assert(info->pStages[i].stage != VK_SHADER_STAGE_VERTEX_BIT);
|
||||
stages[i + 1] = info->pStages[i];
|
||||
}
|
||||
|
||||
VkPipelineShaderStageNirCreateInfoMESA vs_nir_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_NIR_CREATE_INFO_MESA,
|
||||
.nir = vk_meta_draw_rects_vs_nir(meta),
|
||||
};
|
||||
stages[0] = (VkPipelineShaderStageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = &vs_nir_info,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
info_local.stageCount = info->stageCount + 1;
|
||||
info_local.pStages = stages;
|
||||
info_local.pVertexInputState = &vk_meta_draw_rects_vi_state;
|
||||
info_local.pViewportState = &vk_meta_draw_rects_vs_state;
|
||||
|
||||
uint32_t dyn_count = info->pDynamicState != NULL ?
|
||||
info->pDynamicState->dynamicStateCount : 0;
|
||||
|
||||
STACK_ARRAY(VkDynamicState, dyn_state, dyn_count + 2);
|
||||
for (uint32_t i = 0; i < dyn_count; i++)
|
||||
dyn_state[i] = info->pDynamicState->pDynamicStates[i];
|
||||
|
||||
dyn_state[dyn_count + 0] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||
dyn_state[dyn_count + 1] = VK_DYNAMIC_STATE_SCISSOR;
|
||||
|
||||
const VkPipelineDynamicStateCreateInfo dyn_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
.dynamicStateCount = dyn_count + 2,
|
||||
.pDynamicStates = dyn_state,
|
||||
};
|
||||
|
||||
info_local.pDynamicState = &dyn_info;
|
||||
|
||||
VkResult result = disp->CreateGraphicsPipelines(_device, VK_NULL_HANDLE,
|
||||
1, &info_local, NULL,
|
||||
pipeline_out);
|
||||
|
||||
STACK_ARRAY_FINISH(dyn_state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const VkPipelineRasterizationStateCreateInfo default_rs_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.depthClampEnable = false,
|
||||
@@ -254,6 +318,7 @@ vk_meta_create_graphics_pipeline(struct vk_device *device,
|
||||
{
|
||||
const struct vk_device_dispatch_table *disp = &device->dispatch_table;
|
||||
VkDevice _device = vk_device_to_handle(device);
|
||||
VkResult result;
|
||||
|
||||
VkGraphicsPipelineCreateInfo info_local = *info;
|
||||
|
||||
@@ -268,6 +333,10 @@ vk_meta_create_graphics_pipeline(struct vk_device *device,
|
||||
};
|
||||
__vk_append_struct(&info_local, &r_info);
|
||||
|
||||
/* Assume rectangle pipelines */
|
||||
if (info_local.pInputAssemblyState == NULL)
|
||||
info_local.pInputAssemblyState = &vk_meta_draw_rects_ia_state;
|
||||
|
||||
if (info_local.pRasterizationState == NULL)
|
||||
info_local.pRasterizationState = &default_rs_info;
|
||||
|
||||
@@ -304,9 +373,16 @@ vk_meta_create_graphics_pipeline(struct vk_device *device,
|
||||
}
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkResult result = disp->CreateGraphicsPipelines(_device, VK_NULL_HANDLE,
|
||||
1, &info_local,
|
||||
NULL, &pipeline);
|
||||
if (info_local.pInputAssemblyState->topology ==
|
||||
VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA) {
|
||||
result = create_rect_list_pipeline(device, meta,
|
||||
&info_local,
|
||||
&pipeline);
|
||||
} else {
|
||||
result = disp->CreateGraphicsPipelines(_device, VK_NULL_HANDLE,
|
||||
1, &info_local,
|
||||
NULL, &pipeline);
|
||||
}
|
||||
if (unlikely(result != VK_SUCCESS))
|
||||
return result;
|
||||
|
||||
|
@@ -37,9 +37,34 @@ struct hash_table;
|
||||
struct vk_command_buffer;
|
||||
struct vk_device;
|
||||
|
||||
struct vk_meta_rect {
|
||||
uint32_t x0, y0, x1, y1;
|
||||
float z;
|
||||
uint32_t layer;
|
||||
};
|
||||
|
||||
#define VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA (VkPrimitiveTopology)11
|
||||
|
||||
struct vk_meta_device {
|
||||
struct hash_table *cache;
|
||||
simple_mtx_t cache_mtx;
|
||||
|
||||
uint32_t max_bind_map_buffer_size_B;
|
||||
|
||||
VkResult (*cmd_bind_map_buffer)(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
VkBuffer buffer,
|
||||
void **map_out);
|
||||
|
||||
void (*cmd_draw_rects)(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
uint32_t rect_count,
|
||||
const struct vk_meta_rect *rects);
|
||||
|
||||
void (*cmd_draw_volume)(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
const struct vk_meta_rect *rect,
|
||||
uint32_t layer_count);
|
||||
};
|
||||
|
||||
VkResult vk_meta_device_init(struct vk_device *device,
|
||||
@@ -156,6 +181,16 @@ VkResult vk_meta_create_image_view(struct vk_command_buffer *cmd,
|
||||
const VkImageViewCreateInfo *info,
|
||||
VkImageView *image_view_out);
|
||||
|
||||
void vk_meta_draw_rects(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
uint32_t rect_count,
|
||||
const struct vk_meta_rect *rects);
|
||||
|
||||
void vk_meta_draw_volume(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
const struct vk_meta_rect *rect,
|
||||
uint32_t layer_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
282
src/vulkan/runtime/vk_meta_draw_rects.c
Normal file
282
src/vulkan/runtime/vk_meta_draw_rects.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright © 2022 Collabora Ltd
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "vk_meta_private.h"
|
||||
|
||||
#include "vk_command_buffer.h"
|
||||
#include "vk_command_pool.h"
|
||||
#include "vk_device.h"
|
||||
|
||||
#include "nir_builder.h"
|
||||
|
||||
const VkPipelineVertexInputStateCreateInfo vk_meta_draw_rects_vi_state = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
.vertexBindingDescriptionCount = 1,
|
||||
.pVertexBindingDescriptions = &(const VkVertexInputBindingDescription) {
|
||||
.binding = 0,
|
||||
.stride = 4 * sizeof(uint32_t),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
},
|
||||
.vertexAttributeDescriptionCount = 1,
|
||||
.pVertexAttributeDescriptions = &(const VkVertexInputAttributeDescription) {
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32A32_UINT,
|
||||
.offset = 0,
|
||||
},
|
||||
};
|
||||
|
||||
const VkPipelineInputAssemblyStateCreateInfo vk_meta_draw_rects_ia_state = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||
.topology = VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA,
|
||||
.primitiveRestartEnable = VK_FALSE,
|
||||
};
|
||||
|
||||
const VkPipelineViewportStateCreateInfo vk_meta_draw_rects_vs_state = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
.viewportCount = 1,
|
||||
.scissorCount = 1,
|
||||
};
|
||||
|
||||
nir_shader *
|
||||
vk_meta_draw_rects_vs_nir(struct vk_meta_device *device)
|
||||
{
|
||||
nir_builder build = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL,
|
||||
"vk-meta-draw-rects-vs");
|
||||
nir_builder *b = &build;
|
||||
|
||||
nir_variable *in = nir_variable_create(b->shader, nir_var_shader_in,
|
||||
glsl_uvec4_type(), "vtx_in");
|
||||
in->data.location = VERT_ATTRIB_GENERIC0;
|
||||
|
||||
nir_variable *pos = nir_variable_create(b->shader, nir_var_shader_out,
|
||||
glsl_vec4_type(), "gl_Position");
|
||||
pos->data.location = VARYING_SLOT_POS;
|
||||
|
||||
nir_variable *layer = nir_variable_create(b->shader, nir_var_shader_out,
|
||||
glsl_int_type(), "gl_Layer");
|
||||
layer->data.location = VARYING_SLOT_LAYER;
|
||||
|
||||
nir_ssa_def *vtx = nir_load_var(b, in);
|
||||
nir_store_var(b, pos, nir_vec4(b, nir_channel(b, vtx, 0),
|
||||
nir_channel(b, vtx, 1),
|
||||
nir_channel(b, vtx, 2),
|
||||
nir_imm_float(b, 1)),
|
||||
0xf);
|
||||
nir_store_var(b, layer, nir_iadd(b, nir_load_instance_id(b),
|
||||
nir_channel(b, vtx, 3)),
|
||||
0x1);
|
||||
|
||||
return b->shader;
|
||||
}
|
||||
|
||||
struct vertex {
|
||||
float x, y, z;
|
||||
uint32_t layer;
|
||||
};
|
||||
|
||||
static void
|
||||
setup_viewport_scissor(struct vk_command_buffer *cmd,
|
||||
uint32_t rect_count,
|
||||
const struct vk_meta_rect *rects,
|
||||
float *x_scale, float *y_scale)
|
||||
{
|
||||
const struct vk_device_dispatch_table *disp =
|
||||
&cmd->base.device->dispatch_table;
|
||||
VkCommandBuffer _cmd = vk_command_buffer_to_handle(cmd);
|
||||
|
||||
assert(rects[0].x0 < rects[0].x1 && rects[0].y0 < rects[0].y1);
|
||||
uint32_t xbits = rects[0].x1 - 1, ybits = rects[0].y1 - 1;
|
||||
float zmin = rects[0].z, zmax = rects[0].z;
|
||||
for (uint32_t r = 1; r < rect_count; r++) {
|
||||
assert(rects[r].x0 < rects[r].x1 && rects[r].y0 < rects[r].y1);
|
||||
xbits |= rects[r].x1 - 1;
|
||||
ybits |= rects[r].y1 - 1;
|
||||
zmin = fminf(zmin, rects[r].z);
|
||||
zmax = fminf(zmax, rects[r].z);
|
||||
}
|
||||
|
||||
/* Annoyingly, we don't actually know the render area. We assume that all
|
||||
* our rects are inside the render area. We further assume the maximum
|
||||
* image and/or viewport size is a power of two. This means we can round
|
||||
* up to a power of two without going outside any maximums. Using a power
|
||||
* of two will ensure we don't lose precision when scaling coordinates.
|
||||
*/
|
||||
int xmax_log2 = 1 + util_logbase2(xbits);
|
||||
int ymax_log2 = 1 + util_logbase2(ybits);
|
||||
|
||||
assert(xmax_log2 >= 0 && xmax_log2 <= 31);
|
||||
assert(ymax_log2 >= 0 && ymax_log2 <= 31);
|
||||
|
||||
/* We don't care about precise bounds on Z, only that it's inside [0, 1] if
|
||||
* the implementaiton only supports [0, 1].
|
||||
*/
|
||||
if (zmin >= 0.0f && zmax <= 1.0f) {
|
||||
zmin = 0.0f;
|
||||
zmax = 1.0f;
|
||||
}
|
||||
|
||||
VkViewport viewport = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = ldexpf(1.0, xmax_log2),
|
||||
.height = ldexpf(1.0, ymax_log2),
|
||||
.minDepth = zmin,
|
||||
.maxDepth = zmax,
|
||||
};
|
||||
disp->CmdSetViewport(_cmd, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor = {
|
||||
.offset = { 0, 0 },
|
||||
.extent = { 1u << xmax_log2, 1u << ymax_log2 },
|
||||
};
|
||||
disp->CmdSetScissor(_cmd, 0, 1, &scissor);
|
||||
|
||||
/* Scaling factors */
|
||||
*x_scale = ldexpf(2.0, -xmax_log2);
|
||||
*y_scale = ldexpf(2.0, -ymax_log2);
|
||||
}
|
||||
|
||||
static const uint32_t rect_vb_size_B = 6 * 4 * sizeof(float);
|
||||
|
||||
static VkResult
|
||||
create_vertex_buffer(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
float x_scale, float y_scale,
|
||||
uint32_t rect_count,
|
||||
const struct vk_meta_rect *rects,
|
||||
VkBuffer *buffer_out)
|
||||
{
|
||||
VkResult result;
|
||||
|
||||
const VkBufferCreateInfo vtx_buffer_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = rect_count * rect_vb_size_B,
|
||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
.queueFamilyIndexCount = 1,
|
||||
.pQueueFamilyIndices = &cmd->pool->queue_family_index,
|
||||
};
|
||||
|
||||
result = vk_meta_create_buffer(cmd, meta, &vtx_buffer_info, buffer_out);
|
||||
if (unlikely(result != VK_SUCCESS))
|
||||
return result;
|
||||
|
||||
void *map;
|
||||
result = meta->cmd_bind_map_buffer(cmd, meta, *buffer_out, &map);
|
||||
if (unlikely(result != VK_SUCCESS))
|
||||
return result;
|
||||
|
||||
for (uint32_t r = 0; r < rect_count; r++) {
|
||||
float x0 = rects[r].x0 * x_scale - 1.0f;
|
||||
float y0 = rects[r].y0 * y_scale - 1.0f;
|
||||
float x1 = rects[r].x1 * x_scale - 1.0f;
|
||||
float y1 = rects[r].y1 * y_scale - 1.0f;
|
||||
float z = rects[r].z;
|
||||
uint32_t w = rects[r].layer;
|
||||
|
||||
struct vertex rect_vb_data[6] = {
|
||||
{ x0, y1, z, w },
|
||||
{ x0, y0, z, w },
|
||||
{ x1, y1, z, w },
|
||||
|
||||
{ x1, y0, z, w },
|
||||
{ x1, y1, z, w },
|
||||
{ x0, y0, z, w },
|
||||
};
|
||||
assert(sizeof(rect_vb_data) == rect_vb_size_B);
|
||||
memcpy((char *)map + r * rect_vb_size_B, rect_vb_data, rect_vb_size_B);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vk_meta_draw_volume(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
const struct vk_meta_rect *rect,
|
||||
uint32_t layer_count)
|
||||
{
|
||||
const struct vk_device_dispatch_table *disp =
|
||||
&cmd->base.device->dispatch_table;
|
||||
VkCommandBuffer _cmd = vk_command_buffer_to_handle(cmd);
|
||||
|
||||
float x_scale, y_scale;
|
||||
setup_viewport_scissor(cmd, 1, rect, &x_scale, &y_scale);
|
||||
|
||||
VkBuffer vtx_buffer;
|
||||
VkResult result = create_vertex_buffer(cmd, meta, x_scale, y_scale,
|
||||
1, rect, &vtx_buffer);
|
||||
if (unlikely(result != VK_SUCCESS)) {
|
||||
/* TODO: Report error */
|
||||
return;
|
||||
}
|
||||
|
||||
const VkDeviceSize zero = 0;
|
||||
disp->CmdBindVertexBuffers(_cmd, 0, 1, &vtx_buffer, &zero);
|
||||
|
||||
disp->CmdDraw(_cmd, 6, layer_count, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
vk_meta_draw_rects(struct vk_command_buffer *cmd,
|
||||
struct vk_meta_device *meta,
|
||||
uint32_t rect_count,
|
||||
const struct vk_meta_rect *rects)
|
||||
{
|
||||
const struct vk_device_dispatch_table *disp =
|
||||
&cmd->base.device->dispatch_table;
|
||||
VkCommandBuffer _cmd = vk_command_buffer_to_handle(cmd);
|
||||
|
||||
/* Two triangles with VK_FORMAT_R16G16_UINT */
|
||||
const uint32_t rect_vb_size_B = 6 * 3 * sizeof(float);
|
||||
const uint32_t rects_per_draw =
|
||||
meta->max_bind_map_buffer_size_B / rect_vb_size_B;
|
||||
|
||||
if (rect_count == 0)
|
||||
return;
|
||||
|
||||
float x_scale, y_scale;
|
||||
setup_viewport_scissor(cmd, rect_count, rects, &x_scale, &y_scale);
|
||||
|
||||
uint32_t next_rect = 0;
|
||||
while (next_rect < rect_count) {
|
||||
const uint32_t count = MIN2(rects_per_draw, rect_count - next_rect);
|
||||
|
||||
VkBuffer vtx_buffer;
|
||||
VkResult result = create_vertex_buffer(cmd, meta, x_scale, y_scale,
|
||||
count, &rects[next_rect],
|
||||
&vtx_buffer);
|
||||
if (unlikely(result != VK_SUCCESS)) {
|
||||
/* TODO: Report error */
|
||||
return;
|
||||
}
|
||||
|
||||
const VkDeviceSize zero = 0;
|
||||
disp->CmdBindVertexBuffers(_cmd, 0, 1, &vtx_buffer, &zero);
|
||||
|
||||
disp->CmdDraw(_cmd, 6 * count, 1, 0, 0);
|
||||
|
||||
next_rect += count;
|
||||
}
|
||||
assert(next_rect == rect_count);
|
||||
}
|
42
src/vulkan/runtime/vk_meta_private.h
Normal file
42
src/vulkan/runtime/vk_meta_private.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright © 2022 Collabora Ltd
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef VK_META_PRIVATE_H
|
||||
#define VK_META_PRIVATE_H
|
||||
|
||||
#include "vk_meta.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const VkPipelineVertexInputStateCreateInfo vk_meta_draw_rects_vi_state;
|
||||
extern const VkPipelineInputAssemblyStateCreateInfo vk_meta_draw_rects_ia_state;
|
||||
extern const VkPipelineViewportStateCreateInfo vk_meta_draw_rects_vs_state;
|
||||
|
||||
struct nir_shader *vk_meta_draw_rects_vs_nir(struct vk_meta_device *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VK_META_PRIVATE_H */
|
Reference in New Issue
Block a user