#include "util/u_memory.h"
#include "swr_context.h"
+#include "swr_screen.h"
#include "swr_scratch.h"
+#include "swr_fence_work.h"
#include "api.h"
-
void *
swr_copy_to_scratch_space(struct swr_context *ctx,
struct swr_scratch_space *space,
{
void *ptr;
assert(space);
- assert(user_buffer);
assert(size);
- if (size >= 2048) { /* XXX TODO create KNOB_ for this */
- /* Use per draw SwrAllocDrawContextMemory for larger copies */
- ptr = SwrAllocDrawContextMemory(ctx->swrContext, size, 4);
- } else {
- /* Allocate enough so that MAX_DRAWS_IN_FLIGHT sets fit. */
- unsigned int max_size_in_flight = size * KNOB_MAX_DRAWS_IN_FLIGHT;
-
- /* Need to grow space */
- if (max_size_in_flight > space->current_size) {
- /* Must idle the pipeline, this is infrequent */
- SwrWaitForIdle(ctx->swrContext);
-
- space->current_size = max_size_in_flight;
+ /* Allocate enough so that MAX_DRAWS_IN_FLIGHT sets fit. */
+ uint32_t max_size_in_flight = size * ctx->max_draws_in_flight;
- if (space->base) {
- align_free(space->base);
- space->base = NULL;
- }
+ /* Need to grow space */
+ if (max_size_in_flight > space->current_size) {
+ space->current_size = max_size_in_flight;
- if (!space->base) {
- space->base = (BYTE *)align_malloc(space->current_size, 4);
- space->head = (void *)space->base;
- }
+ if (space->base) {
+ /* defer delete, use aligned-free */
+ struct swr_screen *screen = swr_screen(ctx->pipe.screen);
+ swr_fence_work_free(screen->flush_fence, space->base, true);
+ space->base = NULL;
}
- /* Wrap */
- if (((BYTE *)space->head + size)
- >= ((BYTE *)space->base + space->current_size)) {
- /*
- * TODO XXX: Should add a fence on wrap. Assumption is that
- * current_space >> size, and there are at least MAX_DRAWS_IN_FLIGHT
- * draws in scratch. So fence would always be met on wrap. A fence
- * would ensure that first frame in buffer is done before wrapping.
- * If fence ever needs to be waited on, can increase buffer size.
- * So far in testing, this hasn't been necessary.
- */
- space->head = space->base;
+ if (!space->base) {
+ space->base = (uint8_t *)AlignedMalloc(space->current_size,
+ sizeof(void *));
+ space->head = (void *)space->base;
}
+ }
- ptr = space->head;
- space->head = (BYTE *)space->head + size;
+ /* Wrap */
+ if (((uint8_t *)space->head + size)
+ >= ((uint8_t *)space->base + space->current_size)) {
+ space->head = space->base;
}
+ ptr = space->head;
+ space->head = (uint8_t *)space->head + size;
+
/* Copy user_buffer to scratch */
- memcpy(ptr, user_buffer, size);
+ if (user_buffer)
+ memcpy(ptr, user_buffer, size);
return ptr;
}
struct swr_scratch_buffers *scratch = ctx->scratch;
if (scratch) {
- if (scratch->vs_constants.base)
- align_free(scratch->vs_constants.base);
- if (scratch->fs_constants.base)
- align_free(scratch->fs_constants.base);
- if (scratch->vertex_buffer.base)
- align_free(scratch->vertex_buffer.base);
- if (scratch->index_buffer.base)
- align_free(scratch->index_buffer.base);
+ AlignedFree(scratch->vs_constants.base);
+ AlignedFree(scratch->fs_constants.base);
+ AlignedFree(scratch->gs_constants.base);
+ AlignedFree(scratch->vertex_buffer.base);
+ AlignedFree(scratch->index_buffer.base);
FREE(scratch);
}
}