101e04c3fSmrg/****************************************************************************
201e04c3fSmrg * Copyright (C) 2015 Intel Corporation.   All Rights Reserved.
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg ***************************************************************************/
2301e04c3fSmrg
2401e04c3fSmrg#include "util/u_memory.h"
2501e04c3fSmrg#include "swr_context.h"
2601e04c3fSmrg#include "swr_screen.h"
2701e04c3fSmrg#include "swr_scratch.h"
287ec681f3Smrg#include "swr_fence.h"
2901e04c3fSmrg#include "swr_fence_work.h"
3001e04c3fSmrg#include "api.h"
3101e04c3fSmrg
3201e04c3fSmrgvoid *
3301e04c3fSmrgswr_copy_to_scratch_space(struct swr_context *ctx,
3401e04c3fSmrg                          struct swr_scratch_space *space,
3501e04c3fSmrg                          const void *user_buffer,
3601e04c3fSmrg                          unsigned int size)
3701e04c3fSmrg{
3801e04c3fSmrg   void *ptr;
3901e04c3fSmrg   assert(space);
4001e04c3fSmrg   assert(size);
4101e04c3fSmrg
4201e04c3fSmrg   /* Allocate enough so that MAX_DRAWS_IN_FLIGHT sets fit. */
4301e04c3fSmrg   uint32_t max_size_in_flight = size * ctx->max_draws_in_flight;
4401e04c3fSmrg
4501e04c3fSmrg   /* Need to grow space */
4601e04c3fSmrg   if (max_size_in_flight > space->current_size) {
4701e04c3fSmrg      space->current_size = max_size_in_flight;
4801e04c3fSmrg
4901e04c3fSmrg      if (space->base) {
507ec681f3Smrg         /* defer delete, use aligned-free, fence finish enforces the defer
517ec681f3Smrg          * delete will be on the *next* fence */
5201e04c3fSmrg         struct swr_screen *screen = swr_screen(ctx->pipe.screen);
537ec681f3Smrg         swr_fence_finish(ctx->pipe.screen, NULL, screen->flush_fence, 0);
5401e04c3fSmrg         swr_fence_work_free(screen->flush_fence, space->base, true);
5501e04c3fSmrg         space->base = NULL;
5601e04c3fSmrg      }
5701e04c3fSmrg
5801e04c3fSmrg      if (!space->base) {
5901e04c3fSmrg         space->base = (uint8_t *)AlignedMalloc(space->current_size,
6001e04c3fSmrg                                                sizeof(void *));
6101e04c3fSmrg         space->head = (void *)space->base;
6201e04c3fSmrg      }
6301e04c3fSmrg   }
6401e04c3fSmrg
6501e04c3fSmrg   /* Wrap */
6601e04c3fSmrg   if (((uint8_t *)space->head + size)
6701e04c3fSmrg       >= ((uint8_t *)space->base + space->current_size)) {
6801e04c3fSmrg      space->head = space->base;
6901e04c3fSmrg   }
7001e04c3fSmrg
7101e04c3fSmrg   ptr = space->head;
7201e04c3fSmrg   space->head = (uint8_t *)space->head + size;
7301e04c3fSmrg
7401e04c3fSmrg   /* Copy user_buffer to scratch */
7501e04c3fSmrg   if (user_buffer)
7601e04c3fSmrg      memcpy(ptr, user_buffer, size);
7701e04c3fSmrg
7801e04c3fSmrg   return ptr;
7901e04c3fSmrg}
8001e04c3fSmrg
8101e04c3fSmrg
8201e04c3fSmrgvoid
8301e04c3fSmrgswr_init_scratch_buffers(struct swr_context *ctx)
8401e04c3fSmrg{
8501e04c3fSmrg   struct swr_scratch_buffers *scratch;
8601e04c3fSmrg
8701e04c3fSmrg   scratch = CALLOC_STRUCT(swr_scratch_buffers);
8801e04c3fSmrg   ctx->scratch = scratch;
8901e04c3fSmrg}
9001e04c3fSmrg
9101e04c3fSmrgvoid
9201e04c3fSmrgswr_destroy_scratch_buffers(struct swr_context *ctx)
9301e04c3fSmrg{
9401e04c3fSmrg   struct swr_scratch_buffers *scratch = ctx->scratch;
9501e04c3fSmrg
9601e04c3fSmrg   if (scratch) {
9701e04c3fSmrg      AlignedFree(scratch->vs_constants.base);
9801e04c3fSmrg      AlignedFree(scratch->fs_constants.base);
9901e04c3fSmrg      AlignedFree(scratch->gs_constants.base);
1007ec681f3Smrg      AlignedFree(scratch->tcs_constants.base);
1017ec681f3Smrg      AlignedFree(scratch->tes_constants.base);
10201e04c3fSmrg      AlignedFree(scratch->vertex_buffer.base);
10301e04c3fSmrg      AlignedFree(scratch->index_buffer.base);
10401e04c3fSmrg      FREE(scratch);
10501e04c3fSmrg   }
10601e04c3fSmrg}
107