static void
gen6_emit_launch_grid_surface_const(struct ilo_render *r,
                                    const struct ilo_state_vector *vec,
                                    struct ilo_render_launch_grid_session *session)
{
   const struct ilo_shader_state *cs = vec->cs;
   uint32_t *surface_state = r->state.cs.SURFACE_STATE;
   struct ilo_view_surface view;
   int base, count;

   ILO_DEV_ASSERT(r->dev, 7, 7.5);

   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_CONST_BASE);
   count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_CONST_COUNT);

   if (!count)
      return;

   ilo_gpe_init_view_surface_for_buffer(r->dev,
         ilo_buffer(session->input->buffer),
         session->input->buffer_offset,
         session->input->buffer_size,
         1, PIPE_FORMAT_NONE,
         false, false, &view);

   assert(count == 1 && session->input->buffer);
   surface_state[base] = gen6_SURFACE_STATE(r->builder, &view, false);
}
Exemple #2
0
static void
finalize_global_binding(struct ilo_state_vector *vec)
{
   struct ilo_shader_state *cs = vec->cs;
   int base, count, shift;
   int i;

   count = ilo_shader_get_kernel_param(cs,
         ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);
   if (!count)
      return;

   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
   shift = 32 - util_last_bit(base + count - 1);

   if (count > vec->global_binding.count)
      count = vec->global_binding.count;

   for (i = 0; i < count; i++) {
      struct ilo_global_binding_cso *cso =
         util_dynarray_element(&vec->global_binding.bindings,
               struct ilo_global_binding_cso, i);
      const uint32_t offset = *cso->handle & ((1 << shift) - 1);

      *cso->handle = ((base + i) << shift) | offset;
   }
}
static void
gen6_emit_launch_grid_surface_view(struct ilo_render *r,
                                   const struct ilo_state_vector *vec,
                                   struct ilo_render_launch_grid_session *session)
{
   const struct ilo_shader_state *cs = vec->cs;
   const struct ilo_view_state *view = &vec->view[PIPE_SHADER_COMPUTE];
   uint32_t *surface_state = r->state.cs.SURFACE_STATE;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 7, 7.5);

   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TEX_BASE);
   count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TEX_COUNT);

   /* SURFACE_STATEs for sampler views */
   surface_state += base;
   for (i = 0; i < count; i++) {
      if (i < view->count && view->states[i]) {
         const struct ilo_view_cso *cso =
            (const struct ilo_view_cso *) view->states[i];

         surface_state[i] =
            gen6_SURFACE_STATE(r->builder, &cso->surface, false);
      } else {
         surface_state[i] = 0;
      }
   }
}
static void
finalize_vertex_elements(struct ilo_context *ilo)
{
   struct ilo_state_vector *vec = &ilo->state_vector;

   if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS)))
      return;

   vec->dirty |= ILO_DIRTY_VE;

   vec->ve->last_cso_edgeflag = false;
   if (vec->ve->count && vec->vs &&
         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)) {
      vec->ve->edgeflag_cso = vec->ve->cso[vec->ve->count - 1];
      ilo_gpe_set_ve_edgeflag(ilo->dev, &vec->ve->edgeflag_cso);
      vec->ve->last_cso_edgeflag = true;
   }

   vec->ve->prepend_nosrc_cso = false;
   if (vec->vs &&
       (ilo_shader_get_kernel_param(vec->vs,
                                    ILO_KERNEL_VS_INPUT_INSTANCEID) ||
        ilo_shader_get_kernel_param(vec->vs,
                                    ILO_KERNEL_VS_INPUT_VERTEXID))) {
      ilo_gpe_init_ve_nosrc(ilo->dev,
            GEN6_VFCOMP_STORE_VID,
            GEN6_VFCOMP_STORE_IID,
            GEN6_VFCOMP_NOSTORE,
            GEN6_VFCOMP_NOSTORE,
            &vec->ve->nosrc_cso);
      vec->ve->prepend_nosrc_cso = true;
   } else if (!vec->vs) {
      /* generate VUE header */
      ilo_gpe_init_ve_nosrc(ilo->dev,
            GEN6_VFCOMP_STORE_0, /* Reserved */
            GEN6_VFCOMP_STORE_0, /* Render Target Array Index */
            GEN6_VFCOMP_STORE_0, /* Viewport Index */
            GEN6_VFCOMP_STORE_0, /* Point Width */
            &vec->ve->nosrc_cso);
      vec->ve->prepend_nosrc_cso = true;
   } else if (!vec->ve->count) {
      /*
       * From the Sandy Bridge PRM, volume 2 part 1, page 92:
       *
       *    "SW must ensure that at least one vertex element is defined prior
       *     to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
       */
      ilo_gpe_init_ve_nosrc(ilo->dev,
            GEN6_VFCOMP_STORE_0,
            GEN6_VFCOMP_STORE_0,
            GEN6_VFCOMP_STORE_0,
            GEN6_VFCOMP_STORE_1_FP,
            &vec->ve->nosrc_cso);
      vec->ve->prepend_nosrc_cso = true;
   }
}
static void
gen6_emit_draw_surface_binding_tables(struct ilo_render *r,
                                      const struct ilo_state_vector *vec,
                                      int shader_type,
                                      struct ilo_render_draw_session *session)
{
   int count;

   ILO_DEV_ASSERT(r->dev, 6, 7.5);

   /* BINDING_TABLE_STATE */
   switch (shader_type) {
   case PIPE_SHADER_VERTEX:
      if (!session->binding_table_vs_changed)
         return;
      if (!vec->vs)
         return;

      count = ilo_shader_get_kernel_param(vec->vs,
            ILO_KERNEL_SURFACE_TOTAL_COUNT);

      r->state.vs.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
            r->state.vs.SURFACE_STATE, count);
      break;
   case PIPE_SHADER_GEOMETRY:
      if (!session->binding_table_gs_changed)
         return;
      if (vec->gs) {
         count = ilo_shader_get_kernel_param(vec->gs,
               ILO_KERNEL_SURFACE_TOTAL_COUNT);
      } else if (ilo_dev_gen(r->dev) == ILO_GEN(6) && vec->vs) {
         count = ilo_shader_get_kernel_param(vec->vs,
               ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT);
      } else {
         return;
      }

      r->state.gs.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
            r->state.gs.SURFACE_STATE, count);
      break;
   case PIPE_SHADER_FRAGMENT:
      if (!session->binding_table_fs_changed)
         return;
      if (!vec->fs)
         return;

      count = ilo_shader_get_kernel_param(vec->fs,
            ILO_KERNEL_SURFACE_TOTAL_COUNT);

      r->state.wm.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
            r->state.wm.SURFACE_STATE, count);
      break;
   default:
      break;
   }
}
static void
gen6_emit_draw_surface_view(struct ilo_render *r,
                            const struct ilo_state_vector *vec,
                            int shader_type,
                            struct ilo_render_draw_session *session)
{
   const struct ilo_view_state *view = &vec->view[shader_type];
   const struct ilo_shader_state *sh;
   uint32_t *surface_state;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 6, 7.5);

   switch (shader_type) {
   case PIPE_SHADER_VERTEX:
      if (!DIRTY(VS) && !DIRTY(VIEW_VS))
         return;
      if (!vec->vs)
         return;

      sh = vec->vs;
      surface_state = r->state.vs.SURFACE_STATE;
      session->binding_table_vs_changed = true;
      break;
   case PIPE_SHADER_FRAGMENT:
      if (!DIRTY(FS) && !DIRTY(VIEW_FS))
         return;
      if (!vec->fs)
         return;

      sh = vec->fs;
      surface_state = r->state.wm.SURFACE_STATE;
      session->binding_table_fs_changed = true;
      break;
   default:
      return;
      break;
   }

   base = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_TEX_BASE);
   count = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_TEX_COUNT);

   /* SURFACE_STATEs for sampler views */
   surface_state += base;
   for (i = 0; i < count; i++) {
      if (i < view->count && view->states[i]) {
         const struct ilo_view_cso *cso =
            (const struct ilo_view_cso *) view->states[i];

         surface_state[i] =
            gen6_SURFACE_STATE(r->builder, &cso->surface, false);
      } else {
         surface_state[i] = 0;
      }
   }
}
static void
gen6_emit_draw_surface_const(struct ilo_render *r,
                             const struct ilo_state_vector *vec,
                             int shader_type,
                             struct ilo_render_draw_session *session)
{
   const struct ilo_cbuf_state *cbuf = &vec->cbuf[shader_type];
   const struct ilo_shader_state *sh;
   uint32_t *surface_state;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 6, 7.5);

   switch (shader_type) {
   case PIPE_SHADER_VERTEX:
      if (!DIRTY(VS) && !DIRTY(CBUF))
         return;
      if (!vec->vs)
         return;

      sh = vec->vs;
      surface_state = r->state.vs.SURFACE_STATE;
      session->binding_table_vs_changed = true;
      break;
   case PIPE_SHADER_FRAGMENT:
      if (!DIRTY(FS) && !DIRTY(CBUF))
         return;
      if (!vec->fs)
         return;

      sh = vec->fs;
      surface_state = r->state.wm.SURFACE_STATE;
      session->binding_table_fs_changed = true;
      break;
   default:
      return;
      break;
   }

   base = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_CONST_BASE);
   count = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_CONST_COUNT);

   /* SURFACE_STATEs for constant buffers */
   surface_state += base;
   for (i = 0; i < count; i++) {
      const struct ilo_cbuf_cso *cso = &cbuf->cso[i];

      if (cso->resource) {
         surface_state[i] = gen6_SURFACE_STATE(r->builder,
               &cso->surface, false);
      } else {
         surface_state[i] = 0;
      }
   }
}
int
ilo_render_get_draw_surface_states_len(const struct ilo_render *render,
                                       const struct ilo_state_vector *vec)
{
   int sh_type, len;

   ILO_DEV_ASSERT(render->dev, 6, 7.5);

   len = 0;

   for (sh_type = 0; sh_type < PIPE_SHADER_TYPES; sh_type++) {
      const int alignment = 32 / 4;
      int num_surfaces = 0;

      switch (sh_type) {
      case PIPE_SHADER_VERTEX:
         if (vec->vs) {
            num_surfaces = ilo_shader_get_kernel_param(vec->vs,
                  ILO_KERNEL_SURFACE_TOTAL_COUNT);

            if (ilo_dev_gen(render->dev) == ILO_GEN(6)) {
               num_surfaces += ilo_shader_get_kernel_param(vec->vs,
                     ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT);
            }
         }
         break;
      case PIPE_SHADER_GEOMETRY:
         if (vec->gs) {
            num_surfaces = ilo_shader_get_kernel_param(vec->gs,
                  ILO_KERNEL_SURFACE_TOTAL_COUNT);
         }
         break;
      case PIPE_SHADER_FRAGMENT:
         if (vec->fs) {
            num_surfaces = ilo_shader_get_kernel_param(vec->fs,
                  ILO_KERNEL_SURFACE_TOTAL_COUNT);
         }
         break;
      default:
         break;
      }

      /* BINDING_TABLE_STATE and SURFACE_STATEs */
      if (num_surfaces) {
         len += align(num_surfaces, alignment) +
            align(GEN6_SURFACE_STATE__SIZE, alignment) * num_surfaces;
      }
   }

   return len;
}
static void
gen6_emit_draw_surface_so(struct ilo_render *r,
                          const struct ilo_state_vector *vec,
                          struct ilo_render_draw_session *session)
{
   const struct ilo_shader_state *vs = vec->vs;
   const struct ilo_shader_state *gs = vec->gs;
   const struct ilo_so_state *so = &vec->so;
   const struct pipe_stream_output_info *so_info;
   uint32_t *surface_state;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 6, 6);

   if (!DIRTY(VS) && !DIRTY(GS) && !DIRTY(SO))
      return;

   if (gs) {
      so_info = ilo_shader_get_kernel_so_info(gs);
      base = ilo_shader_get_kernel_param(gs,
            ILO_KERNEL_GS_GEN6_SURFACE_SO_BASE);
      count = ilo_shader_get_kernel_param(gs,
            ILO_KERNEL_GS_GEN6_SURFACE_SO_COUNT);
   } else if (vs) {
      so_info = ilo_shader_get_kernel_so_info(vs);
      base = 0;
      count = ilo_shader_get_kernel_param(vs,
            ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT);
   } else {
      return;
   }

   session->binding_table_gs_changed = true;

   /* SURFACE_STATEs for stream output targets */
   surface_state = &r->state.gs.SURFACE_STATE[base];
   for (i = 0; i < count; i++) {
      if (so_info && i < so_info->num_outputs &&
          so_info->output[i].output_buffer < so->count &&
          so->states[so_info->output[i].output_buffer]) {
         const struct pipe_stream_output_target *so_target =
            so->states[so_info->output[i].output_buffer];

         surface_state[i] = gen6_so_SURFACE_STATE(r->builder,
               so_target, so_info, i);
      } else {
         surface_state[i] = 0;
      }
   }
}
Exemple #10
0
int
ilo_render_get_launch_grid_dynamic_states_len(const struct ilo_render *render,
                                              const struct ilo_state_vector *vec)
{
   const int alignment = 32 / 4;
   int num_samplers;
   int len = 0;

   ILO_DEV_ASSERT(render->dev, 7, 7.5);

   num_samplers = ilo_shader_get_kernel_param(vec->cs,
         ILO_KERNEL_SAMPLER_COUNT);

   /* SAMPLER_STATE array and SAMPLER_BORDER_COLORs */
   if (num_samplers) {
      /* prefetches are done in multiples of 4 */
      num_samplers = align(num_samplers, 4);

      len += align(GEN6_SAMPLER_STATE__SIZE * num_samplers, alignment) +
         align(GEN6_SAMPLER_BORDER_COLOR__SIZE, alignment) * num_samplers;
   }

   len += GEN6_INTERFACE_DESCRIPTOR_DATA__SIZE;

   return len;
}
Exemple #11
0
static void
gen6_emit_launch_grid_dynamic_samplers(struct ilo_render *r,
                                       const struct ilo_state_vector *vec,
                                       struct ilo_render_launch_grid_session *session)
{
   const unsigned shader_type = PIPE_SHADER_COMPUTE;
   const struct ilo_shader_state *cs = vec->cs;
   const struct ilo_sampler_cso * const *samplers =
      vec->sampler[shader_type].cso;
   const struct pipe_sampler_view * const *views =
      (const struct pipe_sampler_view **) vec->view[shader_type].states;
   int sampler_count, i;

   ILO_DEV_ASSERT(r->dev, 7, 7.5);

   sampler_count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);

   assert(sampler_count <= Elements(vec->view[shader_type].states) &&
          sampler_count <= Elements(vec->sampler[shader_type].cso));

   for (i = 0; i < sampler_count; i++) {
      r->state.cs.SAMPLER_BORDER_COLOR_STATE[i] = (samplers[i]) ?
         gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, samplers[i]) : 0;
   }

   r->state.cs.SAMPLER_STATE = gen6_SAMPLER_STATE(r->builder, samplers, views,
         r->state.cs.SAMPLER_BORDER_COLOR_STATE, sampler_count);
}
Exemple #12
0
void
ilo_gpe_init_gs_cso_gen7(const struct ilo_dev_info *dev,
                         const struct ilo_shader_state *gs,
                         struct ilo_shader_cso *cso)
{
   int start_grf, vue_read_len, max_threads;
   uint32_t dw2, dw4, dw5;

   ILO_GPE_VALID_GEN(dev, 7, 7.5);

   start_grf = ilo_shader_get_kernel_param(gs, ILO_KERNEL_URB_DATA_START_REG);
   vue_read_len = ilo_shader_get_kernel_param(gs, ILO_KERNEL_INPUT_COUNT);

   /* in pairs */
   vue_read_len = (vue_read_len + 1) / 2;

   switch (dev->gen) {
   case ILO_GEN(7.5):
      max_threads = (dev->gt >= 2) ? 256 : 70;
      break;
   case ILO_GEN(7):
      max_threads = (dev->gt == 2) ? 128 : 36;
      break;
   default:
      max_threads = 1;
      break;
   }

   dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;

   dw4 = vue_read_len << GEN7_GS_DW4_URB_READ_LEN__SHIFT |
         GEN7_GS_DW4_INCLUDE_VERTEX_HANDLES |
         0 << GEN7_GS_DW4_URB_READ_OFFSET__SHIFT |
         start_grf << GEN7_GS_DW4_URB_GRF_START__SHIFT;

   dw5 = (max_threads - 1) << GEN7_GS_DW5_MAX_THREADS__SHIFT |
         GEN7_GS_DW5_STATISTICS |
         GEN7_GS_DW5_GS_ENABLE;

   STATIC_ASSERT(Elements(cso->payload) >= 3);
   cso->payload[0] = dw2;
   cso->payload[1] = dw4;
   cso->payload[2] = dw5;
}
Exemple #13
0
static void
gen6_emit_launch_grid_surface_global(struct ilo_render *r,
                                          const struct ilo_state_vector *vec,
                                          struct ilo_render_launch_grid_session *session)
{
   const struct ilo_shader_state *cs = vec->cs;
   const struct ilo_global_binding_cso *bindings =
      util_dynarray_begin(&vec->global_binding.bindings);
   uint32_t *surface_state = r->state.cs.SURFACE_STATE;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 7, 7.5);

   base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
   count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);

   if (!count)
      return;

   if (base + count > Elements(r->state.cs.SURFACE_STATE)) {
      ilo_warn("too many global bindings\n");
      count = Elements(r->state.cs.SURFACE_STATE) - base;
   }

   /* SURFACE_STATEs for global bindings */
   surface_state += base;
   for (i = 0; i < count; i++) {
      if (i < vec->global_binding.count && bindings[i].resource) {
         const struct ilo_buffer *buf = ilo_buffer(bindings[i].resource);
         struct ilo_view_surface view;

         assert(bindings[i].resource->target == PIPE_BUFFER);

         ilo_gpe_init_view_surface_for_buffer(r->dev, buf, 0, buf->bo_size,
               1, PIPE_FORMAT_NONE, true, true, &view);
         surface_state[i] =
            gen6_SURFACE_STATE(r->builder, &view, true);
      } else {
         surface_state[i] = 0;
      }
   }
}
Exemple #14
0
static void
gen6_emit_draw_surface_rt(struct ilo_render *r,
                          const struct ilo_state_vector *vec,
                          struct ilo_render_draw_session *session)
{
   const struct ilo_shader_state *fs = vec->fs;
   const struct ilo_fb_state *fb = &vec->fb;
   uint32_t *surface_state;
   int base, count, i;

   ILO_DEV_ASSERT(r->dev, 6, 7.5);

   if (!DIRTY(FS) && !DIRTY(FB))
      return;
   if (!fs)
      return;

   session->binding_table_fs_changed = true;

   base = ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_SURFACE_RT_BASE);
   count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_SURFACE_RT_COUNT);

   /* SURFACE_STATEs for render targets */
   surface_state = &r->state.wm.SURFACE_STATE[base];
   for (i = 0; i < count; i++) {
      if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
         const struct ilo_surface_cso *surface =
            (const struct ilo_surface_cso *) fb->state.cbufs[i];

         assert(surface->is_rt);
         surface_state[i] =
            gen6_SURFACE_STATE(r->builder, &surface->u.rt, true);
      } else {
         surface_state[i] =
            gen6_SURFACE_STATE(r->builder, &fb->null_rt, true);
      }
   }
}
Exemple #15
0
static void
gen6_emit_launch_grid_surface_binding_table(struct ilo_render *r,
                                            const struct ilo_state_vector *vec,
                                            struct ilo_render_launch_grid_session *session)
{
   const struct ilo_shader_state *cs = vec->cs;
   int count;

   ILO_DEV_ASSERT(r->dev, 7, 7.5);

   count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
   if (count) {
      r->state.cs.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
            r->state.cs.SURFACE_STATE, count);
   }
}
Exemple #16
0
int
ilo_render_get_launch_grid_surface_states_len(const struct ilo_render *render,
                                              const struct ilo_state_vector *vec)
{
   const int alignment = 32 / 4;
   int num_surfaces;
   int len = 0;

   ILO_DEV_ASSERT(render->dev, 7, 7.5);

   num_surfaces = ilo_shader_get_kernel_param(vec->cs,
         ILO_KERNEL_SURFACE_TOTAL_COUNT);

   /* BINDING_TABLE_STATE and SURFACE_STATEs */
   if (num_surfaces) {
      len += align(num_surfaces, alignment) +
         align(GEN6_SURFACE_STATE__SIZE, alignment) * num_surfaces;
   }

   return len;
}
Exemple #17
0
static void
gen6_draw_gs(struct ilo_render *r,
             const struct ilo_state_vector *vec,
             struct ilo_render_draw_session *session)
{
   /* 3DSTATE_CONSTANT_GS */
   if (session->pcb_gs_changed)
      gen6_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);

   /* 3DSTATE_GS */
   if (DIRTY(GS) || DIRTY(VS) ||
       session->prim_changed || r->instruction_bo_changed) {
      if (vec->gs) {
         gen6_3DSTATE_GS(r->builder, vec->gs);
      } else if (vec->vs &&
            ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)) {
         const int verts_per_prim = u_vertices_per_prim(session->reduced_prim);
         gen6_so_3DSTATE_GS(r->builder, vec->vs, verts_per_prim);
      } else {
         gen6_disable_3DSTATE_GS(r->builder);
      }
   }
}
Exemple #18
0
void
ilo_gpe_init_fs_cso_gen7(const struct ilo_dev_info *dev,
                         const struct ilo_shader_state *fs,
                         struct ilo_shader_cso *cso)
{
   int start_grf, max_threads;
   uint32_t dw2, dw4, dw5;
   uint32_t wm_interps, wm_dw1;

   ILO_GPE_VALID_GEN(dev, 7, 7.5);

   start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);

   dw2 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;

   dw4 = GEN7_PS_DW4_POSOFFSET_NONE;

   /* see brwCreateContext() */
   switch (dev->gen) {
   case ILO_GEN(7.5):
      max_threads = (dev->gt == 3) ? 408 : (dev->gt == 2) ? 204 : 102;
      dw4 |= (max_threads - 1) << GEN75_PS_DW4_MAX_THREADS__SHIFT;
      dw4 |= 1 << GEN75_PS_DW4_SAMPLE_MASK__SHIFT;
      break;
   case ILO_GEN(7):
   default:
      max_threads = (dev->gt == 2) ? 172 : 48;
      dw4 |= (max_threads - 1) << GEN7_PS_DW4_MAX_THREADS__SHIFT;
      break;
   }

   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
      dw4 |= GEN7_PS_DW4_PUSH_CONSTANT_ENABLE;

   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
      dw4 |= GEN7_PS_DW4_ATTR_ENABLE;

   assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
   dw4 |= GEN7_PS_DW4_8_PIXEL_DISPATCH;

   dw5 = start_grf << GEN7_PS_DW5_URB_GRF_START0__SHIFT |
         0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
         0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;

   /* FS affects 3DSTATE_WM too */
   wm_dw1 = 0;

   /*
    * TODO set this bit only when
    *
    *  a) fs writes colors and color is not masked, or
    *  b) fs writes depth, or
    *  c) fs or cc kills
    */
   wm_dw1 |= GEN7_WM_DW1_PS_ENABLE;

   /*
    * From the Ivy Bridge PRM, volume 2 part 1, page 278:
    *
    *     "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
    *      the PS kernel or color calculator has the ability to kill
    *      (discard) pixels or samples, other than due to depth or stencil
    *      testing. This bit is required to be ENABLED in the following
    *      situations:
    *
    *      - The API pixel shader program contains "killpix" or "discard"
    *        instructions, or other code in the pixel shader kernel that
    *        can cause the final pixel mask to differ from the pixel mask
    *        received on dispatch.
    *
    *      - A sampler with chroma key enabled with kill pixel mode is used
    *        by the pixel shader.
    *
    *      - Any render target has Alpha Test Enable or AlphaToCoverage
    *        Enable enabled.
    *
    *      - The pixel shader kernel generates and outputs oMask.
    *
    *      Note: As ClipDistance clipping is fully supported in hardware
    *      and therefore not via PS instructions, there should be no need
    *      to ENABLE this bit due to ClipDistance clipping."
    */
   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
      wm_dw1 |= GEN7_WM_DW1_PS_KILL;

   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
      wm_dw1 |= GEN7_WM_DW1_PSCDEPTH_ON;

   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
      wm_dw1 |= GEN7_WM_DW1_PS_USE_DEPTH;

   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
      wm_dw1 |= GEN7_WM_DW1_PS_USE_W;

   wm_interps = ilo_shader_get_kernel_param(fs,
         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);

   wm_dw1 |= wm_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;

   STATIC_ASSERT(Elements(cso->payload) >= 4);
   cso->payload[0] = dw2;
   cso->payload[1] = dw4;
   cso->payload[2] = dw5;
   cso->payload[3] = wm_dw1;
}
Exemple #19
0
static void
gen6_draw_common_urb(struct ilo_render *r,
                     const struct ilo_state_vector *vec,
                     struct ilo_render_draw_session *session)
{
   /* 3DSTATE_URB */
   if (DIRTY(VE) || DIRTY(VS) || DIRTY(GS)) {
      const bool gs_active = (vec->gs || (vec->vs &&
               ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)));
      int vs_entry_size, gs_entry_size;
      int vs_total_size, gs_total_size;

      vs_entry_size = (vec->vs) ?
         ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_OUTPUT_COUNT) : 0;

      /*
       * As indicated by 2e712e41db0c0676e9f30fc73172c0e8de8d84d4, VF and VS
       * share VUE handles.  The VUE allocation size must be large enough to
       * store either VF outputs (number of VERTEX_ELEMENTs) and VS outputs.
       *
       * I am not sure if the PRM explicitly states that VF and VS share VUE
       * handles.  But here is a citation that implies so:
       *
       * From the Sandy Bridge PRM, volume 2 part 1, page 44:
       *
       *     "Once a FF stage that spawn threads has sufficient input to
       *      initiate a thread, it must guarantee that it is safe to request
       *      the thread initiation. For all these FF stages, this check is
       *      based on :
       *
       *      - The availability of output URB entries:
       *        - VS: As the input URB entries are overwritten with the
       *          VS-generated output data, output URB availability isn't a
       *          factor."
       */
      if (vs_entry_size < vec->ve->count + vec->ve->prepend_nosrc_cso)
         vs_entry_size = vec->ve->count + vec->ve->prepend_nosrc_cso;

      gs_entry_size = (vec->gs) ?
         ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_OUTPUT_COUNT) :
         (gs_active) ? vs_entry_size : 0;

      /* in bytes */
      vs_entry_size *= sizeof(float) * 4;
      gs_entry_size *= sizeof(float) * 4;
      vs_total_size = r->dev->urb_size;

      if (gs_active) {
         vs_total_size /= 2;
         gs_total_size = vs_total_size;
      }
      else {
         gs_total_size = 0;
      }

      gen6_3DSTATE_URB(r->builder, vs_total_size, gs_total_size,
            vs_entry_size, gs_entry_size);

      /*
       * From the Sandy Bridge PRM, volume 2 part 1, page 27:
       *
       *     "Because of a urb corruption caused by allocating a previous
       *      gsunit's urb entry to vsunit software is required to send a
       *      "GS NULL Fence" (Send URB fence with VS URB size == 1 and GS URB
       *      size == 0) plus a dummy DRAW call before any case where VS will
       *      be taking over GS URB space."
       */
      if (r->state.gs.active && !gs_active)
         ilo_render_emit_flush(r);

      r->state.gs.active = gs_active;
   }
}
Exemple #20
0
int
ilo_render_get_draw_dynamic_states_len(const struct ilo_render *render,
                                       const struct ilo_state_vector *vec)
{
   static int static_len;
   int sh_type, len;

   ILO_DEV_ASSERT(render->dev, 6, 7.5);

   if (!static_len) {
      /* 64 bytes, or 16 dwords */
      const int alignment = 64 / 4;

      /* pad first */
      len = alignment - 1;

      /* CC states */
      len += align(GEN6_BLEND_STATE__SIZE * ILO_MAX_DRAW_BUFFERS, alignment);
      len += align(GEN6_DEPTH_STENCIL_STATE__SIZE, alignment);
      len += align(GEN6_COLOR_CALC_STATE__SIZE, alignment);

      /* viewport arrays */
      if (ilo_dev_gen(render->dev) >= ILO_GEN(7)) {
         len += 15 + /* pad first */
            align(GEN7_SF_CLIP_VIEWPORT__SIZE * ILO_MAX_VIEWPORTS, 16) +
            align(GEN6_CC_VIEWPORT__SIZE * ILO_MAX_VIEWPORTS, 8) +
            align(GEN6_SCISSOR_RECT__SIZE * ILO_MAX_VIEWPORTS, 8);
      } else {
         len += 7 + /* pad first */
            align(GEN6_SF_VIEWPORT__SIZE * ILO_MAX_VIEWPORTS, 8) +
            align(GEN6_CLIP_VIEWPORT__SIZE * ILO_MAX_VIEWPORTS, 8) +
            align(GEN6_CC_VIEWPORT__SIZE * ILO_MAX_VIEWPORTS, 8) +
            align(GEN6_SCISSOR_RECT__SIZE * ILO_MAX_VIEWPORTS, 8);
      }

      static_len = len;
   }

   len = static_len;

   for (sh_type = 0; sh_type < PIPE_SHADER_TYPES; sh_type++) {
      const int alignment = 32 / 4;
      int num_samplers = 0, pcb_len = 0;

      switch (sh_type) {
      case PIPE_SHADER_VERTEX:
         if (vec->vs) {
            num_samplers = ilo_shader_get_kernel_param(vec->vs,
                  ILO_KERNEL_SAMPLER_COUNT);
            pcb_len = ilo_shader_get_kernel_param(vec->vs,
                  ILO_KERNEL_PCB_CBUF0_SIZE);
            pcb_len += ilo_shader_get_kernel_param(vec->vs,
                  ILO_KERNEL_VS_PCB_UCP_SIZE);
         }
         break;
      case PIPE_SHADER_GEOMETRY:
         break;
      case PIPE_SHADER_FRAGMENT:
         if (vec->fs) {
            num_samplers = ilo_shader_get_kernel_param(vec->fs,
                  ILO_KERNEL_SAMPLER_COUNT);
            pcb_len = ilo_shader_get_kernel_param(vec->fs,
                  ILO_KERNEL_PCB_CBUF0_SIZE);
         }
         break;
      default:
         break;
      }

      /* SAMPLER_STATE array and SAMPLER_BORDER_COLORs */
      if (num_samplers) {
         /* prefetches are done in multiples of 4 */
         num_samplers = align(num_samplers, 4);

         len += align(GEN6_SAMPLER_STATE__SIZE * num_samplers, alignment) +
            align(GEN6_SAMPLER_BORDER_COLOR__SIZE, alignment) * num_samplers;
      }

      /* PCB */
      if (pcb_len)
         len += align(pcb_len, alignment);
   }

   return len;
}
Exemple #21
0
static void
gen6_emit_draw_dynamic_pcb(struct ilo_render *r,
                           const struct ilo_state_vector *vec,
                           struct ilo_render_draw_session *session)
{
   ILO_DEV_ASSERT(r->dev, 6, 7.5);

   /* push constant buffer for VS */
   if (DIRTY(VS) || DIRTY(CBUF) || DIRTY(CLIP)) {
      const int cbuf0_size = (vec->vs) ?
            ilo_shader_get_kernel_param(vec->vs,
                  ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
      const int clip_state_size = (vec->vs) ?
            ilo_shader_get_kernel_param(vec->vs,
                  ILO_KERNEL_VS_PCB_UCP_SIZE) : 0;
      const int total_size = cbuf0_size + clip_state_size;

      if (total_size) {
         void *pcb;

         r->state.vs.PUSH_CONSTANT_BUFFER =
            gen6_push_constant_buffer(r->builder, total_size, &pcb);
         r->state.vs.PUSH_CONSTANT_BUFFER_size = total_size;

         if (cbuf0_size) {
            const struct ilo_cbuf_state *cbuf =
               &vec->cbuf[PIPE_SHADER_VERTEX];

            if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
               memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
            } else {
               memcpy(pcb, cbuf->cso[0].user_buffer,
                     cbuf->cso[0].user_buffer_size);
               memset(pcb + cbuf->cso[0].user_buffer_size, 0,
                     cbuf0_size - cbuf->cso[0].user_buffer_size);
            }

            pcb += cbuf0_size;
         }

         if (clip_state_size)
            memcpy(pcb, &vec->clip, clip_state_size);

         session->pcb_vs_changed = true;
      } else if (r->state.vs.PUSH_CONSTANT_BUFFER_size) {
         r->state.vs.PUSH_CONSTANT_BUFFER = 0;
         r->state.vs.PUSH_CONSTANT_BUFFER_size = 0;

         session->pcb_vs_changed = true;
      }
   }

   /* push constant buffer for FS */
   if (DIRTY(FS) || DIRTY(CBUF)) {
      const int cbuf0_size = (vec->fs) ?
         ilo_shader_get_kernel_param(vec->fs, ILO_KERNEL_PCB_CBUF0_SIZE) : 0;

      if (cbuf0_size) {
         const struct ilo_cbuf_state *cbuf = &vec->cbuf[PIPE_SHADER_FRAGMENT];
         void *pcb;

         r->state.wm.PUSH_CONSTANT_BUFFER =
            gen6_push_constant_buffer(r->builder, cbuf0_size, &pcb);
         r->state.wm.PUSH_CONSTANT_BUFFER_size = cbuf0_size;

         if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
            memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
         } else {
            memcpy(pcb, cbuf->cso[0].user_buffer,
                  cbuf->cso[0].user_buffer_size);
            memset(pcb + cbuf->cso[0].user_buffer_size, 0,
                  cbuf0_size - cbuf->cso[0].user_buffer_size);
         }

         session->pcb_fs_changed = true;
      } else if (r->state.wm.PUSH_CONSTANT_BUFFER_size) {
         r->state.wm.PUSH_CONSTANT_BUFFER = 0;
         r->state.wm.PUSH_CONSTANT_BUFFER_size = 0;

         session->pcb_fs_changed = true;
      }
   }
}
Exemple #22
0
static void
gen6_emit_draw_dynamic_samplers(struct ilo_render *r,
                                const struct ilo_state_vector *vec,
                                int shader_type,
                                struct ilo_render_draw_session *session)
{
   const struct ilo_sampler_cso * const *samplers =
      vec->sampler[shader_type].cso;
   const struct pipe_sampler_view * const *views =
      (const struct pipe_sampler_view **) vec->view[shader_type].states;
   uint32_t *sampler_state, *border_color_state;
   int sampler_count;
   bool emit_border_color = false;
   bool skip = false;

   ILO_DEV_ASSERT(r->dev, 6, 7.5);

   /* SAMPLER_BORDER_COLOR_STATE and SAMPLER_STATE */
   switch (shader_type) {
   case PIPE_SHADER_VERTEX:
      if (DIRTY(VS) || DIRTY(SAMPLER_VS) || DIRTY(VIEW_VS)) {
         sampler_state = &r->state.vs.SAMPLER_STATE;
         border_color_state = r->state.vs.SAMPLER_BORDER_COLOR_STATE;

         if (DIRTY(VS) || DIRTY(SAMPLER_VS))
            emit_border_color = true;

         sampler_count = (vec->vs) ? ilo_shader_get_kernel_param(vec->vs,
               ILO_KERNEL_SAMPLER_COUNT) : 0;

         session->sampler_vs_changed = true;
      } else {
         skip = true;
      }
      break;
   case PIPE_SHADER_FRAGMENT:
      if (DIRTY(FS) || DIRTY(SAMPLER_FS) || DIRTY(VIEW_FS)) {
         sampler_state = &r->state.wm.SAMPLER_STATE;
         border_color_state = r->state.wm.SAMPLER_BORDER_COLOR_STATE;

         if (DIRTY(VS) || DIRTY(SAMPLER_FS))
            emit_border_color = true;

         sampler_count = (vec->fs) ? ilo_shader_get_kernel_param(vec->fs,
               ILO_KERNEL_SAMPLER_COUNT) : 0;

         session->sampler_fs_changed = true;
      } else {
         skip = true;
      }
      break;
   default:
      skip = true;
      break;
   }

   if (skip)
      return;

   assert(sampler_count <= Elements(vec->view[shader_type].states) &&
          sampler_count <= Elements(vec->sampler[shader_type].cso));

   if (emit_border_color) {
      int i;

      for (i = 0; i < sampler_count; i++) {
         border_color_state[i] = (samplers[i]) ?
            gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, samplers[i]) : 0;
      }
   }

   *sampler_state = gen6_SAMPLER_STATE(r->builder,
         samplers, views, border_color_state, sampler_count);
}