Signed-off-by: Chia-I Wu <olvaffe@gmail.com> Reviewed-by: Ryan Neph <ryanneph@google.com> Reviewed-by: Gert Wollny <gert.wollny@collabora.com>macos/master
parent
48be4bd55f
commit
a5149985ee
@ -0,0 +1,351 @@ |
||||
/*
|
||||
* Copyright 2021 Google LLC |
||||
* SPDX-License-Identifier: MIT |
||||
*/ |
||||
|
||||
#include "vkr_cs.h" |
||||
|
||||
#include "util/u_memory.h" |
||||
|
||||
#include "vrend_iov.h" |
||||
|
||||
void |
||||
vkr_cs_encoder_set_stream(struct vkr_cs_encoder *enc, |
||||
const struct iovec *iov, |
||||
int iov_count, |
||||
size_t offset, |
||||
size_t size) |
||||
{ |
||||
enc->stream.iov = iov; |
||||
enc->stream.iov_count = iov_count; |
||||
enc->stream.offset = offset; |
||||
enc->stream.size = size; |
||||
/* clear cache */ |
||||
enc->stream.cached_index = 0; |
||||
enc->stream.cached_offset = 0; |
||||
|
||||
vkr_cs_encoder_seek_stream(enc, 0); |
||||
} |
||||
|
||||
static bool |
||||
vkr_cs_encoder_translate_stream_offset(struct vkr_cs_encoder *enc, |
||||
size_t offset, |
||||
int *iov_index, |
||||
size_t *iov_offset) |
||||
{ |
||||
int idx = 0; |
||||
|
||||
/* use or clear cache */ |
||||
if (offset >= enc->stream.cached_offset) { |
||||
offset -= enc->stream.cached_offset; |
||||
idx = enc->stream.cached_index; |
||||
} else { |
||||
enc->stream.cached_index = 0; |
||||
enc->stream.cached_offset = 0; |
||||
} |
||||
|
||||
while (true) { |
||||
if (idx >= enc->stream.iov_count) |
||||
return false; |
||||
|
||||
const struct iovec *iov = &enc->stream.iov[idx]; |
||||
if (offset < iov->iov_len) |
||||
break; |
||||
|
||||
idx++; |
||||
offset -= iov->iov_len; |
||||
|
||||
/* update cache */ |
||||
enc->stream.cached_index++; |
||||
enc->stream.cached_offset += iov->iov_len; |
||||
} |
||||
|
||||
*iov_index = idx; |
||||
*iov_offset = offset; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static void |
||||
vkr_cs_encoder_update_end(struct vkr_cs_encoder *enc) |
||||
{ |
||||
const struct iovec *iov = &enc->stream.iov[enc->next_iov - 1]; |
||||
const size_t iov_offset = enc->cur - (uint8_t *)iov->iov_base; |
||||
const size_t iov_remain = iov->iov_len - iov_offset; |
||||
|
||||
if (enc->remaining_size >= iov_remain) { |
||||
enc->end = enc->cur + iov_remain; |
||||
enc->remaining_size -= iov_remain; |
||||
} else { |
||||
enc->end = enc->cur + enc->remaining_size; |
||||
enc->remaining_size = 0; |
||||
} |
||||
} |
||||
|
||||
void |
||||
vkr_cs_encoder_seek_stream(struct vkr_cs_encoder *enc, size_t pos) |
||||
{ |
||||
const size_t offset = enc->stream.offset + pos; |
||||
int iov_index; |
||||
size_t iov_offset; |
||||
if (pos > enc->stream.size || !vkr_cs_encoder_translate_stream_offset( |
||||
enc, offset, &iov_index, &iov_offset)) { |
||||
vkr_cs_encoder_set_fatal(enc); |
||||
return; |
||||
} |
||||
|
||||
enc->remaining_size = enc->stream.size - pos; |
||||
enc->next_iov = iov_index + 1; |
||||
|
||||
const struct iovec *iov = &enc->stream.iov[iov_index]; |
||||
enc->cur = iov->iov_base; |
||||
enc->cur += iov_offset; |
||||
|
||||
vkr_cs_encoder_update_end(enc); |
||||
} |
||||
|
||||
static bool |
||||
vkr_cs_encoder_next_iov(struct vkr_cs_encoder *enc) |
||||
{ |
||||
if (enc->next_iov >= enc->stream.iov_count) |
||||
return false; |
||||
|
||||
const struct iovec *iov = &enc->stream.iov[enc->next_iov++]; |
||||
enc->cur = iov->iov_base; |
||||
vkr_cs_encoder_update_end(enc); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static uint8_t * |
||||
vkr_cs_encoder_get_ptr(struct vkr_cs_encoder *enc, |
||||
size_t size, |
||||
size_t *ptr_size) |
||||
{ |
||||
while (true) { |
||||
uint8_t *ptr = enc->cur; |
||||
const size_t avail = enc->end - enc->cur; |
||||
|
||||
if (avail) { |
||||
*ptr_size = MIN2(size, avail); |
||||
enc->cur += *ptr_size; |
||||
return ptr; |
||||
} |
||||
|
||||
if (!vkr_cs_encoder_next_iov(enc)) { |
||||
*ptr_size = 0; |
||||
return size ? NULL : ptr; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void |
||||
vkr_cs_encoder_write_internal(struct vkr_cs_encoder *enc, |
||||
size_t size, |
||||
const void *val, |
||||
size_t val_size) |
||||
{ |
||||
size_t pad_size = size - val_size; |
||||
|
||||
do { |
||||
size_t ptr_size; |
||||
uint8_t *ptr = vkr_cs_encoder_get_ptr(enc, val_size, &ptr_size); |
||||
if (unlikely(!ptr)) { |
||||
vkr_cs_encoder_set_fatal(enc); |
||||
return; |
||||
} |
||||
|
||||
memcpy(ptr, val, ptr_size); |
||||
val = (const uint8_t *)val + ptr_size; |
||||
val_size -= ptr_size; |
||||
} while (val_size); |
||||
|
||||
while (pad_size) { |
||||
size_t ptr_size; |
||||
const void *ptr = vkr_cs_encoder_get_ptr(enc, pad_size, &ptr_size); |
||||
if (unlikely(!ptr)) { |
||||
vkr_cs_encoder_set_fatal(enc); |
||||
return; |
||||
} |
||||
pad_size -= ptr_size; |
||||
} |
||||
} |
||||
|
||||
void |
||||
vkr_cs_decoder_init(struct vkr_cs_decoder *dec, |
||||
const struct util_hash_table_u64 *object_table) |
||||
{ |
||||
memset(dec, 0, sizeof(*dec)); |
||||
dec->object_table = object_table; |
||||
} |
||||
|
||||
void |
||||
vkr_cs_decoder_fini(struct vkr_cs_decoder *dec) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
for (uint32_t i = 0; i < pool->buffer_count; i++) |
||||
free(pool->buffers[i]); |
||||
if (pool->buffers) |
||||
free(pool->buffers); |
||||
} |
||||
|
||||
static void |
||||
vkr_cs_decoder_sanity_check(const struct vkr_cs_decoder *dec) |
||||
{ |
||||
const struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
assert(pool->buffer_count <= pool->buffer_max); |
||||
if (pool->buffer_count) { |
||||
assert(pool->buffers[pool->buffer_count - 1] <= pool->reset_to); |
||||
assert(pool->reset_to <= pool->cur); |
||||
assert(pool->cur <= pool->end); |
||||
} |
||||
|
||||
assert(dec->cur <= dec->end); |
||||
} |
||||
|
||||
static void |
||||
vkr_cs_decoder_gc_temp_pool(struct vkr_cs_decoder *dec) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
if (!pool->buffer_count) |
||||
return; |
||||
|
||||
/* free all but the last buffer */ |
||||
if (pool->buffer_count > 1) { |
||||
for (uint32_t i = 0; i < pool->buffer_count - 1; i++) |
||||
free(pool->buffers[i]); |
||||
|
||||
pool->buffers[0] = pool->buffers[pool->buffer_count - 1]; |
||||
pool->buffer_count = 1; |
||||
} |
||||
|
||||
pool->reset_to = pool->buffers[0]; |
||||
pool->cur = pool->buffers[0]; |
||||
|
||||
vkr_cs_decoder_sanity_check(dec); |
||||
} |
||||
|
||||
/**
|
||||
* Reset a decoder for reuse. |
||||
*/ |
||||
void |
||||
vkr_cs_decoder_reset(struct vkr_cs_decoder *dec) |
||||
{ |
||||
/* dec->fatal_error is sticky */ |
||||
|
||||
vkr_cs_decoder_gc_temp_pool(dec); |
||||
|
||||
dec->saved_state_count = 0; |
||||
dec->cur = NULL; |
||||
dec->end = NULL; |
||||
} |
||||
|
||||
bool |
||||
vkr_cs_decoder_push_state(struct vkr_cs_decoder *dec) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
struct vkr_cs_decoder_saved_state *saved; |
||||
|
||||
if (dec->saved_state_count >= ARRAY_SIZE(dec->saved_states)) |
||||
return false; |
||||
|
||||
saved = &dec->saved_states[dec->saved_state_count++]; |
||||
saved->cur = dec->cur; |
||||
saved->end = dec->end; |
||||
|
||||
saved->pool_buffer_count = pool->buffer_count; |
||||
saved->pool_reset_to = pool->reset_to; |
||||
/* avoid temp data corruption */ |
||||
pool->reset_to = pool->cur; |
||||
|
||||
vkr_cs_decoder_sanity_check(dec); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void |
||||
vkr_cs_decoder_pop_state(struct vkr_cs_decoder *dec) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
const struct vkr_cs_decoder_saved_state *saved; |
||||
|
||||
assert(dec->saved_state_count); |
||||
saved = &dec->saved_states[--dec->saved_state_count]; |
||||
dec->cur = saved->cur; |
||||
dec->end = saved->end; |
||||
|
||||
/* restore only if pool->reset_to points to the same buffer */ |
||||
if (pool->buffer_count == saved->pool_buffer_count) |
||||
pool->reset_to = saved->pool_reset_to; |
||||
|
||||
vkr_cs_decoder_sanity_check(dec); |
||||
} |
||||
|
||||
static uint32_t |
||||
next_array_size(uint32_t cur_size, uint32_t min_size) |
||||
{ |
||||
const uint32_t next_size = cur_size ? cur_size * 2 : min_size; |
||||
return next_size > cur_size ? next_size : 0; |
||||
} |
||||
|
||||
static size_t |
||||
next_buffer_size(size_t cur_size, size_t min_size, size_t need) |
||||
{ |
||||
size_t next_size = cur_size ? cur_size * 2 : min_size; |
||||
while (next_size < need) { |
||||
next_size *= 2; |
||||
if (!next_size) |
||||
return 0; |
||||
} |
||||
return next_size; |
||||
} |
||||
|
||||
static bool |
||||
vkr_cs_decoder_grow_temp_pool(struct vkr_cs_decoder *dec) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
const uint32_t buf_max = next_array_size(pool->buffer_max, 4); |
||||
if (!buf_max) |
||||
return false; |
||||
|
||||
uint8_t **bufs = realloc(pool->buffers, sizeof(*pool->buffers) * buf_max); |
||||
if (!bufs) |
||||
return false; |
||||
|
||||
pool->buffers = bufs; |
||||
pool->buffer_max = buf_max; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool |
||||
vkr_cs_decoder_alloc_temp_internal(struct vkr_cs_decoder *dec, size_t size) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
|
||||
if (pool->buffer_count >= pool->buffer_max) { |
||||
if (!vkr_cs_decoder_grow_temp_pool(dec)) |
||||
return false; |
||||
assert(pool->buffer_count < pool->buffer_max); |
||||
} |
||||
|
||||
const size_t cur_buf_size = |
||||
pool->buffer_count ? pool->end - pool->buffers[pool->buffer_count - 1] |
||||
: 0; |
||||
const size_t buf_size = next_buffer_size(cur_buf_size, 4096, size); |
||||
if (!buf_size) |
||||
return false; |
||||
|
||||
uint8_t *buf = malloc(buf_size); |
||||
if (!buf) |
||||
return false; |
||||
|
||||
pool->buffers[pool->buffer_count++] = buf; |
||||
pool->reset_to = buf; |
||||
pool->cur = buf; |
||||
pool->end = buf + buf_size; |
||||
|
||||
vkr_cs_decoder_sanity_check(dec); |
||||
|
||||
return true; |
||||
} |
@ -0,0 +1,287 @@ |
||||
/*
|
||||
* Copyright 2021 Google LLC |
||||
* SPDX-License-Identifier: MIT |
||||
*/ |
||||
|
||||
#ifndef VKR_CS_H |
||||
#define VKR_CS_H |
||||
|
||||
#include <assert.h> |
||||
#include <stdbool.h> |
||||
#include <stddef.h> |
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
|
||||
#include "util/u_hash_table.h" |
||||
#include "util/u_math.h" |
||||
|
||||
#include "vkr_object.h" |
||||
|
||||
struct iovec; |
||||
|
||||
struct vkr_cs_encoder { |
||||
bool *fatal_error; |
||||
|
||||
struct { |
||||
const struct iovec *iov; |
||||
int iov_count; |
||||
size_t offset; |
||||
size_t size; |
||||
|
||||
int cached_index; |
||||
size_t cached_offset; |
||||
} stream; |
||||
|
||||
size_t remaining_size; |
||||
int next_iov; |
||||
uint8_t *cur; |
||||
const uint8_t *end; |
||||
}; |
||||
|
||||
struct vkr_cs_decoder_saved_state { |
||||
const uint8_t *cur; |
||||
const uint8_t *end; |
||||
|
||||
uint32_t pool_buffer_count; |
||||
uint8_t *pool_reset_to; |
||||
}; |
||||
|
||||
struct vkr_cs_decoder_temp_pool { |
||||
uint8_t **buffers; |
||||
uint32_t buffer_count; |
||||
uint32_t buffer_max; |
||||
|
||||
uint8_t *reset_to; |
||||
|
||||
uint8_t *cur; |
||||
const uint8_t *end; |
||||
}; |
||||
|
||||
struct vkr_cs_decoder { |
||||
const struct util_hash_table_u64 *object_table; |
||||
|
||||
bool fatal_error; |
||||
struct vkr_cs_decoder_temp_pool temp_pool; |
||||
|
||||
struct vkr_cs_decoder_saved_state saved_states[1]; |
||||
uint32_t saved_state_count; |
||||
|
||||
const uint8_t *cur; |
||||
const uint8_t *end; |
||||
}; |
||||
|
||||
static inline void |
||||
vkr_cs_encoder_init(struct vkr_cs_encoder *enc, bool *fatal_error) |
||||
{ |
||||
memset(enc, 0, sizeof(*enc)); |
||||
enc->fatal_error = fatal_error; |
||||
} |
||||
|
||||
static inline void |
||||
vkr_cs_encoder_set_fatal(const struct vkr_cs_encoder *enc) |
||||
{ |
||||
*enc->fatal_error = true; |
||||
} |
||||
|
||||
void |
||||
vkr_cs_encoder_set_stream(struct vkr_cs_encoder *enc, |
||||
const struct iovec *iov, |
||||
int iov_count, |
||||
size_t offset, |
||||
size_t size); |
||||
|
||||
void |
||||
vkr_cs_encoder_seek_stream(struct vkr_cs_encoder *enc, size_t pos); |
||||
|
||||
void |
||||
vkr_cs_encoder_write_internal(struct vkr_cs_encoder *enc, |
||||
size_t size, |
||||
const void *val, |
||||
size_t val_size); |
||||
|
||||
static inline void |
||||
vkr_cs_encoder_write(struct vkr_cs_encoder *enc, |
||||
size_t size, |
||||
const void *val, |
||||
size_t val_size) |
||||
{ |
||||
assert(val_size <= size); |
||||
|
||||
if (unlikely(size > (size_t)(enc->end - enc->cur))) { |
||||
vkr_cs_encoder_write_internal(enc, size, val, val_size); |
||||
return; |
||||
} |
||||
|
||||
/* we should not rely on the compiler to optimize away memcpy... */ |
||||
memcpy(enc->cur, val, val_size); |
||||
enc->cur += size; |
||||
} |
||||
|
||||
void |
||||
vkr_cs_decoder_init(struct vkr_cs_decoder *dec, |
||||
const struct util_hash_table_u64 *object_table); |
||||
|
||||
void |
||||
vkr_cs_decoder_fini(struct vkr_cs_decoder *dec); |
||||
|
||||
void |
||||
vkr_cs_decoder_reset(struct vkr_cs_decoder *dec); |
||||
|
||||
static inline void |
||||
vkr_cs_decoder_set_fatal(const struct vkr_cs_decoder *dec) |
||||
{ |
||||
((struct vkr_cs_decoder *)dec)->fatal_error = true; |
||||
} |
||||
|
||||
static inline bool |
||||
vkr_cs_decoder_get_fatal(const struct vkr_cs_decoder *dec) |
||||
{ |
||||
return dec->fatal_error; |
||||
} |
||||
|
||||
static inline void |
||||
vkr_cs_decoder_set_stream(struct vkr_cs_decoder *dec, |
||||
const void *data, |
||||
size_t size) |
||||
{ |
||||
dec->cur = data; |
||||
dec->end = dec->cur + size; |
||||
} |
||||
|
||||
static inline bool |
||||
vkr_cs_decoder_has_command(const struct vkr_cs_decoder *dec) |
||||
{ |
||||
return dec->cur < dec->end; |
||||
} |
||||
|
||||
bool |
||||
vkr_cs_decoder_push_state(struct vkr_cs_decoder *dec); |
||||
|
||||
void |
||||
vkr_cs_decoder_pop_state(struct vkr_cs_decoder *dec); |
||||
|
||||
static inline bool |
||||
vkr_cs_decoder_peek_internal(const struct vkr_cs_decoder *dec, |
||||
size_t size, |
||||
void *val, |
||||
size_t val_size) |
||||
{ |
||||
assert(val_size <= size); |
||||
|
||||
if (unlikely(size > (size_t)(dec->end - dec->cur))) { |
||||
vkr_cs_decoder_set_fatal(dec); |
||||
memset(val, 0, val_size); |
||||
return false; |
||||
} |
||||
|
||||
/* we should not rely on the compiler to optimize away memcpy... */ |
||||
memcpy(val, dec->cur, val_size); |
||||
return true; |
||||
} |
||||
|
||||
static inline void |
||||
vkr_cs_decoder_read(struct vkr_cs_decoder *dec, |
||||
size_t size, |
||||
void *val, |
||||
size_t val_size) |
||||
{ |
||||
if (vkr_cs_decoder_peek_internal(dec, size, val, val_size)) |
||||
dec->cur += size; |
||||
} |
||||
|
||||
static inline void |
||||
vkr_cs_decoder_peek(const struct vkr_cs_decoder *dec, |
||||
size_t size, |
||||
void *val, |
||||
size_t val_size) |
||||
{ |
||||
vkr_cs_decoder_peek_internal(dec, size, val, val_size); |
||||
} |
||||
|
||||
static inline struct vkr_object * |
||||
vkr_cs_decoder_lookup_object(const struct vkr_cs_decoder *dec, |
||||
vkr_object_id id) |
||||
{ |
||||
struct vkr_object *obj; |
||||
|
||||
if (!id) |
||||
return NULL; |
||||
|
||||
obj = util_hash_table_get_u64( |
||||
(struct util_hash_table_u64 *)dec->object_table, id); |
||||
if (!obj) |
||||
vkr_cs_decoder_set_fatal(dec); |
||||
|
||||
return obj; |
||||
} |
||||
|
||||
static inline void |
||||
vkr_cs_decoder_reset_temp_pool(struct vkr_cs_decoder *dec) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
pool->cur = pool->reset_to; |
||||
} |
||||
|
||||
bool |
||||
vkr_cs_decoder_alloc_temp_internal(struct vkr_cs_decoder *dec, size_t size); |
||||
|
||||
static inline void * |
||||
vkr_cs_decoder_alloc_temp(struct vkr_cs_decoder *dec, size_t size) |
||||
{ |
||||
struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool; |
||||
|
||||
/* align to 64-bit */ |
||||
size = align(size, 8); |
||||
if (unlikely(size > (size_t)(pool->end - pool->cur))) { |
||||
if (!vkr_cs_decoder_alloc_temp_internal(dec, size)) { |
||||
vkr_cs_decoder_set_fatal(dec); |
||||
return NULL; |
||||
} |
||||
assert(size <= (size_t)(pool->end - pool->cur)); |
||||
} |
||||
|
||||
void *ptr = pool->cur; |
||||
pool->cur += size; |
||||
return ptr; |
||||
} |
||||
|
||||
static inline bool |
||||
vkr_cs_handle_indirect_id(VkObjectType type) |
||||
{ |
||||
/* Dispatchable handles may or may not have enough bits to store
|
||||
* vkr_object_id. Non-dispatchable handles always have enough bits to |
||||
* store vkr_object_id. |
||||
* |
||||
* This should compile to a constant after inlining. |
||||
*/ |
||||
switch (type) { |
||||
case VK_OBJECT_TYPE_INSTANCE: |
||||
case VK_OBJECT_TYPE_PHYSICAL_DEVICE: |
||||
case VK_OBJECT_TYPE_DEVICE: |
||||
case VK_OBJECT_TYPE_QUEUE: |
||||
case VK_OBJECT_TYPE_COMMAND_BUFFER: |
||||
return sizeof(VkInstance) < sizeof(vkr_object_id); |
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
static inline vkr_object_id |
||||
vkr_cs_handle_load_id(const void **handle, VkObjectType type) |
||||
{ |
||||
const vkr_object_id *p = vkr_cs_handle_indirect_id(type) |
||||
? *(const vkr_object_id **)handle |
||||
: (const vkr_object_id *)handle; |
||||
return *p; |
||||
} |
||||
|
||||
static inline void |
||||
vkr_cs_handle_store_id(void **handle, vkr_object_id id, VkObjectType type) |
||||
{ |
||||
vkr_object_id *p = vkr_cs_handle_indirect_id(type) |
||||
? *(vkr_object_id **)handle |
||||
: (vkr_object_id *)handle; |
||||
*p = id; |
||||
} |
||||
|
||||
#endif /* VKR_CS_H */ |
@ -0,0 +1,55 @@ |
||||
/*
|
||||
* Copyright 2021 Google LLC |
||||
* SPDX-License-Identifier: MIT |
||||
*/ |
||||
|
||||
#ifndef VKR_OBJECT_H |
||||
#define VKR_OBJECT_H |
||||
|
||||
#include <stdbool.h> |
||||
#include <stdint.h> |
||||
|
||||
#include "venus-protocol/vulkan.h" |
||||
|
||||
typedef uint64_t vkr_object_id; |
||||
|
||||
/* base class for all objects */ |
||||
struct vkr_object { |
||||
VkObjectType type; |
||||
vkr_object_id id; |
||||
|
||||
union { |
||||
uint64_t u64; |
||||
|
||||
VkInstance instance; |
||||
VkPhysicalDevice physical_device; |
||||
VkDevice device; |
||||
VkQueue queue; |
||||
VkCommandBuffer command_buffer; |
||||
|
||||
VkBuffer buffer; |
||||
VkImage image; |
||||
VkSemaphore semaphore; |
||||
VkFence fence; |
||||
VkDeviceMemory device_memory; |
||||
VkEvent event; |
||||
VkQueryPool query_pool; |
||||
VkBufferView buffer_view; |
||||
VkImageView image_view; |
||||
VkShaderModule shader_module; |
||||
VkPipelineCache pipeline_cache; |
||||
VkPipelineLayout pipeline_layout; |
||||
VkPipeline pipeline; |
||||
VkRenderPass render_pass; |
||||
VkDescriptorSetLayout descriptor_set_layout; |
||||
VkSampler sampler; |
||||
VkDescriptorSet descriptor_set; |
||||
VkDescriptorPool descriptor_pool; |
||||
VkFramebuffer framebuffer; |
||||
VkCommandPool command_pool; |
||||
VkSamplerYcbcrConversion sampler_ycbcr_conversion; |
||||
VkDescriptorUpdateTemplate descriptor_update_template; |
||||
} handle; |
||||
}; |
||||
|
||||
#endif /* VKR_OBJECT_H */ |
Loading…
Reference in new issue