mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-7570 Implemented ring buffer. Added lazy implicit initialization for dynamic arrays. (#451)
This commit is contained in:
@@ -8,25 +8,48 @@ void* CARR_array_alloc(size_t elem_size, size_t capacity) {
|
||||
if (pvec == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pvec->elem_size = elem_size;
|
||||
pvec->size = 0;
|
||||
pvec->capacity = capacity;
|
||||
return pvec->data;
|
||||
}
|
||||
|
||||
void* CARR_array_realloc(CARR_array_t* vec, size_t new_capacity) {
|
||||
void* CARR_array_realloc(CARR_array_t* vec, size_t elem_size, size_t new_capacity) {
|
||||
if (vec->capacity == new_capacity) {
|
||||
return vec->data;
|
||||
}
|
||||
CARR_array_t* new_vec =
|
||||
(CARR_array_t*)((char*)CARR_array_alloc(vec->elem_size, new_capacity) - offsetof(CARR_array_t, data));
|
||||
(CARR_array_t*)((char*)CARR_array_alloc(elem_size, new_capacity) - offsetof(CARR_array_t, data));
|
||||
if (new_vec == NULL) {
|
||||
return NULL;
|
||||
return vec == NULL ? NULL : vec->data;
|
||||
}
|
||||
new_vec->capacity = new_capacity;
|
||||
new_vec->size = MIN(vec->size, new_capacity);
|
||||
new_vec->elem_size = vec->elem_size;
|
||||
memcpy(new_vec->data, vec->data, new_vec->size*new_vec->elem_size);
|
||||
memcpy(new_vec->data, vec->data, new_vec->size*elem_size);
|
||||
free(vec);
|
||||
return new_vec->data;
|
||||
}
|
||||
|
||||
void* CARR_ring_buffer_realloc(CARR_ring_buffer_t* buf, size_t elem_size, size_t new_capacity) {
|
||||
if (buf != NULL && buf->capacity == new_capacity) {
|
||||
return buf->data;
|
||||
}
|
||||
CARR_ring_buffer_t* new_buf =
|
||||
(CARR_ring_buffer_t*) malloc(elem_size * new_capacity + offsetof(CARR_ring_buffer_t, data));
|
||||
if (new_buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new_buf->head = new_buf->tail = 0;
|
||||
new_buf->capacity = new_capacity;
|
||||
if (buf != NULL) {
|
||||
if (buf->tail > buf->head) {
|
||||
new_buf->tail = buf->tail - buf->head;
|
||||
memcpy(new_buf->data, buf->data + buf->head*elem_size, new_buf->tail*elem_size);
|
||||
} else if (buf->tail < buf->head) {
|
||||
new_buf->tail = buf->capacity + buf->tail - buf->head;
|
||||
memcpy(new_buf->data, buf->data + buf->head*elem_size, (buf->capacity-buf->head)*elem_size);
|
||||
memcpy(new_buf->data + (new_buf->tail-buf->tail)*elem_size, buf->data, buf->tail*elem_size);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
return new_buf->data;
|
||||
}
|
||||
|
||||
@@ -1,48 +1,63 @@
|
||||
#ifndef C_ARRAY_UTIL_H
|
||||
#define C_ARRAY_UTIL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define ARRAY_CAPACITY_MULT 2
|
||||
// C_ARRAY_UTIL_ALLOCATION_FAILED is called when allocation fails.
|
||||
// Default implementation calls abort().
|
||||
// Functions that can call C_ARRAY_UTIL_ALLOCATION_FAILED explicitly state
|
||||
// this in the documentation. Functions with *_TRY_* return NULL on failure.
|
||||
#ifndef C_ARRAY_UTIL_ALLOCATION_FAILED
|
||||
#include <stdlib.h>
|
||||
#define C_ARRAY_UTIL_ALLOCATION_FAILED() abort()
|
||||
#endif
|
||||
|
||||
#define ARRAY_CAPACITY_GROW(C) (((C) * 3 + 1) / 2) // 1.5 multiplier
|
||||
#define ARRAY_DEFAULT_CAPACITY 10
|
||||
typedef struct {
|
||||
size_t elem_size;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
char data[];
|
||||
} CARR_array_t;
|
||||
|
||||
void* CARR_array_alloc(size_t elem_size, size_t capacity);
|
||||
void* CARR_array_realloc(CARR_array_t* vec, size_t new_capacity);
|
||||
void* CARR_array_realloc(CARR_array_t* vec, size_t elem_size, size_t new_capacity);
|
||||
|
||||
typedef struct {
|
||||
size_t head;
|
||||
size_t tail;
|
||||
size_t capacity;
|
||||
char data[];
|
||||
} CARR_ring_buffer_t;
|
||||
|
||||
void* CARR_ring_buffer_realloc(CARR_ring_buffer_t* buf, size_t elem_size, size_t new_capacity);
|
||||
|
||||
/**
|
||||
* Allocate array
|
||||
* Allocate array. Returns NULL on allocation failure.
|
||||
* @param T type of elements
|
||||
* @param CAPACITY capacity of the array
|
||||
*/
|
||||
#define ARRAY_ALLOC(T, CAPACITY) (T*)CARR_array_alloc(sizeof(T), CAPACITY)
|
||||
|
||||
|
||||
#define ARRAY_T(P) (CARR_array_t *)((char*)P - offsetof(CARR_array_t, data))
|
||||
#define ARRAY_T(P) ((CARR_array_t *)((P) == NULL ? NULL : (char*)(P) - offsetof(CARR_array_t, data)))
|
||||
|
||||
/**
|
||||
* @param P pointer to the first data element of the array
|
||||
* @return size of the array
|
||||
*/
|
||||
#define ARRAY_SIZE(P) (ARRAY_T(P))->size
|
||||
#define ARRAY_SIZE(P) ((P) == NULL ? (size_t) 0 : (ARRAY_T(P))->size)
|
||||
|
||||
/**
|
||||
* @param P pointer to the first data element of the array
|
||||
* @return capacity of the array
|
||||
*/
|
||||
#define ARRAY_CAPACITY(P) (ARRAY_T(P))->capacity
|
||||
#define ARRAY_CAPACITY(P) ((P) == NULL ? (size_t) 0 : (ARRAY_T(P))->capacity)
|
||||
|
||||
/**
|
||||
* @param P pointer to the first data element of the array
|
||||
* @return last element in the array
|
||||
*/
|
||||
#define ARRAY_LAST(P) (P[(ARRAY_T(P))->size - 1])
|
||||
#define ARRAY_LAST(P) ((P)[ARRAY_SIZE(P) - 1])
|
||||
|
||||
/**
|
||||
* Deallocate the vector
|
||||
@@ -56,7 +71,7 @@ void* CARR_array_realloc(CARR_array_t* vec, size_t new_capacity);
|
||||
* @param F function to apply
|
||||
*/
|
||||
#define ARRAY_APPLY(P, F) do { \
|
||||
for (uint32_t _i = 0; _i < ARRAY_SIZE(P); _i++) F(&(P[_i])); \
|
||||
for (size_t _i = 0; _i < ARRAY_SIZE(P); _i++) F(&((P)[_i])); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
@@ -65,7 +80,7 @@ void* CARR_array_realloc(CARR_array_t* vec, size_t new_capacity);
|
||||
* @param F function to apply
|
||||
*/
|
||||
#define ARRAY_APPLY_LEADING(P, F, ...) do { \
|
||||
for (uint32_t _i = 0; _i < ARRAY_SIZE(P); _i++) F(&(P[_i]), __VA_ARGS__); \
|
||||
for (size_t _i = 0; _i < ARRAY_SIZE(P); _i++) F(&((P)[_i]), __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
@@ -74,29 +89,148 @@ void* CARR_array_realloc(CARR_array_t* vec, size_t new_capacity);
|
||||
* @param F function to apply
|
||||
*/
|
||||
#define ARRAY_APPLY_TRAILING(P, F, ...) do { \
|
||||
for (uint32_t _i = 0; _i < ARRAY_SIZE(P); _i++) F(__VA_ARGS__, &(P[_i])); \
|
||||
for (size_t _i = 0; _i < ARRAY_SIZE(P); _i++) F(__VA_ARGS__, &((P)[_i])); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Shrink capacity of the array to its size
|
||||
* @param PP pointer to the pointer to the first data element of the array
|
||||
* Ensure array capacity. Implicitly initializes when array is NULL.
|
||||
* On allocation failure, array is unchanged.
|
||||
* @param P pointer to the first data element of the array
|
||||
* @param CAPACITY required capacity of the array
|
||||
*/
|
||||
#define ARRAY_SHRINK_TO_FIT(PP) do { \
|
||||
*PP = CARR_array_realloc(ARRAY_T(*PP), ARRAY_SIZE(*PP)); \
|
||||
#define ARRAY_TRY_ENSURE_CAPACITY(P, CAPACITY) do { \
|
||||
if ((P) == NULL) { \
|
||||
if ((CAPACITY) > 0) (P) = CARR_array_alloc(sizeof((P)[0]), CAPACITY); \
|
||||
} else if (ARRAY_CAPACITY(P) < (CAPACITY)) { \
|
||||
(P) = CARR_array_realloc(ARRAY_T(P), sizeof((P)[0]), CAPACITY); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Add element to the end of the array
|
||||
* @param PP pointer to the pointer to the first data element of the array
|
||||
* Ensure array capacity. Implicitly initializes when array is NULL.
|
||||
* On allocation failure, C_ARRAY_UTIL_ALLOCATION_FAILED is called.
|
||||
* @param P pointer to the first data element of the array
|
||||
* @param CAPACITY required capacity of the array
|
||||
*/
|
||||
#define ARRAY_PUSH_BACK(PP, D) do { \
|
||||
if (ARRAY_SIZE(*PP) >= ARRAY_CAPACITY(*PP)) { \
|
||||
*PP = CARR_array_realloc(ARRAY_T(*PP), ARRAY_SIZE(*PP)*ARRAY_CAPACITY_MULT);\
|
||||
} \
|
||||
*(*PP + ARRAY_SIZE(*PP)) = (D); \
|
||||
ARRAY_SIZE(*PP)++; \
|
||||
#define ARRAY_ENSURE_CAPACITY(P, CAPACITY) do { \
|
||||
ARRAY_TRY_ENSURE_CAPACITY(P, CAPACITY); \
|
||||
if (ARRAY_CAPACITY(P) < (CAPACITY)) C_ARRAY_UTIL_ALLOCATION_FAILED(); \
|
||||
} while(0)
|
||||
|
||||
#define SARRAY_COUNT_OF(STATIC_ARRAY) (sizeof(STATIC_ARRAY)/sizeof(STATIC_ARRAY[0]))
|
||||
/**
|
||||
* Shrink capacity of the array to its size.
|
||||
* On allocation failure, array is unchanged.
|
||||
* @param P pointer to the first data element of the array
|
||||
*/
|
||||
#define ARRAY_SHRINK_TO_FIT(P) do { \
|
||||
if ((P) != NULL) { \
|
||||
(P) = CARR_array_realloc(ARRAY_T(P), sizeof((P)[0]), ARRAY_SIZE(P)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ARRAY_RESIZE_IMPL(P, SIZE, ...) do { \
|
||||
if ((P) != NULL || (SIZE) > 0) { \
|
||||
ARRAY_ENSURE_CAPACITY(P, SIZE); \
|
||||
if ((P) != NULL && (ARRAY_T(P))->capacity >= (SIZE)) { \
|
||||
(ARRAY_T(P))->size = (SIZE); \
|
||||
} __VA_ARGS__ \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Resize an array. Implicitly initializes when array is NULL.
|
||||
* On allocation failure, array is unchanged.
|
||||
* @param P pointer to the first data element of the array
|
||||
* @param SIZE required size of the array
|
||||
*/
|
||||
#define ARRAY_TRY_RESIZE(P, SIZE) ARRAY_RESIZE_IMPL(P, SIZE, )
|
||||
|
||||
/**
|
||||
* Resize an array. Implicitly initializes when array is NULL.
|
||||
* On allocation failure, C_ARRAY_UTIL_ALLOCATION_FAILED is called.
|
||||
* @param P pointer to the first data element of the array
|
||||
* @param SIZE required size of the array
|
||||
*/
|
||||
#define ARRAY_RESIZE(P, SIZE) ARRAY_RESIZE_IMPL(P, SIZE, else if ((SIZE) > 0) C_ARRAY_UTIL_ALLOCATION_FAILED();)
|
||||
|
||||
/**
|
||||
* Add element to the end of the array. Implicitly initializes when array is NULL.
|
||||
* On allocation failure, C_ARRAY_UTIL_ALLOCATION_FAILED is called.
|
||||
* @param P pointer to the first data element of the array
|
||||
*/
|
||||
#define ARRAY_PUSH_BACK(P, ...) do { \
|
||||
if ((P) == NULL) { \
|
||||
(P) = CARR_array_alloc(sizeof((P)[0]), ARRAY_DEFAULT_CAPACITY); \
|
||||
} else if (ARRAY_SIZE(P) >= ARRAY_CAPACITY(P)) { \
|
||||
(P) = CARR_array_realloc(ARRAY_T(P), sizeof((P)[0]), ARRAY_CAPACITY_GROW(ARRAY_SIZE(P))); \
|
||||
} \
|
||||
if (ARRAY_SIZE(P) >= ARRAY_CAPACITY(P)) C_ARRAY_UTIL_ALLOCATION_FAILED(); \
|
||||
*((P) + ARRAY_SIZE(P)) = (__VA_ARGS__); \
|
||||
(ARRAY_T(P))->size++; \
|
||||
} while(0)
|
||||
|
||||
#define SARRAY_COUNT_OF(STATIC_ARRAY) (sizeof(STATIC_ARRAY)/sizeof((STATIC_ARRAY)[0]))
|
||||
|
||||
#define RING_BUFFER_T(P) ((CARR_ring_buffer_t *)((P) == NULL ? NULL : (char*)(P) - offsetof(CARR_ring_buffer_t, data)))
|
||||
|
||||
/**
|
||||
* @param P pointer to the first data element of the ring buffer
|
||||
* @return size of the ring buffer
|
||||
*/
|
||||
#define RING_BUFFER_SIZE(P) ((P) == NULL ? (size_t) 0 : \
|
||||
(RING_BUFFER_T(P)->capacity + RING_BUFFER_T(P)->tail - RING_BUFFER_T(P)->head) % RING_BUFFER_T(P)->capacity)
|
||||
|
||||
/**
|
||||
* @param P pointer to the first data element of the ring buffer
|
||||
* @return capacity of the ring buffer
|
||||
*/
|
||||
#define RING_BUFFER_CAPACITY(P) ((P) == NULL ? (size_t) 0 : RING_BUFFER_T(P)->capacity)
|
||||
|
||||
/**
|
||||
* Add element to the end of the ring buffer. Implicitly initializes when buffer is NULL.
|
||||
* On allocation failure, C_ARRAY_UTIL_ALLOCATION_FAILED is called.
|
||||
* @param P pointer to the first data element of the buffer
|
||||
*/
|
||||
#define RING_BUFFER_PUSH(P, ...) RING_BUFFER_PUSH_CUSTOM(P, (P)[tail] = (__VA_ARGS__);)
|
||||
#define RING_BUFFER_PUSH_CUSTOM(P, ...) do { \
|
||||
size_t head, tail, new_tail; \
|
||||
if ((P) == NULL) { \
|
||||
(P) = CARR_ring_buffer_realloc(NULL, sizeof((P)[0]), ARRAY_DEFAULT_CAPACITY); \
|
||||
if ((P) == NULL) C_ARRAY_UTIL_ALLOCATION_FAILED(); \
|
||||
head = tail = 0; \
|
||||
new_tail = 1; \
|
||||
} else { \
|
||||
head = RING_BUFFER_T(P)->head; \
|
||||
tail = RING_BUFFER_T(P)->tail; \
|
||||
new_tail = (tail + 1) % RING_BUFFER_T(P)->capacity; \
|
||||
if (new_tail == head) { \
|
||||
(P) = CARR_ring_buffer_realloc(RING_BUFFER_T(P), sizeof(P[0]), ARRAY_CAPACITY_GROW(RING_BUFFER_T(P)->capacity)); \
|
||||
if ((P) == NULL) C_ARRAY_UTIL_ALLOCATION_FAILED(); \
|
||||
head = 0; \
|
||||
tail = RING_BUFFER_T(P)->tail; \
|
||||
new_tail = RING_BUFFER_T(P)->tail + 1; \
|
||||
} \
|
||||
} \
|
||||
__VA_ARGS__ \
|
||||
RING_BUFFER_T(P)->tail = new_tail; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Get pointer to the first element of the ring buffer.
|
||||
* @param P pointer to the first data element of the buffer
|
||||
*/
|
||||
#define RING_BUFFER_PEEK(P) ((P) == NULL || RING_BUFFER_T(P)->head == RING_BUFFER_T(P)->tail ? NULL : &(P)[RING_BUFFER_T(P)->head])
|
||||
|
||||
/**
|
||||
* Move beginning of the ring buffer forward (remove first element).
|
||||
* @param P pointer to the first data element of the buffer
|
||||
*/
|
||||
#define RING_BUFFER_POP(P) RING_BUFFER_T(P)->head = (RING_BUFFER_T(P)->head + 1) % RING_BUFFER_T(P)->capacity
|
||||
|
||||
/**
|
||||
* Deallocate the ring buffer
|
||||
* @param P pointer to the first data element of the buffer
|
||||
*/
|
||||
#define RING_BUFFER_FREE(P) free(RING_BUFFER_T(P))
|
||||
|
||||
#endif // CARRAYUTILS_H
|
||||
|
||||
@@ -241,13 +241,13 @@ static jboolean VK_InitGraphicsEnvironment(PFN_vkGetInstanceProcAddr vkGetInstan
|
||||
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, " %s", (char *) extensions[i].extensionName)
|
||||
}
|
||||
|
||||
pchar* enabledLayers = ARRAY_ALLOC(pchar, MAX_ENABLED_LAYERS);
|
||||
pchar* enabledExtensions = ARRAY_ALLOC(pchar, MAX_ENABLED_EXTENSIONS);
|
||||
pchar* enabledLayers = NULL;
|
||||
pchar* enabledExtensions = NULL;
|
||||
void *pNext = NULL;
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
ARRAY_PUSH_BACK(&enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
ARRAY_PUSH_BACK(enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
ARRAY_PUSH_BACK(&enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
ARRAY_PUSH_BACK(enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
|
||||
// Check required layers & extensions.
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(enabledExtensions); i++) {
|
||||
@@ -300,8 +300,8 @@ static jboolean VK_InitGraphicsEnvironment(PFN_vkGetInstanceProcAddr vkGetInstan
|
||||
}
|
||||
|
||||
if (foundDebugLayer && foundDebugExt) {
|
||||
ARRAY_PUSH_BACK(&enabledLayers, VALIDATION_LAYER_NAME);
|
||||
ARRAY_PUSH_BACK(&enabledExtensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
ARRAY_PUSH_BACK(enabledLayers, VALIDATION_LAYER_NAME);
|
||||
ARRAY_PUSH_BACK(enabledExtensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
pNext = &features;
|
||||
} else {
|
||||
J2dRlsTraceLn2(J2D_TRACE_WARNING, "Vulkan: %s and %s are not supported",
|
||||
@@ -561,7 +561,7 @@ static jboolean VK_FindDevices() {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
ARRAY_PUSH_BACK(&deviceEnabledExtensions, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
ARRAY_PUSH_BACK(deviceEnabledExtensions, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
|
||||
// Validation layer
|
||||
#ifdef DEBUG
|
||||
@@ -569,7 +569,7 @@ static jboolean VK_FindDevices() {
|
||||
for (uint32_t j = 0; j < layerCount; j++) {
|
||||
if (strcmp(VALIDATION_LAYER_NAME, layers[j].layerName) == 0) {
|
||||
validationLayerNotSupported = 0;
|
||||
ARRAY_PUSH_BACK(&deviceEnabledLayers, VALIDATION_LAYER_NAME);
|
||||
ARRAY_PUSH_BACK(deviceEnabledLayers, VALIDATION_LAYER_NAME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -584,7 +584,7 @@ static jboolean VK_FindDevices() {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
ARRAY_PUSH_BACK(&geInstance->devices,
|
||||
ARRAY_PUSH_BACK(geInstance->devices,
|
||||
((VKDevice) {
|
||||
.name = deviceName,
|
||||
.handle = VK_NULL_HANDLE,
|
||||
@@ -795,10 +795,10 @@ static jboolean VK_InitDevice(VKDevice* device) {
|
||||
}
|
||||
|
||||
VKTxVertex* vertices = ARRAY_ALLOC(VKTxVertex, 4);
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKTxVertex){-1.0f, -1.0f, 0.0f, 0.0f}));
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKTxVertex){1.0f, -1.0f, 1.0f, 0.0f}));
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKTxVertex){-1.0f, 1.0f, 0.0f, 1.0f}));
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKTxVertex){1.0f, 1.0f, 1.0f, 1.0f}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKTxVertex){-1.0f, -1.0f, 0.0f, 0.0f}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKTxVertex){1.0f, -1.0f, 1.0f, 0.0f}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKTxVertex){-1.0f, 1.0f, 0.0f, 1.0f}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKTxVertex){1.0f, 1.0f, 1.0f, 1.0f}));
|
||||
device->blitVertexBuffer = ARRAY_TO_VERTEX_BUF(device, vertices);
|
||||
if (!device->blitVertexBuffer) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "Cannot create vertex buffer")
|
||||
|
||||
@@ -175,7 +175,7 @@ VKImage* VKImage_CreateImageArrayFromSwapChain(VKDevice* device,
|
||||
|
||||
VKImage* images = ARRAY_ALLOC(VKImage, swapChainImagesCount);
|
||||
for (uint32_t i = 0; i < swapChainImagesCount; i++) {
|
||||
ARRAY_PUSH_BACK(&images, ((VKImage){
|
||||
ARRAY_PUSH_BACK(images, ((VKImage){
|
||||
.image = swapChainImages[i],
|
||||
.memory = VK_NULL_HANDLE,
|
||||
.format = format,
|
||||
|
||||
@@ -831,16 +831,16 @@ void VKRenderer_RenderParallelogram(VKDevice* device,
|
||||
float p4x = -1.0f + (x11 + dx12) / width;
|
||||
float p4y = -1.0f + (y11 + dy12) / height;
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex) {p1x, p1y}));
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex) {p2x, p2y}));
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex) {p3x, p3y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex) {p1x, p1y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex) {p2x, p2y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex) {p3x, p3y}));
|
||||
|
||||
if (renderer->primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) {
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex) {p3x, p3y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex) {p3x, p3y}));
|
||||
}
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex) {p4x, p4y}));
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex) {p1x, p1y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex) {p4x, p4y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex) {p1x, p1y}));
|
||||
|
||||
int vertexNum = ARRAY_SIZE(vertices);
|
||||
|
||||
@@ -888,17 +888,17 @@ void VKRenderer_FillSpans(VKDevice* device, jint color, VKSDOps *dstOps, jint sp
|
||||
float p4x = p1x;
|
||||
float p4y = p3y;
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex){p1x,p1y}));
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex){p2x,p2y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex){p2x,p2y}));
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex){p3x,p3y}));
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex){p3x,p3y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex){p3x,p3y}));
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex){p4x,p4y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex){p4x,p4y}));
|
||||
|
||||
ARRAY_PUSH_BACK(&vertices, ((VKVertex){p1x,p1y}));
|
||||
ARRAY_PUSH_BACK(vertices, ((VKVertex){p1x,p1y}));
|
||||
}
|
||||
|
||||
VKBuffer *fillVertexBuffer = ARRAY_TO_VERTEX_BUF(device, vertices);
|
||||
|
||||
Reference in New Issue
Block a user