1 /*
2 * Copyright © 2018 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "anv_private.h"
25 #include "test_common.h"
26
27 void state_pool_padding_test(void);
28
state_pool_padding_test(void)29 void state_pool_padding_test(void)
30 {
31 struct anv_physical_device physical_device = {};
32 struct anv_device device = {};
33 struct anv_state_pool state_pool;
34 const uint32_t _1Gb = 1024 * 1024 * 1024;
35
36 test_device_info_init(&physical_device.info);
37 anv_device_set_physical(&device, &physical_device);
38 device.kmd_backend = anv_kmd_backend_get(INTEL_KMD_TYPE_STUB);
39 pthread_mutex_init(&device.mutex, NULL);
40 anv_bo_cache_init(&device.bo_cache, &device);
41 anv_state_pool_init(&state_pool, &device,
42 &(struct anv_state_pool_params) {
43 .name = "test",
44 .base_address = 4096,
45 .start_offset = 0,
46 .block_size = 4096,
47 .max_size = _1Gb,
48 });
49
50 /* Get the size of the underlying block_pool */
51 struct anv_block_pool *bp = &state_pool.block_pool;
52 uint64_t pool_size = bp->size;
53
54 /* Grab one so the pool has some initial usage */
55 anv_state_pool_alloc(&state_pool, 16, 16);
56
57 /* Grab a state that is the size of the initial allocation */
58 struct anv_state state = anv_state_pool_alloc(&state_pool, pool_size, 16);
59
60 /* The pool must have grown */
61 ASSERT(bp->size > pool_size);
62
63 /* And the state must have been allocated at the end of the original size */
64 ASSERT(state.offset == pool_size);
65
66 /* A new allocation that fits into the returned empty space should have an
67 * offset within the original pool size
68 */
69 state = anv_state_pool_alloc(&state_pool, 4096, 16);
70 ASSERT(state.offset + state.alloc_size <= pool_size);
71
72 /* We should be able to allocate pool->block_size'd chunks in the returned area
73 */
74 int left_chunks = pool_size / 4096 - 2;
75 for (int i = 0; i < left_chunks; i++) {
76 state = anv_state_pool_alloc(&state_pool, 4096, 16);
77 ASSERT(state.offset + state.alloc_size <= pool_size);
78 }
79
80 /* Now the next chunk to be allocated should make the pool grow again */
81 pool_size = bp->size;
82 state = anv_state_pool_alloc(&state_pool, 4096, 16);
83 ASSERT(bp->size > pool_size);
84 ASSERT(state.offset == pool_size);
85
86 anv_state_pool_finish(&state_pool);
87 anv_bo_cache_finish(&device.bo_cache);
88 pthread_mutex_destroy(&device.mutex);
89 }
90