diff options
author | Chia-I Wu <[email protected]> | 2019-01-28 14:33:20 -0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2019-03-11 10:02:13 -0700 |
commit | f59c3814232d5735aba6bed9de506e59321e4170 (patch) | |
tree | eff029331d6d393f1cfbf9eaaf378fa8c1ce8c0a /src/freedreno/vulkan/tu_cs.c | |
parent | 5c63fc626f98def10d20971161e672f9e7cd341c (diff) |
turnip: add tu_cs_mode
Add tu_cs_mode and TU_CS_MODE_EXTERNAL. When in
TU_CS_MODE_EXTERNAL, tu_cs wraps an external buffer and can not
grow.
This also moves tu_cs* up in tu_private.h, such that other structs
can embed tu_cs_entry.
Diffstat (limited to 'src/freedreno/vulkan/tu_cs.c')
-rw-r--r-- | src/freedreno/vulkan/tu_cs.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/src/freedreno/vulkan/tu_cs.c b/src/freedreno/vulkan/tu_cs.c index f4bec106934..226abb05510 100644 --- a/src/freedreno/vulkan/tu_cs.c +++ b/src/freedreno/vulkan/tu_cs.c @@ -31,10 +31,24 @@ tu_cs_init(struct tu_cs *cs, uint32_t initial_size) { memset(cs, 0, sizeof(*cs)); + cs->mode = TU_CS_MODE_GROW; cs->next_bo_size = initial_size; } /** + * Initialize a command stream as a wrapper to an external buffer. + */ +void +tu_cs_init_external(struct tu_cs *cs, uint32_t *start, uint32_t *end) +{ + memset(cs, 0, sizeof(*cs)); + + cs->mode = TU_CS_MODE_EXTERNAL; + cs->start = cs->reserved_end = cs->cur = start; + cs->end = end; +} + +/** * Finish and release all resources owned by a command stream. */ void @@ -96,6 +110,9 @@ tu_cs_is_empty(const struct tu_cs *cs) static VkResult tu_cs_add_bo(struct tu_device *dev, struct tu_cs *cs, uint32_t size) { + /* no BO for TU_CS_MODE_EXTERNAL */ + assert(cs->mode != TU_CS_MODE_EXTERNAL); + /* no dangling command packet */ assert(tu_cs_is_empty(cs)); @@ -142,6 +159,9 @@ tu_cs_add_bo(struct tu_device *dev, struct tu_cs *cs, uint32_t size) static VkResult tu_cs_reserve_entry(struct tu_device *dev, struct tu_cs *cs) { + /* entries are only for TU_CS_MODE_GROW */ + assert(cs->mode == TU_CS_MODE_GROW); + /* grow cs->entries if needed */ if (cs->entry_count == cs->entry_capacity) { uint32_t new_capacity = MAX2(4, cs->entry_capacity * 2); @@ -164,6 +184,9 @@ tu_cs_reserve_entry(struct tu_device *dev, struct tu_cs *cs) static void tu_cs_add_entry(struct tu_cs *cs) { + /* entries are only for TU_CS_MODE_GROW */ + assert(cs->mode == TU_CS_MODE_GROW); + /* disallow empty entry */ assert(!tu_cs_is_empty(cs)); @@ -200,12 +223,13 @@ tu_cs_begin(struct tu_cs *cs) void tu_cs_end(struct tu_cs *cs) { - if (!tu_cs_is_empty(cs)) + if (cs->mode == TU_CS_MODE_GROW && !tu_cs_is_empty(cs)) tu_cs_add_entry(cs); } /** * Reserve space from a command stream for \a reserved_size uint32_t values. + * This never fails when \a cs has mode TU_CS_MODE_EXTERNAL. */ VkResult tu_cs_reserve_space(struct tu_device *dev, @@ -213,6 +237,11 @@ tu_cs_reserve_space(struct tu_device *dev, uint32_t reserved_size) { if (tu_cs_get_space(cs) < reserved_size) { + if (cs->mode == TU_CS_MODE_EXTERNAL) { + unreachable("cannot grow external buffer"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + /* add an entry for the exiting command packets */ if (!tu_cs_is_empty(cs)) tu_cs_add_entry(cs); @@ -228,8 +257,12 @@ tu_cs_reserve_space(struct tu_device *dev, assert(tu_cs_get_space(cs) >= reserved_size); cs->reserved_end = cs->cur + reserved_size; - /* reserve an entry for the next call to this function or tu_cs_end */ - return tu_cs_reserve_entry(dev, cs); + if (cs->mode == TU_CS_MODE_GROW) { + /* reserve an entry for the next call to this function or tu_cs_end */ + return tu_cs_reserve_entry(dev, cs); + } + + return VK_SUCCESS; } /** @@ -239,6 +272,12 @@ tu_cs_reserve_space(struct tu_device *dev, void tu_cs_reset(struct tu_device *dev, struct tu_cs *cs) { + if (cs->mode == TU_CS_MODE_EXTERNAL) { + assert(!cs->bo_count && !cs->entry_count); + cs->reserved_end = cs->cur = cs->start; + return; + } + for (uint32_t i = 0; i + 1 < cs->bo_count; ++i) { tu_bo_finish(dev, cs->bos[i]); free(cs->bos[i]); |