/**********************************************************
 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 **********************************************************/

#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"

#include "svga_resource_texture.h"
#include "svga_sampler_view.h"
#include "svga_winsys.h"
#include "svga_context.h"
#include "svga_shader.h"
#include "svga_state.h"
#include "svga_cmd.h"


/**
 * Called when tearing down a context to free resources and samplers.
 */
void svga_cleanup_tss_binding(struct svga_context *svga)
{
   const enum pipe_shader_type shader = PIPE_SHADER_FRAGMENT;
   unsigned i;

   for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.views); i++) {
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
      if (view) {
         svga_sampler_view_reference(&view->v, NULL);
         pipe_sampler_view_release(&svga->pipe,
                                   &svga->curr.sampler_views[shader][i]);
         pipe_resource_reference(&view->texture, NULL);
         view->dirty = TRUE;
      }
   }
}


struct bind_queue {
   struct {
      unsigned unit;
      struct svga_hw_view_state *view;
   } bind[PIPE_MAX_SAMPLERS];

   unsigned bind_count;
};


/**
 * Update the texture binding for one texture unit.
 */
static void
emit_tex_binding_unit(struct svga_context *svga,
                      unsigned unit,
                      const struct svga_sampler_state *s,
                      const struct pipe_sampler_view *sv,
                      struct svga_hw_view_state *view,
                      boolean reemit,
                      struct bind_queue *queue)
{
   struct pipe_resource *texture = NULL;
   unsigned last_level, min_lod, max_lod;

   /* get min max lod */
   if (sv && s) {
      if (s->mipfilter == SVGA3D_TEX_FILTER_NONE) {
         /* just use the base level image */
         min_lod = max_lod = sv->u.tex.first_level;
      }
      else {
         last_level = MIN2(sv->u.tex.last_level, sv->texture->last_level);
         min_lod = s->view_min_lod + sv->u.tex.first_level;
         min_lod = MIN2(min_lod, last_level);
         max_lod = MIN2(s->view_max_lod + sv->u.tex.first_level, last_level);
      }
      texture = sv->texture;
   }
   else {
      min_lod = 0;
      max_lod = 0;
   }

   if (view->texture != texture ||
       view->min_lod != min_lod ||
       view->max_lod != max_lod) {

      svga_sampler_view_reference(&view->v, NULL);
      pipe_resource_reference( &view->texture, texture );

      view->dirty = TRUE;
      view->min_lod = min_lod;
      view->max_lod = max_lod;

      if (texture) {
         view->v = svga_get_tex_sampler_view(&svga->pipe,
                                             texture,
                                             min_lod,
                                             max_lod);
      }
   }

   /*
    * We need to reemit non-null texture bindings, even when they are not
    * dirty, to ensure that the resources are paged in.
    */
   if (view->dirty || (reemit && view->v)) {
      queue->bind[queue->bind_count].unit = unit;
      queue->bind[queue->bind_count].view = view;
      queue->bind_count++;
   }

   if (!view->dirty && view->v) {
      svga_validate_sampler_view(svga, view->v);
   }
}


static enum pipe_error
update_tss_binding(struct svga_context *svga, 
                   unsigned dirty )
{
   const enum pipe_shader_type shader = PIPE_SHADER_FRAGMENT;
   boolean reemit = svga->rebind.flags.texture_samplers;
   unsigned i;
   unsigned count = MAX2( svga->curr.num_sampler_views[shader],
                          svga->state.hw_draw.num_views );

   struct bind_queue queue;

   if (svga_have_vgpu10(svga))
      return PIPE_OK;

   queue.bind_count = 0;
   
   for (i = 0; i < count; i++) {
      emit_tex_binding_unit(svga, i,
                            svga->curr.sampler[shader][i],
                            svga->curr.sampler_views[shader][i],
                            &svga->state.hw_draw.views[i],
                            reemit,
                            &queue);
   }

   svga->state.hw_draw.num_views = svga->curr.num_sampler_views[shader];

   /* Polygon stipple */
   if (svga->curr.rast->templ.poly_stipple_enable) {
      const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
      emit_tex_binding_unit(svga, unit,
                            svga->polygon_stipple.sampler,
                            &svga->polygon_stipple.sampler_view->base,
                            &svga->state.hw_draw.views[unit],
                            reemit,
                            &queue);
   }

   svga->state.hw_draw.num_backed_views = 0;

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.bind_count ) != PIPE_OK)
         goto fail;

      for (i = 0; i < queue.bind_count; i++) {
         struct svga_winsys_surface *handle;
         struct svga_hw_view_state *view = queue.bind[i].view;

         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         if (view->v) {
            handle = view->v->handle;

            /* Keep track of number of views with a backing copy
             * of texture.
             */
            if (handle != svga_texture(view->texture)->handle)
               svga->state.hw_draw.num_backed_views++;
         }
         else {
            handle = NULL;
         }
         svga->swc->surface_relocation(svga->swc,
                                       &ts[i].value,
                                       NULL,
                                       handle,
                                       SVGA_RELOC_READ);
         
         queue.bind[i].view->dirty = FALSE;
      }

      SVGA_FIFOCommitAll( svga->swc );
   }

   svga->rebind.flags.texture_samplers = FALSE;

   return PIPE_OK;

fail:
   return PIPE_ERROR_OUT_OF_MEMORY;
}


/*
 * Rebind textures.
 *
 * Similar to update_tss_binding, but without any state checking/update.
 *
 * Called at the beginning of every new command buffer to ensure that
 * non-dirty textures are properly paged-in.
 */
enum pipe_error
svga_reemit_tss_bindings(struct svga_context *svga)
{
   unsigned i;
   enum pipe_error ret;
   struct bind_queue queue;

   assert(!svga_have_vgpu10(svga));
   assert(svga->rebind.flags.texture_samplers);

   queue.bind_count = 0;

   for (i = 0; i < svga->state.hw_draw.num_views; i++) {
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];

      if (view->v) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      }
   }

   /* Polygon stipple */
   if (svga->curr.rast->templ.poly_stipple_enable) {
      const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[unit];

      if (view->v) {
         queue.bind[queue.bind_count].unit = unit;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      }
   }

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      ret = SVGA3D_BeginSetTextureState(svga->swc,
                                        &ts,
                                        queue.bind_count);
      if (ret != PIPE_OK) {
         return ret;
      }

      for (i = 0; i < queue.bind_count; i++) {
         struct svga_winsys_surface *handle;

         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         assert(queue.bind[i].view->v);
         handle = queue.bind[i].view->v->handle;
         svga->swc->surface_relocation(svga->swc,
                                       &ts[i].value,
                                       NULL,
                                       handle,
                                       SVGA_RELOC_READ);
      }

      SVGA_FIFOCommitAll(svga->swc);
   }

   svga->rebind.flags.texture_samplers = FALSE;

   return PIPE_OK;
}


struct svga_tracked_state svga_hw_tss_binding = {
   "texture binding emit",
   SVGA_NEW_FRAME_BUFFER |
   SVGA_NEW_TEXTURE_BINDING |
   SVGA_NEW_STIPPLE |
   SVGA_NEW_SAMPLER,
   update_tss_binding
};


/***********************************************************************
 */

struct ts_queue {
   unsigned ts_count;
   SVGA3dTextureState ts[PIPE_MAX_SAMPLERS*SVGA3D_TS_MAX];
};


static inline void
svga_queue_tss( struct ts_queue *q,
                unsigned unit,
                unsigned tss,
                unsigned value )
{
   assert(q->ts_count < ARRAY_SIZE(q->ts));
   q->ts[q->ts_count].stage = unit;
   q->ts[q->ts_count].name = tss;
   q->ts[q->ts_count].value = value;
   q->ts_count++;
}


#define EMIT_TS(svga, unit, val, token)                                 \
do {                                                                    \
   assert(unit < ARRAY_SIZE(svga->state.hw_draw.ts));                     \
   STATIC_ASSERT(SVGA3D_TS_##token < ARRAY_SIZE(svga->state.hw_draw.ts[unit])); \
   if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) {        \
      svga_queue_tss( queue, unit, SVGA3D_TS_##token, val );            \
      svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val;            \
   }                                                                    \
} while (0)

#define EMIT_TS_FLOAT(svga, unit, fvalue, token)                        \
do {                                                                    \
   unsigned val = fui(fvalue);                                          \
   assert(unit < ARRAY_SIZE(svga->state.hw_draw.ts));                     \
   STATIC_ASSERT(SVGA3D_TS_##token < ARRAY_SIZE(svga->state.hw_draw.ts[unit])); \
   if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) {        \
      svga_queue_tss( queue, unit, SVGA3D_TS_##token, val );            \
      svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val;            \
   }                                                                    \
} while (0)


/**
 * Emit texture sampler state (tss) for one texture unit.
 */
static void
emit_tss_unit(struct svga_context *svga, unsigned unit,
              const struct svga_sampler_state *state,
              struct ts_queue *queue)
{
   EMIT_TS(svga, unit, state->mipfilter, MIPFILTER);
   EMIT_TS(svga, unit, state->min_lod, TEXTURE_MIPMAP_LEVEL);
   EMIT_TS(svga, unit, state->magfilter, MAGFILTER);
   EMIT_TS(svga, unit, state->minfilter, MINFILTER);
   EMIT_TS(svga, unit, state->aniso_level, TEXTURE_ANISOTROPIC_LEVEL);
   EMIT_TS_FLOAT(svga, unit, state->lod_bias, TEXTURE_LOD_BIAS);
   EMIT_TS(svga, unit, state->addressu, ADDRESSU);
   EMIT_TS(svga, unit, state->addressw, ADDRESSW);
   EMIT_TS(svga, unit, state->bordercolor, BORDERCOLOR);
   // TEXCOORDINDEX -- hopefully not needed

   if (svga->curr.tex_flags.flag_1d & (1 << unit))
      EMIT_TS(svga, unit, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV);
   else
      EMIT_TS(svga, unit, state->addressv, ADDRESSV);

   if (svga->curr.tex_flags.flag_srgb & (1 << unit))
      EMIT_TS_FLOAT(svga, unit, 2.2f, GAMMA);
   else
      EMIT_TS_FLOAT(svga, unit, 1.0f, GAMMA);
}

static enum pipe_error
update_tss(struct svga_context *svga, 
           unsigned dirty )
{
   const enum pipe_shader_type shader = PIPE_SHADER_FRAGMENT;
   unsigned i;
   struct ts_queue queue;

   if (svga_have_vgpu10(svga))
      return PIPE_OK;

   queue.ts_count = 0;
   for (i = 0; i < svga->curr.num_samplers[shader]; i++) {
      if (svga->curr.sampler[shader][i]) {
         const struct svga_sampler_state *curr = svga->curr.sampler[shader][i];
         emit_tss_unit(svga, i, curr, &queue);
      }
   }

   /* polygon stipple sampler */
   if (svga->curr.rast->templ.poly_stipple_enable) {
      emit_tss_unit(svga,
                    svga->state.hw_draw.fs->pstipple_sampler_unit,
                    svga->polygon_stipple.sampler,
                    &queue);
   }
 
   if (queue.ts_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.ts_count ) != PIPE_OK)
         goto fail;

      memcpy( ts,
              queue.ts,
              queue.ts_count * sizeof queue.ts[0]);
      
      SVGA_FIFOCommitAll( svga->swc );
   }

   return PIPE_OK;

fail:
   /* XXX: need to poison cached hardware state on failure to ensure
    * dirty state gets re-emitted.  Fix this by re-instating partial
    * FIFOCommit command and only updating cached hw state once the
    * initial allocation has succeeded.
    */
   memset(svga->state.hw_draw.ts, 0xcd, sizeof(svga->state.hw_draw.ts));

   return PIPE_ERROR_OUT_OF_MEMORY;
}


struct svga_tracked_state svga_hw_tss = {
   "texture state emit",
   (SVGA_NEW_SAMPLER |
    SVGA_NEW_STIPPLE |
    SVGA_NEW_TEXTURE_FLAGS),
   update_tss
};

