Example #1
0
void
util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
                                         const uint8_t *src_row, unsigned src_stride,
                                         unsigned width, unsigned height)
{
   unsigned x, y;
   float p[3];
   for(y = 0; y < height; y += 1) {
      uint8_t *dst = dst_row;
      const uint8_t *src = src_row;
      for(x = 0; x < width; x += 1) {
         uint32_t value = *(const uint32_t *)src;
#ifdef PIPE_ARCH_BIG_ENDIAN
         value = util_bswap32(value);
#endif
         rgb9e5_to_float3(value, p);
         dst[0] = float_to_ubyte(p[0]); /* r */
         dst[1] = float_to_ubyte(p[1]); /* g */
         dst[2] = float_to_ubyte(p[2]); /* b */
         dst[3] = 255; /* a */
         src += 4;
         dst += 4;
      }
      src_row += src_stride;
      dst_row += dst_stride/sizeof(*dst_row);
   }
}
Example #2
0
static inline void
util_format_dxtn_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
                                 const float *src, unsigned src_stride,
                                 unsigned width, unsigned height,
                                 enum util_format_dxtn format,
                                 unsigned block_size, boolean srgb)
{
   unsigned x, y, i, j, k;
   for(y = 0; y < height; y += 4) {
      uint8_t *dst = dst_row;
      for(x = 0; x < width; x += 4) {
         uint8_t tmp[4][4][4];
         for(j = 0; j < 4; ++j) {
            for(i = 0; i < 4; ++i) {
               float src_tmp;
               for(k = 0; k < 3; ++k) {
                  src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k];
                  if (srgb) {
                     tmp[j][i][k] = util_format_linear_float_to_srgb_8unorm(src_tmp);
                  }
                  else {
                     tmp[j][i][k] = float_to_ubyte(src_tmp);
                  }
               }
               /* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */
               src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + 3];
               tmp[j][i][3] = float_to_ubyte(src_tmp);
            }
         }
         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0);
         dst += block_size;
      }
      dst_row += 4*dst_stride/sizeof(*dst_row);
   }
}
Example #3
0
	uint32_t Color::as_uint32() const
	{
		return static_cast<uint32_t>(((
			float_to_ubyte(alpha) << 24) |
			(float_to_ubyte(blue) << 16) |
			(float_to_ubyte(green) << 8) |
			float_to_ubyte(red)));
	}
Example #4
0
void
debug_dump_float_rgba_bmp(const char *filename,
                          unsigned width, unsigned height,
                          float *rgba, unsigned stride)
{
#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
   struct os_stream *stream;
   struct bmp_file_header bmfh;
   struct bmp_info_header bmih;
   unsigned x, y;

   if(!rgba)
      goto error1;

   bmfh.bfType = 0x4d42;
   bmfh.bfSize = 14 + 40 + height*width*4;
   bmfh.bfReserved1 = 0;
   bmfh.bfReserved2 = 0;
   bmfh.bfOffBits = 14 + 40;

   bmih.biSize = 40;
   bmih.biWidth = width;
   bmih.biHeight = height;
   bmih.biPlanes = 1;
   bmih.biBitCount = 32;
   bmih.biCompression = 0;
   bmih.biSizeImage = height*width*4;
   bmih.biXPelsPerMeter = 0;
   bmih.biYPelsPerMeter = 0;
   bmih.biClrUsed = 0;
   bmih.biClrImportant = 0;

   stream = os_file_stream_create(filename);
   if(!stream)
      goto error1;

   os_stream_write(stream, &bmfh, 14);
   os_stream_write(stream, &bmih, 40);

   y = height;
   while(y--) {
      float *ptr = rgba + (stride * y * 4);
      for(x = 0; x < width; ++x)
      {
         struct bmp_rgb_quad pixel;
         pixel.rgbRed   = float_to_ubyte(ptr[x*4 + 0]);
         pixel.rgbGreen = float_to_ubyte(ptr[x*4 + 1]);
         pixel.rgbBlue  = float_to_ubyte(ptr[x*4 + 2]);
         pixel.rgbAlpha = 255;
         os_stream_write(stream, &pixel, 4);
      }
   }

   os_stream_close(stream);
error1:
   ;
#endif
}
Example #5
0
void
debug_dump_float_rgba_bmp(const char *filename,
                          unsigned width, unsigned height,
                          float *rgba, unsigned stride)
{
   FILE *stream;
   struct bmp_file_header bmfh;
   struct bmp_info_header bmih;
   unsigned x, y;

   if(!rgba)
      goto error1;

   bmfh.bfType = 0x4d42;
   bmfh.bfSize = 14 + 40 + height*width*4;
   bmfh.bfReserved1 = 0;
   bmfh.bfReserved2 = 0;
   bmfh.bfOffBits = 14 + 40;

   bmih.biSize = 40;
   bmih.biWidth = width;
   bmih.biHeight = height;
   bmih.biPlanes = 1;
   bmih.biBitCount = 32;
   bmih.biCompression = 0;
   bmih.biSizeImage = height*width*4;
   bmih.biXPelsPerMeter = 0;
   bmih.biYPelsPerMeter = 0;
   bmih.biClrUsed = 0;
   bmih.biClrImportant = 0;

   stream = fopen(filename, "wb");
   if(!stream)
      goto error1;

   fwrite(&bmfh, 14, 1, stream);
   fwrite(&bmih, 40, 1, stream);

   y = height;
   while(y--) {
      float *ptr = rgba + (stride * y * 4);
      for(x = 0; x < width; ++x)
      {
         struct bmp_rgb_quad pixel;
         pixel.rgbRed   = float_to_ubyte(ptr[x*4 + 0]);
         pixel.rgbGreen = float_to_ubyte(ptr[x*4 + 1]);
         pixel.rgbBlue  = float_to_ubyte(ptr[x*4 + 2]);
         pixel.rgbAlpha = float_to_ubyte(ptr[x*4 + 3]);
         fwrite(&pixel, 1, 4, stream);
      }
   }

   fclose(stream);
error1:
   ;
}
Example #6
0
static void *
nv30_sampler_state_create(struct pipe_context *pipe,
                          const struct pipe_sampler_state *cso)
{
   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
   struct nv30_sampler_state *so;
   const float max_lod = 15.0 + (255.0 / 256.0);

   so = MALLOC_STRUCT(nv30_sampler_state);
   if (!so)
      return NULL;

   so->pipe  = *cso;
   so->fmt   = 0;
   so->wrap  = (wrap_mode(cso->wrap_s) << NV30_3D_TEX_WRAP_S__SHIFT) |
               (wrap_mode(cso->wrap_t) << NV30_3D_TEX_WRAP_T__SHIFT) |
               (wrap_mode(cso->wrap_r) << NV30_3D_TEX_WRAP_R__SHIFT);
   so->en    = 0;
   so->wrap |= compare_mode(cso);
   so->filt  = filter_mode(cso) | 0x00002000;
   so->bcol  = (float_to_ubyte(cso->border_color.f[3]) << 24) |
               (float_to_ubyte(cso->border_color.f[0]) << 16) |
               (float_to_ubyte(cso->border_color.f[1]) <<  8) |
               (float_to_ubyte(cso->border_color.f[2]) <<  0);

   if (eng3d->oclass >= NV40_3D_CLASS) {
      unsigned aniso = cso->max_anisotropy;

      if (!cso->normalized_coords)
         so->fmt |= NV40_3D_TEX_FORMAT_RECT;

      if (aniso > 1) {
         if      (aniso >= 16) so->en |= NV40_3D_TEX_ENABLE_ANISO_16X;
         else if (aniso >= 12) so->en |= NV40_3D_TEX_ENABLE_ANISO_12X;
         else if (aniso >= 10) so->en |= NV40_3D_TEX_ENABLE_ANISO_10X;
         else if (aniso >=  8) so->en |= NV40_3D_TEX_ENABLE_ANISO_8X;
         else if (aniso >=  6) so->en |= NV40_3D_TEX_ENABLE_ANISO_6X;
         else if (aniso >=  4) so->en |= NV40_3D_TEX_ENABLE_ANISO_4X;
         else                  so->en |= NV40_3D_TEX_ENABLE_ANISO_2X;

         so->wrap |= nv30_context(pipe)->config.aniso;
      }
   } else {
      so->en |= NV30_3D_TEX_ENABLE_ENABLE;

      if      (cso->max_anisotropy >= 8) so->en |= NV30_3D_TEX_ENABLE_ANISO_8X;
      else if (cso->max_anisotropy >= 4) so->en |= NV30_3D_TEX_ENABLE_ANISO_4X;
      else if (cso->max_anisotropy >= 2) so->en |= NV30_3D_TEX_ENABLE_ANISO_2X;
   }

   so->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
   so->max_lod = (int)(CLAMP(cso->max_lod, 0.0, max_lod) * 256.0);
   so->min_lod = (int)(CLAMP(cso->min_lod, 0.0, max_lod) * 256.0);
   return so;
}
Example #7
0
static void *
svga_create_sampler_state(struct pipe_context *pipe,
                          const struct pipe_sampler_state *sampler)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_sampler_state *cso = CALLOC_STRUCT( svga_sampler_state );
   
   cso->mipfilter = translate_mip_filter(sampler->min_mip_filter);
   cso->magfilter = translate_img_filter( sampler->mag_img_filter );
   cso->minfilter = translate_img_filter( sampler->min_img_filter );
   cso->aniso_level = MAX2( (unsigned) sampler->max_anisotropy, 1 );
   cso->lod_bias = sampler->lod_bias;
   cso->addressu = translate_wrap_mode(sampler->wrap_s);
   cso->addressv = translate_wrap_mode(sampler->wrap_t);
   cso->addressw = translate_wrap_mode(sampler->wrap_r);
   cso->normalized_coords = sampler->normalized_coords;
   cso->compare_mode = sampler->compare_mode;
   cso->compare_func = sampler->compare_func;

   {
      ubyte r = float_to_ubyte(sampler->border_color[0]);
      ubyte g = float_to_ubyte(sampler->border_color[1]);
      ubyte b = float_to_ubyte(sampler->border_color[2]);
      ubyte a = float_to_ubyte(sampler->border_color[3]);

      util_pack_color_ub( r, g, b, a,
                          PIPE_FORMAT_B8G8R8A8_UNORM,
                          &cso->bordercolor );
   }

   /* No SVGA3D support for:
    *    - min/max LOD clamping
    */
   cso->min_lod = 0;
   cso->view_min_lod = MAX2(sampler->min_lod, 0);
   cso->view_max_lod = MAX2(sampler->max_lod, 0);

   /* Use min_mipmap */
   if (svga->debug.use_min_mipmap) {
      if (cso->view_min_lod == cso->view_max_lod) {
         cso->min_lod = cso->view_min_lod;
         cso->view_min_lod = 0;
         cso->view_max_lod = 1000; /* Just a high number */
         cso->mipfilter = SVGA3D_TEX_FILTER_NONE;
      }
   }

   SVGA_DBG(DEBUG_VIEWS, "min %u, view(min %u, max %u) lod, mipfilter %s\n",
            cso->min_lod, cso->view_min_lod, cso->view_max_lod,
            cso->mipfilter == SVGA3D_TEX_FILTER_NONE ? "SVGA3D_TEX_FILTER_NONE" : "SOMETHING");

   return cso;
}
Example #8
0
void
nvfx_state_blend_colour_validate(struct nvfx_context *nvfx)
{
	struct nouveau_channel* chan = nvfx->screen->base.channel;
	struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
	struct pipe_blend_color *bcol = &nvfx->blend_colour;

	BEGIN_RING(chan, eng3d, NV30_3D_BLEND_COLOR, 1);
	OUT_RING(chan, ((float_to_ubyte(bcol->color[3]) << 24) |
		       (float_to_ubyte(bcol->color[0]) << 16) |
		       (float_to_ubyte(bcol->color[1]) <<  8) |
		       (float_to_ubyte(bcol->color[2]) <<  0)));
}
Example #9
0
void image_clear(struct vg_image *img,
                 VGint x, VGint y, VGint width, VGint height)
{
   struct vg_context *ctx = vg_current_context();
   VGfloat *clear_colorf = ctx->state.vg.clear_color;
   VGubyte r, g, b ,a;
   VGint clear_colori;
   /* FIXME: this is very nasty */
   r = float_to_ubyte(clear_colorf[0]);
   g = float_to_ubyte(clear_colorf[1]);
   b = float_to_ubyte(clear_colorf[2]);
   a = float_to_ubyte(clear_colorf[3]);
   clear_colori = r << 24 | g << 16 | b << 8 | a;
   image_cleari(img, clear_colori, x, y, width, height);
}
static boolean
nv40_state_blend_colour_validate(struct nv40_context *nv40)
{
	struct nouveau_stateobj *so = so_new(2, 0);
	struct pipe_blend_color *bcol = &nv40->blend_colour;

	so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1);
	so_data  (so, ((float_to_ubyte(bcol->color[3]) << 24) |
		       (float_to_ubyte(bcol->color[0]) << 16) |
		       (float_to_ubyte(bcol->color[1]) <<  8) |
		       (float_to_ubyte(bcol->color[2]) <<  0)));

	so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]);
	so_ref(NULL, &so);
	return TRUE;
}
Example #11
0
/**
 * Extract the needed fields from vertex_header and emit i915 dwords.
 * Recall that the vertices are constructed by the 'draw' module and
 * have a couple of slots at the beginning (1-dword header, 4-dword
 * clip pos) that we ignore here.
 */
static INLINE void
emit_hw_vertex( struct i915_context *i915,
                const struct vertex_header *vertex)
{
   const struct vertex_info *vinfo = &i915->current.vertex_info;
   uint i;
   uint count = 0;  /* for debug/sanity */

   assert(!i915->dirty);

   for (i = 0; i < vinfo->num_attribs; i++) {
      const uint j = vinfo->attrib[i].src_index;
      const float *attrib = vertex->data[j];
      switch (vinfo->attrib[i].emit) {
      case EMIT_1F:
         OUT_BATCH( fui(attrib[0]) );
         count++;
         break;
      case EMIT_2F:
         OUT_BATCH( fui(attrib[0]) );
         OUT_BATCH( fui(attrib[1]) );
         count += 2;
         break;
      case EMIT_3F:
         OUT_BATCH( fui(attrib[0]) );
         OUT_BATCH( fui(attrib[1]) );
         OUT_BATCH( fui(attrib[2]) );
         count += 3;
         break;
      case EMIT_4F:
         OUT_BATCH( fui(attrib[0]) );
         OUT_BATCH( fui(attrib[1]) );
         OUT_BATCH( fui(attrib[2]) );
         OUT_BATCH( fui(attrib[3]) );
         count += 4;
         break;
      case EMIT_4UB:
         OUT_BATCH( pack_ub4(float_to_ubyte( attrib[0] ),
                             float_to_ubyte( attrib[1] ),
                             float_to_ubyte( attrib[2] ),
                             float_to_ubyte( attrib[3] )) );
         count += 1;
         break;
      case EMIT_4UB_BGRA:
         OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ),
                             float_to_ubyte( attrib[1] ),
                             float_to_ubyte( attrib[0] ),
                             float_to_ubyte( attrib[3] )) );
         count += 1;
         break;
      default:
         assert(0);
      }
   }
   assert(count == vinfo->size);
}
Example #12
0
static void
vc4_set_blend_color(struct pipe_context *pctx,
                    const struct pipe_blend_color *blend_color)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        vc4->blend_color.f = *blend_color;
        for (int i = 0; i < 4; i++)
                vc4->blend_color.ub[i] = float_to_ubyte(blend_color->color[i]);
        vc4->dirty |= VC4_DIRTY_BLEND_COLOR;
}
Example #13
0
static void *
nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
			const struct pipe_depth_stencil_alpha_state *cso)
{
	struct nv40_context *nv40 = nv40_context(pipe);
	struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
	struct nouveau_stateobj *so = so_new(32, 0);
	struct nouveau_grobj *curie = nv40->screen->curie;

	so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
	so_data  (so, nvgl_comparison_op(cso->depth.func));
	so_data  (so, cso->depth.writemask ? 1 : 0);
	so_data  (so, cso->depth.enabled ? 1 : 0);

	so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
	so_data  (so, cso->alpha.enabled ? 1 : 0);
	so_data  (so, nvgl_comparison_op(cso->alpha.func));
	so_data  (so, float_to_ubyte(cso->alpha.ref_value));

	if (cso->stencil[0].enabled) {
		so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
		so_data  (so, cso->stencil[0].enabled ? 1 : 0);
		so_data  (so, cso->stencil[0].writemask);
		so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
		so_data  (so, cso->stencil[0].ref_value);
		so_data  (so, cso->stencil[0].valuemask);
		so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
		so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
		so_data  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
	} else {
		so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
		so_data  (so, 0);
	}

	if (cso->stencil[1].enabled) {
		so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
		so_data  (so, cso->stencil[1].enabled ? 1 : 0);
		so_data  (so, cso->stencil[1].writemask);
		so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
		so_data  (so, cso->stencil[1].ref_value);
		so_data  (so, cso->stencil[1].valuemask);
		so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
		so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
		so_data  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
	} else {
		so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
		so_data  (so, 0);
	}

	so_ref(so, &zsaso->so);
	so_ref(NULL, &so);
	zsaso->pipe = *cso;
	return (void *)zsaso;
}
Example #14
0
void
util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
{
   const unsigned bw = 4, bh = 4, bytes_per_block = 16;
   unsigned x, y, i, j;

   for(y = 0; y < height; y += bh) {
      uint8_t *dst = dst_row;
      for(x = 0; x < width; x += bw) {
         uint8_t tmp_r[4][4];  /* [bh][bw][comps] */
         uint8_t tmp_g[4][4];  /* [bh][bw][comps] */
         for(j = 0; j < bh; ++j) {
            for(i = 0; i < bw; ++i) {
	       tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
               tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
            }
         }
         u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
         u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
         dst += bytes_per_block;
      }
      dst_row += dst_stride / sizeof(*dst_row);
   }
}
static void create_bcc_state( struct brw_depth_stencil_state *zstencil,
			      const struct pipe_depth_stencil_alpha_state *templ )
{
   if (templ->stencil[0].enabled) {
      zstencil->cc0.stencil_enable = 1;
      zstencil->cc0.stencil_func =
	 brw_translate_compare_func(templ->stencil[0].func);
      zstencil->cc0.stencil_fail_op =
	 translate_stencil_op(templ->stencil[0].fail_op);
      zstencil->cc0.stencil_pass_depth_fail_op =
	 translate_stencil_op(templ->stencil[0].zfail_op);
      zstencil->cc0.stencil_pass_depth_pass_op =
	 translate_stencil_op(templ->stencil[0].zpass_op);
      zstencil->cc1.stencil_write_mask = templ->stencil[0].writemask;
      zstencil->cc1.stencil_test_mask = templ->stencil[0].valuemask;

      if (templ->stencil[1].enabled) {
	 zstencil->cc0.bf_stencil_enable = 1;
	 zstencil->cc0.bf_stencil_func =
	    brw_translate_compare_func(templ->stencil[1].func);
	 zstencil->cc0.bf_stencil_fail_op =
	    translate_stencil_op(templ->stencil[1].fail_op);
	 zstencil->cc0.bf_stencil_pass_depth_fail_op =
	    translate_stencil_op(templ->stencil[1].zfail_op);
	 zstencil->cc0.bf_stencil_pass_depth_pass_op =
	    translate_stencil_op(templ->stencil[1].zpass_op);
	 zstencil->cc2.bf_stencil_write_mask = templ->stencil[1].writemask;
	 zstencil->cc2.bf_stencil_test_mask = templ->stencil[1].valuemask;
      }

      zstencil->cc0.stencil_write_enable = (zstencil->cc1.stencil_write_mask ||
					    zstencil->cc2.bf_stencil_write_mask);
   }


   if (templ->alpha.enabled) {
      zstencil->cc3.alpha_test = 1;
      zstencil->cc3.alpha_test_func = brw_translate_compare_func(templ->alpha.func);
      zstencil->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
      zstencil->cc7.alpha_ref.ub[0] = float_to_ubyte(templ->alpha.ref_value);
   }

   if (templ->depth.enabled) {
      zstencil->cc2.depth_test = 1;
      zstencil->cc2.depth_test_function = brw_translate_compare_func(templ->depth.func);
      zstencil->cc2.depth_write_enable = templ->depth.writemask;
   }
}
Example #16
0
/**
 * When a whole surface is being cleared to a value we can avoid
 * fetching tiles above.
 * Save the color and set a 'clearflag' for each tile of the screen.
 */
void
lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba,
                    uint clearValue)
{
   struct pipe_transfer *pt = tc->transfer;
   const unsigned w = pt->width;
   const unsigned h = pt->height;
   unsigned x, y, chan;

   for(chan = 0; chan < 4; ++chan)
      tc->clear_color[chan] = float_to_ubyte(rgba[chan]);

   tc->clear_val = clearValue;

   /* push the tile to all positions marked as clear */
   for (y = 0; y < h; y += TILE_SIZE) {
      for (x = 0; x < w; x += TILE_SIZE) {
         struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
         tile->status = LP_TILE_STATUS_CLEAR;
      }
   }
}
void
util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
                                      const float *src, unsigned src_stride,
                                      unsigned width, unsigned height)
{
   unsigned x, y, i, j, k;
   for(y = 0; y < height; y += 4) {
      uint8_t *dst = dst_row;
      for(x = 0; x < width; x += 4) {
         uint8_t tmp[4][4][4];
         for(j = 0; j < 4; ++j) {
            for(i = 0; i < 4; ++i) {
               for(k = 0; k < 4; ++k) {
                  tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
               }
            }
         }
         util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0);
         dst += 16;
      }
      dst_row += 4*dst_stride/sizeof(*dst_row);
   }
}
Example #18
0
void
fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
{
	struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend);
	struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa);
	struct fd_ringbuffer *ring = ctx->batch->draw;

	/* NOTE: we probably want to eventually refactor this so each state
	 * object handles emitting it's own state..  although the mapping of
	 * state to registers is not always orthogonal, sometimes a single
	 * register contains bitfields coming from multiple state objects,
	 * so not sure the best way to deal with that yet.
	 */

	if (dirty & FD_DIRTY_SAMPLE_MASK) {
		OUT_PKT3(ring, CP_SET_CONSTANT, 2);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK));
		OUT_RING(ring, ctx->sample_mask);
	}

	if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_STENCIL_REF)) {
		struct pipe_stencil_ref *sr = &ctx->stencil_ref;

		OUT_PKT3(ring, CP_SET_CONSTANT, 2);
		OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL));
		OUT_RING(ring, zsa->rb_depthcontrol);

		OUT_PKT3(ring, CP_SET_CONSTANT, 4);
		OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF));
		OUT_RING(ring, zsa->rb_stencilrefmask_bf |
				A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[1]));
		OUT_RING(ring, zsa->rb_stencilrefmask |
				A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0]));
		OUT_RING(ring, zsa->rb_alpha_ref);
	}

	if (ctx->rasterizer && dirty & FD_DIRTY_RASTERIZER) {
		struct fd2_rasterizer_stateobj *rasterizer =
				fd2_rasterizer_stateobj(ctx->rasterizer);
		OUT_PKT3(ring, CP_SET_CONSTANT, 3);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
		OUT_RING(ring, rasterizer->pa_cl_clip_cntl);
		OUT_RING(ring, rasterizer->pa_su_sc_mode_cntl |
				A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE);

		OUT_PKT3(ring, CP_SET_CONSTANT, 5);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_POINT_SIZE));
		OUT_RING(ring, rasterizer->pa_su_point_size);
		OUT_RING(ring, rasterizer->pa_su_point_minmax);
		OUT_RING(ring, rasterizer->pa_su_line_cntl);
		OUT_RING(ring, rasterizer->pa_sc_line_stipple);

		OUT_PKT3(ring, CP_SET_CONSTANT, 6);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_VTX_CNTL));
		OUT_RING(ring, rasterizer->pa_su_vtx_cntl);
		OUT_RING(ring, fui(1.0));                /* PA_CL_GB_VERT_CLIP_ADJ */
		OUT_RING(ring, fui(1.0));                /* PA_CL_GB_VERT_DISC_ADJ */
		OUT_RING(ring, fui(1.0));                /* PA_CL_GB_HORZ_CLIP_ADJ */
		OUT_RING(ring, fui(1.0));                /* PA_CL_GB_HORZ_DISC_ADJ */
	}

	/* NOTE: scissor enabled bit is part of rasterizer state: */
	if (dirty & (FD_DIRTY_SCISSOR | FD_DIRTY_RASTERIZER)) {
		struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);

		OUT_PKT3(ring, CP_SET_CONSTANT, 3);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
		OUT_RING(ring, xy2d(scissor->minx,       /* PA_SC_WINDOW_SCISSOR_TL */
				scissor->miny));
		OUT_RING(ring, xy2d(scissor->maxx,       /* PA_SC_WINDOW_SCISSOR_BR */
				scissor->maxy));

		ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx);
		ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny);
		ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);
		ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);
	}

	if (dirty & FD_DIRTY_VIEWPORT) {
		OUT_PKT3(ring, CP_SET_CONSTANT, 7);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE));
		OUT_RING(ring, fui(ctx->viewport.scale[0]));       /* PA_CL_VPORT_XSCALE */
		OUT_RING(ring, fui(ctx->viewport.translate[0]));   /* PA_CL_VPORT_XOFFSET */
		OUT_RING(ring, fui(ctx->viewport.scale[1]));       /* PA_CL_VPORT_YSCALE */
		OUT_RING(ring, fui(ctx->viewport.translate[1]));   /* PA_CL_VPORT_YOFFSET */
		OUT_RING(ring, fui(ctx->viewport.scale[2]));       /* PA_CL_VPORT_ZSCALE */
		OUT_RING(ring, fui(ctx->viewport.translate[2]));   /* PA_CL_VPORT_ZOFFSET */

		OUT_PKT3(ring, CP_SET_CONSTANT, 2);
		OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL));
		OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT |
				A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA |
				A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA |
				A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA |
				A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA |
				A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA |
				A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA);
	}

	if (dirty & (FD_DIRTY_PROG | FD_DIRTY_VTXSTATE | FD_DIRTY_TEXSTATE)) {
		fd2_program_validate(ctx);
		fd2_program_emit(ring, &ctx->prog);
	}

	if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONST)) {
		emit_constants(ring,  VS_CONST_BASE * 4,
				&ctx->constbuf[PIPE_SHADER_VERTEX],
				(dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL);
		emit_constants(ring, PS_CONST_BASE * 4,
				&ctx->constbuf[PIPE_SHADER_FRAGMENT],
				(dirty & FD_DIRTY_PROG) ? ctx->prog.fp : NULL);
	}

	if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_ZSA)) {
		OUT_PKT3(ring, CP_SET_CONSTANT, 2);
		OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL));
		OUT_RING(ring, blend ? zsa->rb_colorcontrol | blend->rb_colorcontrol : 0);
	}

	if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) {
		enum pipe_format format =
			pipe_surface_format(ctx->batch->framebuffer.cbufs[0]);
		bool has_alpha = util_format_has_alpha(format);

		OUT_PKT3(ring, CP_SET_CONSTANT, 2);
		OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL));
		OUT_RING(ring, blend ? blend->rb_blendcontrol_alpha |
			COND(has_alpha, blend->rb_blendcontrol_rgb) |
			COND(!has_alpha, blend->rb_blendcontrol_no_alpha_rgb) : 0);

		OUT_PKT3(ring, CP_SET_CONSTANT, 2);
		OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK));
		OUT_RING(ring, blend ? blend->rb_colormask : 0xf);
	}

	if (dirty & FD_DIRTY_BLEND_COLOR) {
		OUT_PKT3(ring, CP_SET_CONSTANT, 5);
		OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED));
		OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[0]));
		OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[1]));
		OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[2]));
		OUT_RING(ring, float_to_ubyte(ctx->blend_color.color[3]));
	}

	if (dirty & (FD_DIRTY_TEX | FD_DIRTY_PROG))
		emit_textures(ring, ctx);
}
Example #19
0
/**
 * Called by vbuf code when we're about to draw something.
 *
 * This function stores all dirty state in the current scene's display list
 * memory, via lp_scene_alloc().  We can not pass pointers of mutable state to
 * the JIT functions, as the JIT functions will be called later on, most likely
 * on a different thread.
 *
 * When processing dirty state it is imperative that we don't refer to any
 * pointers previously allocated with lp_scene_alloc() in this function (or any
 * function) as they may belong to a scene freed since then.
 */
static boolean
try_update_scene_state( struct lp_setup_context *setup )
{
   static const float fake_const_buf[4];
   boolean new_scene = (setup->fs.stored == NULL);
   struct lp_scene *scene = setup->scene;
   unsigned i;

   assert(scene);

   if (setup->dirty & LP_SETUP_NEW_VIEWPORTS) {
      /*
       * Record new depth range state for changes due to viewport updates.
       *
       * TODO: Collapse the existing viewport and depth range information
       *       into one structure, for access by JIT.
       */
      struct lp_jit_viewport *stored;

      stored = (struct lp_jit_viewport *)
         lp_scene_alloc(scene, sizeof setup->viewports);

      if (!stored) {
         assert(!new_scene);
         return FALSE;
      }

      memcpy(stored, setup->viewports, sizeof setup->viewports);

      setup->fs.current.jit_context.viewports = stored;
      setup->dirty |= LP_SETUP_NEW_FS;
   }

   if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
      uint8_t *stored;
      float* fstored;
      unsigned i, j;
      unsigned size;

      /* Alloc u8_blend_color (16 x i8) and f_blend_color (4 or 8 x f32) */
      size  = 4 * 16 * sizeof(uint8_t);
      size += (LP_MAX_VECTOR_LENGTH / 4) * sizeof(float);
      stored = lp_scene_alloc_aligned(scene, size, LP_MIN_VECTOR_ALIGN);

      if (!stored) {
         assert(!new_scene);
         return FALSE;
      }

      /* Store floating point colour */
      fstored = (float*)(stored + 4*16);
      for (i = 0; i < (LP_MAX_VECTOR_LENGTH / 4); ++i) {
         fstored[i] = setup->blend_color.current.color[i % 4];
      }

      /* smear each blend color component across 16 ubyte elements */
      for (i = 0; i < 4; ++i) {
         uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]);
         for (j = 0; j < 16; ++j)
            stored[i*16 + j] = c;
      }

      setup->blend_color.stored = stored;
      setup->fs.current.jit_context.u8_blend_color = stored;
      setup->fs.current.jit_context.f_blend_color = fstored;
      setup->dirty |= LP_SETUP_NEW_FS;
   }

   if (setup->dirty & LP_SETUP_NEW_CONSTANTS) {
      for (i = 0; i < ARRAY_SIZE(setup->constants); ++i) {
         struct pipe_resource *buffer = setup->constants[i].current.buffer;
         const unsigned current_size = MIN2(setup->constants[i].current.buffer_size,
                                            LP_MAX_TGSI_CONST_BUFFER_SIZE);
         const ubyte *current_data = NULL;
         int num_constants;

         STATIC_ASSERT(DATA_BLOCK_SIZE >= LP_MAX_TGSI_CONST_BUFFER_SIZE);

         if (buffer) {
            /* resource buffer */
            current_data = (ubyte *) llvmpipe_resource_data(buffer);
         }
         else if (setup->constants[i].current.user_buffer) {
            /* user-space buffer */
            current_data = (ubyte *) setup->constants[i].current.user_buffer;
         }

         if (current_data) {
            current_data += setup->constants[i].current.buffer_offset;

            /* TODO: copy only the actually used constants? */

            if (setup->constants[i].stored_size != current_size ||
               !setup->constants[i].stored_data ||
               memcmp(setup->constants[i].stored_data,
                      current_data,
                      current_size) != 0) {
               void *stored;

               stored = lp_scene_alloc(scene, current_size);
               if (!stored) {
                  assert(!new_scene);
                  return FALSE;
               }

               memcpy(stored,
                      current_data,
                      current_size);
               setup->constants[i].stored_size = current_size;
               setup->constants[i].stored_data = stored;
            }
            setup->fs.current.jit_context.constants[i] =
               setup->constants[i].stored_data;
         }
         else {
            setup->constants[i].stored_size = 0;
            setup->constants[i].stored_data = NULL;
            setup->fs.current.jit_context.constants[i] = fake_const_buf;
         }

         num_constants =
            setup->constants[i].stored_size / (sizeof(float) * 4);
         setup->fs.current.jit_context.num_constants[i] = num_constants;
         setup->dirty |= LP_SETUP_NEW_FS;
      }
   }


   if (setup->dirty & LP_SETUP_NEW_FS) {
      if (!setup->fs.stored ||
          memcmp(setup->fs.stored,
                 &setup->fs.current,
                 sizeof setup->fs.current) != 0)
      {
         struct lp_rast_state *stored;
         
         /* The fs state that's been stored in the scene is different from
          * the new, current state.  So allocate a new lp_rast_state object
          * and append it to the bin's setup data buffer.
          */
         stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
         if (!stored) {
            assert(!new_scene);
            return FALSE;
         }

         memcpy(stored,
                &setup->fs.current,
                sizeof setup->fs.current);
         setup->fs.stored = stored;
         
         /* The scene now references the textures in the rasterization
          * state record.  Note that now.
          */
         for (i = 0; i < ARRAY_SIZE(setup->fs.current_tex); i++) {
            if (setup->fs.current_tex[i]) {
               if (!lp_scene_add_resource_reference(scene,
                                                    setup->fs.current_tex[i],
                                                    new_scene)) {
                  assert(!new_scene);
                  return FALSE;
               }
            }
         }
      }
   }

   if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
      unsigned i;
      for (i = 0; i < PIPE_MAX_VIEWPORTS; ++i) {
         setup->draw_regions[i] = setup->framebuffer;
         if (setup->scissor_test) {
            u_rect_possible_intersection(&setup->scissors[i],
                                         &setup->draw_regions[i]);
         }
      }
   }

   setup->dirty = 0;

   assert(setup->fs.stored);
   return TRUE;
}
Example #20
0
/**
 * Called by vbuf code when we're about to draw something.
 */
static boolean
try_update_scene_state( struct lp_setup_context *setup )
{
   boolean new_scene = (setup->fs.stored == NULL);
   struct lp_scene *scene = setup->scene;
   unsigned i;

   assert(scene);

   if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
      uint8_t *stored;
      float* fstored;
      unsigned i, j;
      unsigned size;

      /* Alloc u8_blend_color (16 x i8) and f_blend_color (4 or 8 x f32) */
      size  = 4 * 16 * sizeof(uint8_t);
      size += (LP_MAX_VECTOR_LENGTH / 4) * sizeof(float);
      stored = lp_scene_alloc_aligned(scene, size, LP_MAX_VECTOR_LENGTH);

      if (!stored) {
         assert(!new_scene);
         return FALSE;
      }

      /* Store floating point colour */
      fstored = (float*)(stored + 4*16);
      for (i = 0; i < (LP_MAX_VECTOR_LENGTH / 4); ++i) {
         fstored[i] = setup->blend_color.current.color[i % 4];
      }

      /* smear each blend color component across 16 ubyte elements */
      for (i = 0; i < 4; ++i) {
         uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]);
         for (j = 0; j < 16; ++j)
            stored[i*16 + j] = c;
      }

      setup->blend_color.stored = stored;
      setup->fs.current.jit_context.u8_blend_color = stored;
      setup->fs.current.jit_context.f_blend_color = fstored;
      setup->dirty |= LP_SETUP_NEW_FS;
   }

   if (setup->dirty & LP_SETUP_NEW_CONSTANTS) {
      for (i = 0; i < Elements(setup->constants); ++i) {
         struct pipe_resource *buffer = setup->constants[i].current.buffer;
         const unsigned current_size = setup->constants[i].current.buffer_size;
         const ubyte *current_data = NULL;

         if (buffer) {
            /* resource buffer */
            current_data = (ubyte *) llvmpipe_resource_data(buffer);
         }
         else if (setup->constants[i].current.user_buffer) {
            /* user-space buffer */
            current_data = (ubyte *) setup->constants[i].current.user_buffer;
         }

         if (current_data) {
            current_data += setup->constants[i].current.buffer_offset;

            /* TODO: copy only the actually used constants? */

            if (setup->constants[i].stored_size != current_size ||
               !setup->constants[i].stored_data ||
               memcmp(setup->constants[i].stored_data,
                      current_data,
                      current_size) != 0) {
               void *stored;

               stored = lp_scene_alloc(scene, current_size);
               if (!stored) {
                  assert(!new_scene);
                  return FALSE;
               }

               memcpy(stored,
                      current_data,
                      current_size);
               setup->constants[i].stored_size = current_size;
               setup->constants[i].stored_data = stored;
            }
         }
         else {
            setup->constants[i].stored_size = 0;
            setup->constants[i].stored_data = NULL;
         }

         setup->fs.current.jit_context.constants[i] = setup->constants[i].stored_data;
         setup->dirty |= LP_SETUP_NEW_FS;
      }
   }


   if (setup->dirty & LP_SETUP_NEW_FS) {
      if (!setup->fs.stored ||
          memcmp(setup->fs.stored,
                 &setup->fs.current,
                 sizeof setup->fs.current) != 0)
      {
         struct lp_rast_state *stored;
         
         /* The fs state that's been stored in the scene is different from
          * the new, current state.  So allocate a new lp_rast_state object
          * and append it to the bin's setup data buffer.
          */
         stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
         if (!stored) {
            assert(!new_scene);
            return FALSE;
         }

         memcpy(stored,
                &setup->fs.current,
                sizeof setup->fs.current);
         setup->fs.stored = stored;
         
         /* The scene now references the textures in the rasterization
          * state record.  Note that now.
          */
         for (i = 0; i < Elements(setup->fs.current_tex); i++) {
            if (setup->fs.current_tex[i]) {
               if (!lp_scene_add_resource_reference(scene,
                                                    setup->fs.current_tex[i],
                                                    new_scene)) {
                  assert(!new_scene);
                  return FALSE;
               }
            }
         }
      }
   }

   if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
      setup->draw_region = setup->framebuffer;
      if (setup->scissor_test) {
         u_rect_possible_intersection(&setup->scissor,
                                      &setup->draw_region);
      }
   }
                                      
   setup->dirty = 0;

   assert(setup->fs.stored);
   return TRUE;
}
Example #21
0
/**
 * Called by vbuf code when we're about to draw something.
 */
static boolean
try_update_scene_state( struct lp_setup_context *setup )
{
   boolean new_scene = (setup->fs.stored == NULL);
   struct lp_scene *scene = setup->scene;

   assert(scene);

   if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
      uint8_t *stored;
      unsigned i, j;

      stored = lp_scene_alloc_aligned(scene, 4 * 16, 16);
      if (!stored) {
         assert(!new_scene);
         return FALSE;
      }

      /* smear each blend color component across 16 ubyte elements */
      for (i = 0; i < 4; ++i) {
         uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]);
         for (j = 0; j < 16; ++j)
            stored[i*16 + j] = c;
      }

      setup->blend_color.stored = stored;
      setup->fs.current.jit_context.blend_color = setup->blend_color.stored;
      setup->dirty |= LP_SETUP_NEW_FS;
   }

   if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {
      struct pipe_resource *buffer = setup->constants.current;

      if(buffer) {
         unsigned current_size = buffer->width0;
         const void *current_data = llvmpipe_resource_data(buffer);

         /* TODO: copy only the actually used constants? */

         if(setup->constants.stored_size != current_size ||
            !setup->constants.stored_data ||
            memcmp(setup->constants.stored_data,
                   current_data,
                   current_size) != 0) {
            void *stored;

            stored = lp_scene_alloc(scene, current_size);
            if (!stored) {
               assert(!new_scene);
               return FALSE;
            }

            memcpy(stored,
                   current_data,
                   current_size);
            setup->constants.stored_size = current_size;
            setup->constants.stored_data = stored;
         }
      }
      else {
         setup->constants.stored_size = 0;
         setup->constants.stored_data = NULL;
      }

      setup->fs.current.jit_context.constants = setup->constants.stored_data;
      setup->dirty |= LP_SETUP_NEW_FS;
   }


   if (setup->dirty & LP_SETUP_NEW_FS) {
      if (!setup->fs.stored ||
          memcmp(setup->fs.stored,
                 &setup->fs.current,
                 sizeof setup->fs.current) != 0)
      {
         struct lp_rast_state *stored;
         uint i;
         
         /* The fs state that's been stored in the scene is different from
          * the new, current state.  So allocate a new lp_rast_state object
          * and append it to the bin's setup data buffer.
          */
         stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
         if (!stored) {
            assert(!new_scene);
            return FALSE;
         }

         memcpy(stored,
                &setup->fs.current,
                sizeof setup->fs.current);
         setup->fs.stored = stored;
         
         /* The scene now references the textures in the rasterization
          * state record.  Note that now.
          */
         for (i = 0; i < Elements(setup->fs.current_tex); i++) {
            if (setup->fs.current_tex[i]) {
               if (!lp_scene_add_resource_reference(scene,
                                                    setup->fs.current_tex[i],
                                                    new_scene)) {
                  assert(!new_scene);
                  return FALSE;
               }
            }
         }
      }
   }

   if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
      setup->draw_region = setup->framebuffer;
      if (setup->scissor_test) {
         u_rect_possible_intersection(&setup->scissor,
                                      &setup->draw_region);
      }
   }
                                      
   setup->dirty = 0;

   assert(setup->fs.stored);
   return TRUE;
}
Example #22
0
static boolean
lp_setup_try_clear( struct lp_setup_context *setup,
                    const float *color,
                    double depth,
                    unsigned stencil,
                    unsigned flags )
{
   uint32_t zsmask = 0;
   uint32_t zsvalue = 0;
   union lp_rast_cmd_arg color_arg;
   unsigned i;

   LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);

   if (flags & PIPE_CLEAR_COLOR) {
      for (i = 0; i < 4; i++)
         color_arg.clear_color[i] = float_to_ubyte(color[i]);
   }

   if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
      unsigned zmask = (flags & PIPE_CLEAR_DEPTH) ? ~0 : 0;
      unsigned smask = (flags & PIPE_CLEAR_STENCIL) ? ~0 : 0;

      zsvalue = util_pack_z_stencil(setup->fb.zsbuf->format,
                                    depth,
                                    stencil);

      zsmask = util_pack_uint_z_stencil(setup->fb.zsbuf->format,
                                        zmask,
                                        smask);
   }

   if (setup->state == SETUP_ACTIVE) {
      struct lp_scene *scene = setup->scene;

      /* Add the clear to existing scene.  In the unusual case where
       * both color and depth-stencil are being cleared when there's
       * already been some rendering, we could discard the currently
       * binned scene and start again, but I don't see that as being
       * a common usage.
       */
      if (flags & PIPE_CLEAR_COLOR) {
         if (!lp_scene_bin_everywhere( scene, 
                                       LP_RAST_OP_CLEAR_COLOR,
                                       color_arg ))
            return FALSE;
      }

      if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
         if (!lp_scene_bin_everywhere( scene,
                                       LP_RAST_OP_CLEAR_ZSTENCIL,
                                       lp_rast_arg_clearzs(zsvalue, zsmask) ))
            return FALSE;
      }
   }
   else {
      /* Put ourselves into the 'pre-clear' state, specifically to try
       * and accumulate multiple clears to color and depth_stencil
       * buffers which the app or state-tracker might issue
       * separately.
       */
      set_scene_state( setup, SETUP_CLEARED, __FUNCTION__ );

      setup->clear.flags |= flags;

      if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
         setup->clear.zsmask |= zsmask;
         setup->clear.zsvalue =
            (setup->clear.zsvalue & ~zsmask) | (zsvalue & zsmask);
      }

      if (flags & PIPE_CLEAR_COLOR) {
         memcpy(setup->clear.color.clear_color,
                &color_arg,
                sizeof color_arg);
      }
   }
   
   return TRUE;
}
static void
write_texture_border_color(struct vc5_job *job,
                           struct vc5_cl_out **uniforms,
                           struct vc5_texture_stateobj *texstate,
                           uint32_t unit)
{
        struct pipe_sampler_state *sampler = texstate->samplers[unit];
        struct pipe_sampler_view *texture = texstate->textures[unit];
        struct vc5_resource *rsc = vc5_resource(texture->texture);
        union util_color uc;

        const struct util_format_description *tex_format_desc =
                util_format_description(texture->format);

        float border_color[4];
        for (int i = 0; i < 4; i++)
                border_color[i] = sampler->border_color.f[i];
        if (util_format_is_srgb(texture->format)) {
                for (int i = 0; i < 3; i++)
                        border_color[i] =
                                util_format_linear_to_srgb_float(border_color[i]);
        }

        /* Turn the border color into the layout of channels that it would
         * have when stored as texture contents.
         */
        float storage_color[4];
        util_format_unswizzle_4f(storage_color,
                                 border_color,
                                 tex_format_desc->swizzle);

        /* Now, pack so that when the vc5_format-sampled texture contents are
         * replaced with our border color, the vc5_get_format_swizzle()
         * swizzling will get the right channels.
         */
        if (util_format_is_depth_or_stencil(texture->format)) {
                uc.ui[0] = util_pack_z(PIPE_FORMAT_Z24X8_UNORM,
                                       sampler->border_color.f[0]) << 8;
        } else {
                switch (rsc->vc5_format) {
                default:
                case VC5_TEXTURE_TYPE_RGBA8888:
                        util_pack_color(storage_color,
                                        PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
                        break;
                case VC5_TEXTURE_TYPE_RGBA4444:
                        util_pack_color(storage_color,
                                        PIPE_FORMAT_A8B8G8R8_UNORM, &uc);
                        break;
                case VC5_TEXTURE_TYPE_RGB565:
                        util_pack_color(storage_color,
                                        PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
                        break;
                case VC5_TEXTURE_TYPE_ALPHA:
                        uc.ui[0] = float_to_ubyte(storage_color[0]) << 24;
                        break;
                case VC5_TEXTURE_TYPE_LUMALPHA:
                        uc.ui[0] = ((float_to_ubyte(storage_color[1]) << 24) |
                                    (float_to_ubyte(storage_color[0]) << 0));
                        break;
                }
        }

        cl_aligned_u32(uniforms, uc.ui[0]);
}
Example #24
0
/* Compare old and new render states and emit differences between them
 * to hardware.  Simplest implementation would be to emit the whole of
 * the "to" state.
 */
static enum pipe_error
emit_rss(struct svga_context *svga, unsigned dirty)
{
   struct svga_screen *screen = svga_screen(svga->pipe.screen);
   struct rs_queue queue;
   float point_size_min;

   queue.rs_count = 0;

   if (dirty & SVGA_NEW_BLEND) {
      const struct svga_blend_state *curr = svga->curr.blend;

      EMIT_RS( svga, curr->rt[0].writemask, COLORWRITEENABLE, fail );
      EMIT_RS( svga, curr->rt[0].blend_enable, BLENDENABLE, fail );

      if (curr->rt[0].blend_enable) {
         EMIT_RS( svga, curr->rt[0].srcblend, SRCBLEND, fail );
         EMIT_RS( svga, curr->rt[0].dstblend, DSTBLEND, fail );
         EMIT_RS( svga, curr->rt[0].blendeq, BLENDEQUATION, fail );

         EMIT_RS( svga, curr->rt[0].separate_alpha_blend_enable, 
                  SEPARATEALPHABLENDENABLE, fail );

         if (curr->rt[0].separate_alpha_blend_enable) {
            EMIT_RS( svga, curr->rt[0].srcblend_alpha, SRCBLENDALPHA, fail );
            EMIT_RS( svga, curr->rt[0].dstblend_alpha, DSTBLENDALPHA, fail );
            EMIT_RS( svga, curr->rt[0].blendeq_alpha, BLENDEQUATIONALPHA, fail );
         }
      }
   }

   if (dirty & SVGA_NEW_BLEND_COLOR) {
      uint32 color;
      uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
      uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
      uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
      uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);

      color = (a << 24) | (r << 16) | (g << 8) | b;

      EMIT_RS( svga, color, BLENDCOLOR, fail );
   }

   if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
      const struct svga_depth_stencil_state *curr = svga->curr.depth; 
      const struct svga_rasterizer_state *rast = svga->curr.rast; 

      if (!curr->stencil[0].enabled) 
      {
         /* Stencil disabled
          */
         EMIT_RS( svga, FALSE, STENCILENABLE, fail );
         EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
      }
      else if (curr->stencil[0].enabled && !curr->stencil[1].enabled)
      {
         /* Regular stencil
          */
         EMIT_RS( svga, TRUE, STENCILENABLE, fail );
         EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );

         EMIT_RS( svga, curr->stencil[0].func,  STENCILFUNC, fail );
         EMIT_RS( svga, curr->stencil[0].fail,  STENCILFAIL, fail );
         EMIT_RS( svga, curr->stencil[0].zfail, STENCILZFAIL, fail );
         EMIT_RS( svga, curr->stencil[0].pass,  STENCILPASS, fail );

         EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
         EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
      }
      else 
      {
         int cw, ccw;

         /* Hardware frontwinding is always CW, so if ours is also CW,
          * then our definition of front face agrees with hardware.
          * Otherwise need to flip.
          */
         if (rast->templ.front_ccw) {
            ccw = 0;
            cw = 1;
         }
         else {
            ccw = 1;
            cw = 0;
         }

         /* Twoside stencil
          */
         EMIT_RS( svga, TRUE, STENCILENABLE, fail );
         EMIT_RS( svga, TRUE, STENCILENABLE2SIDED, fail );

         EMIT_RS( svga, curr->stencil[cw].func,  STENCILFUNC, fail );
         EMIT_RS( svga, curr->stencil[cw].fail,  STENCILFAIL, fail );
         EMIT_RS( svga, curr->stencil[cw].zfail, STENCILZFAIL, fail );
         EMIT_RS( svga, curr->stencil[cw].pass,  STENCILPASS, fail );

         EMIT_RS( svga, curr->stencil[ccw].func,  CCWSTENCILFUNC, fail );
         EMIT_RS( svga, curr->stencil[ccw].fail,  CCWSTENCILFAIL, fail );
         EMIT_RS( svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL, fail );
         EMIT_RS( svga, curr->stencil[ccw].pass,  CCWSTENCILPASS, fail );

         EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail );
         EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail );
      }

      EMIT_RS( svga, curr->zenable, ZENABLE, fail );
      if (curr->zenable) {
         EMIT_RS( svga, curr->zfunc, ZFUNC, fail );
         EMIT_RS( svga, curr->zwriteenable, ZWRITEENABLE, fail );
      }

      EMIT_RS( svga, curr->alphatestenable, ALPHATESTENABLE, fail );
      if (curr->alphatestenable) {
         EMIT_RS( svga, curr->alphafunc, ALPHAFUNC, fail );
         EMIT_RS_FLOAT( svga, curr->alpharef, ALPHAREF, fail );
      }
   }

   if (dirty & SVGA_NEW_STENCIL_REF) {
      EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
   }

   if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
   {
      const struct svga_rasterizer_state *curr = svga->curr.rast; 
      unsigned cullmode = curr->cullmode;

      /* Shademode: still need to rearrange index list to move
       * flat-shading PV first vertex.
       */
      EMIT_RS( svga, curr->shademode, SHADEMODE, fail );

      /* Don't do culling while the software pipeline is active.  It
       * does it for us, and additionally introduces potentially
       * back-facing triangles.
       */
      if (svga->state.sw.need_pipeline)
         cullmode = SVGA3D_FACE_NONE;

      point_size_min = util_get_min_point_size(&curr->templ);

      EMIT_RS( svga, cullmode, CULLMODE, fail );
      EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
      EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
      EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
      EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
      EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
      EMIT_RS_FLOAT( svga, point_size_min, POINTSIZEMIN, fail );
      EMIT_RS_FLOAT( svga, screen->maxPointSize, POINTSIZEMAX, fail );
      EMIT_RS( svga, curr->pointsprite, POINTSPRITEENABLE, fail);
   }

   if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))
   {
      const struct svga_rasterizer_state *curr = svga->curr.rast; 
      float slope = 0.0;
      float bias  = 0.0;

      /* Need to modify depth bias according to bound depthbuffer
       * format.  Don't do hardware depthbias while the software
       * pipeline is active.
       */
      if (!svga->state.sw.need_pipeline &&
          svga->curr.framebuffer.zsbuf)
      {
         slope = curr->slopescaledepthbias;
         bias  = svga->curr.depthscale * curr->depthbias;
      }

      EMIT_RS_FLOAT( svga, slope, SLOPESCALEDEPTHBIAS, fail );
      EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail );
   }

   if (dirty & SVGA_NEW_FRAME_BUFFER) {
      /* XXX: we only look at the first color buffer's sRGB state */
      float gamma = 1.0f;
      if (svga->curr.framebuffer.cbufs[0] &&
          util_format_is_srgb(svga->curr.framebuffer.cbufs[0]->format)) {
         gamma = 2.2f;
      }
      EMIT_RS_FLOAT(svga, gamma, OUTPUTGAMMA, fail);
   }

   if (dirty & SVGA_NEW_RAST) {
      /* bitmask of the enabled clip planes */
      unsigned enabled = svga->curr.rast->templ.clip_plane_enable;
      EMIT_RS( svga, enabled, CLIPPLANEENABLE, fail );
   }

   if (queue.rs_count) {
      SVGA3dRenderState *rs;

      if (SVGA3D_BeginSetRenderState( svga->swc,
                                      &rs,
                                      queue.rs_count ) != PIPE_OK)
         goto fail;

      memcpy( rs,
              queue.rs,
              queue.rs_count * sizeof queue.rs[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.rs, 0xcd, sizeof(svga->state.hw_draw.rs));

   return PIPE_ERROR_OUT_OF_MEMORY;
}
Example #25
0
static void *
i915_create_sampler_state(struct pipe_context *pipe,
                          const struct pipe_sampler_state *sampler)
{
   struct i915_sampler_state *cso = CALLOC_STRUCT( i915_sampler_state );
   const unsigned ws = sampler->wrap_s;
   const unsigned wt = sampler->wrap_t;
   const unsigned wr = sampler->wrap_r;
   unsigned minFilt, magFilt;
   unsigned mipFilt;

   cso->templ = *sampler;

   mipFilt = translate_mip_filter(sampler->min_mip_filter);
   minFilt = translate_img_filter( sampler->min_img_filter );
   magFilt = translate_img_filter( sampler->mag_img_filter );

   if (sampler->max_anisotropy > 1)
      minFilt = magFilt = FILTER_ANISOTROPIC;

   if (sampler->max_anisotropy > 2) {
      cso->state[0] |= SS2_MAX_ANISO_4;
   }

   {
      int b = (int) (sampler->lod_bias * 16.0);
      b = CLAMP(b, -256, 255);
      cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
   }

   /* Shadow:
    */
   if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
   {
      cso->state[0] |= (SS2_SHADOW_ENABLE |
                        i915_translate_shadow_compare_func(sampler->compare_func));

      minFilt = FILTER_4X4_FLAT;
      magFilt = FILTER_4X4_FLAT;
   }

   cso->state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
                     (mipFilt << SS2_MIP_FILTER_SHIFT) |
                     (magFilt << SS2_MAG_FILTER_SHIFT));

   cso->state[1] |=
      ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
       (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
       (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));

   if (sampler->normalized_coords)
      cso->state[1] |= SS3_NORMALIZED_COORDS;

   {
      int minlod = (int) (16.0 * sampler->min_lod);
      int maxlod = (int) (16.0 * sampler->max_lod);
      minlod = CLAMP(minlod, 0, 16 * 11);
      maxlod = CLAMP(maxlod, 0, 16 * 11);

      if (minlod > maxlod)
	 maxlod = minlod;

      cso->minlod = minlod;
      cso->maxlod = maxlod;
   }

   {
      ubyte r = float_to_ubyte(sampler->border_color.f[0]);
      ubyte g = float_to_ubyte(sampler->border_color.f[1]);
      ubyte b = float_to_ubyte(sampler->border_color.f[2]);
      ubyte a = float_to_ubyte(sampler->border_color.f[3]);
      cso->state[2] = I915PACKCOLOR8888(r, g, b, a);
   }
   return cso;
}
Example #26
0
static void *
i915_create_depth_stencil_state(struct pipe_context *pipe,
				const struct pipe_depth_stencil_alpha_state *depth_stencil)
{
   struct i915_depth_stencil_state *cso = CALLOC_STRUCT( i915_depth_stencil_state );

   {
      int testmask = depth_stencil->stencil[0].valuemask & 0xff;
      int writemask = depth_stencil->stencil[0].writemask & 0xff;

      cso->stencil_modes4 |= (_3DSTATE_MODES_4_CMD |
                              ENABLE_STENCIL_TEST_MASK |
                              STENCIL_TEST_MASK(testmask) |
                              ENABLE_STENCIL_WRITE_MASK |
                              STENCIL_WRITE_MASK(writemask));
   }

   if (depth_stencil->stencil[0].enabled) {
      int test = i915_translate_compare_func(depth_stencil->stencil[0].func);
      int fop  = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op);
      int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op);
      int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op);

      cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE |
                            S5_STENCIL_WRITE_ENABLE |
                            (test << S5_STENCIL_TEST_FUNC_SHIFT) |
                            (fop  << S5_STENCIL_FAIL_SHIFT) |
                            (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
                            (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT));
   }

   if (depth_stencil->stencil[1].enabled) {
      int test  = i915_translate_compare_func(depth_stencil->stencil[1].func);
      int fop   = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op);
      int dfop  = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op);
      int dpop  = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op);
      int tmask = depth_stencil->stencil[1].valuemask & 0xff;
      int wmask = depth_stencil->stencil[1].writemask & 0xff;

      cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
                     BFO_ENABLE_STENCIL_FUNCS |
                     BFO_ENABLE_STENCIL_TWO_SIDE |
                     BFO_ENABLE_STENCIL_REF |
                     BFO_STENCIL_TWO_SIDE |
                     (test << BFO_STENCIL_TEST_SHIFT) |
                     (fop  << BFO_STENCIL_FAIL_SHIFT) |
                     (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
                     (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));

      cso->bfo[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS |
                     BFM_ENABLE_STENCIL_TEST_MASK |
                     BFM_ENABLE_STENCIL_WRITE_MASK |
                     (tmask << BFM_STENCIL_TEST_MASK_SHIFT) |
                     (wmask << BFM_STENCIL_WRITE_MASK_SHIFT));
   }
   else {
      /* This actually disables two-side stencil: The bit set is a
       * modify-enable bit to indicate we are changing the two-side
       * setting.  Then there is a symbolic zero to show that we are
       * setting the flag to zero/off.
       */
      cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
                     BFO_ENABLE_STENCIL_TWO_SIDE |
                     0);
      cso->bfo[1] = 0;
   }

   if (depth_stencil->depth.enabled) {
      int func = i915_translate_compare_func(depth_stencil->depth.func);

      cso->depth_LIS6 |= (S6_DEPTH_TEST_ENABLE |
                          (func << S6_DEPTH_TEST_FUNC_SHIFT));

      if (depth_stencil->depth.writemask)
	 cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE;
   }

   if (depth_stencil->alpha.enabled) {
      int test = i915_translate_compare_func(depth_stencil->alpha.func);
      ubyte refByte = float_to_ubyte(depth_stencil->alpha.ref_value);

      cso->depth_LIS6 |= (S6_ALPHA_TEST_ENABLE |
			  (test << S6_ALPHA_TEST_FUNC_SHIFT) |
			  (((unsigned) refByte) << S6_ALPHA_REF_SHIFT));
   }

   return cso;
}
Example #27
0
static void *
nv30_zsa_state_create(struct pipe_context *pipe,
                      const struct pipe_depth_stencil_alpha_state *cso)
{
   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
   struct nv30_zsa_stateobj *so;

   so = CALLOC_STRUCT(nv30_zsa_stateobj);
   if (!so)
      return NULL;
   so->pipe = *cso;

   SB_MTHD30(so, DEPTH_FUNC, 3);
   SB_DATA  (so, nvgl_comparison_op(cso->depth.func));
   SB_DATA  (so, cso->depth.writemask);
   SB_DATA  (so, cso->depth.enabled);

   if (eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS) {
      SB_MTHD35(so, DEPTH_BOUNDS_TEST_ENABLE, 3);
      SB_DATA  (so, cso->depth.bounds_test);
      SB_DATA  (so, fui(cso->depth.bounds_min));
      SB_DATA  (so, fui(cso->depth.bounds_max));
   }

   if (cso->stencil[0].enabled) {
      SB_MTHD30(so, STENCIL_ENABLE(0), 3);
      SB_DATA  (so, 1);
      SB_DATA  (so, cso->stencil[0].writemask);
      SB_DATA  (so, nvgl_comparison_op(cso->stencil[0].func));
      SB_MTHD30(so, STENCIL_FUNC_MASK(0), 4);
      SB_DATA  (so, cso->stencil[0].valuemask);
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
   } else {
      SB_MTHD30(so, STENCIL_ENABLE(0), 2);
      SB_DATA  (so, 0);
      SB_DATA  (so, 0x000000ff);
   }

   if (cso->stencil[1].enabled) {
      SB_MTHD30(so, STENCIL_ENABLE(1), 3);
      SB_DATA  (so, 1);
      SB_DATA  (so, cso->stencil[1].writemask);
      SB_DATA  (so, nvgl_comparison_op(cso->stencil[1].func));
      SB_MTHD30(so, STENCIL_FUNC_MASK(1), 4);
      SB_DATA  (so, cso->stencil[1].valuemask);
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
   } else {
      SB_MTHD30(so, STENCIL_ENABLE(1), 1);
      SB_DATA  (so, 0);
   }

   SB_MTHD30(so, ALPHA_FUNC_ENABLE, 3);
   SB_DATA  (so, cso->alpha.enabled ? 1 : 0);
   SB_DATA  (so, nvgl_comparison_op(cso->alpha.func));
   SB_DATA  (so, float_to_ubyte(cso->alpha.ref_value));

   return so;
}
Example #28
0
static void *
nv40_sampler_state_create(struct pipe_context *pipe,
			  const struct pipe_sampler_state *cso)
{
	struct nv40_sampler_state *ps;
	uint32_t filter = 0;

	ps = MALLOC(sizeof(struct nv40_sampler_state));

	ps->fmt = 0;
	if (!cso->normalized_coords)
		ps->fmt |= NV40TCL_TEX_FORMAT_RECT;

	ps->wrap = ((wrap_mode(cso->wrap_s) << NV40TCL_TEX_WRAP_S_SHIFT) |
		    (wrap_mode(cso->wrap_t) << NV40TCL_TEX_WRAP_T_SHIFT) |
		    (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT));

	ps->en = 0;
	if (cso->max_anisotropy >= 2.0) {
		/* no idea, binary driver sets it, works without it.. meh.. */
		ps->wrap |= (1 << 5);

		if (cso->max_anisotropy >= 16.0) {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
		} else
		if (cso->max_anisotropy >= 12.0) {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
		} else
		if (cso->max_anisotropy >= 10.0) {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
		} else
		if (cso->max_anisotropy >= 8.0) {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
		} else
		if (cso->max_anisotropy >= 6.0) {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
		} else
		if (cso->max_anisotropy >= 4.0) {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
		} else {
			ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
		}
	}

	switch (cso->mag_img_filter) {
	case PIPE_TEX_FILTER_LINEAR:
		filter |= NV40TCL_TEX_FILTER_MAG_LINEAR;
		break;
	case PIPE_TEX_FILTER_NEAREST:
	default:
		filter |= NV40TCL_TEX_FILTER_MAG_NEAREST;
		break;
	}

	switch (cso->min_img_filter) {
	case PIPE_TEX_FILTER_LINEAR:
		switch (cso->min_mip_filter) {
		case PIPE_TEX_MIPFILTER_NEAREST:
			filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST;
			break;
		case PIPE_TEX_MIPFILTER_LINEAR:
			filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR;
			break;
		case PIPE_TEX_MIPFILTER_NONE:
		default:
			filter |= NV40TCL_TEX_FILTER_MIN_LINEAR;
			break;
		}
		break;
	case PIPE_TEX_FILTER_NEAREST:
	default:
		switch (cso->min_mip_filter) {
		case PIPE_TEX_MIPFILTER_NEAREST:
			filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST;
		break;
		case PIPE_TEX_MIPFILTER_LINEAR:
			filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR;
			break;
		case PIPE_TEX_MIPFILTER_NONE:
		default:
			filter |= NV40TCL_TEX_FILTER_MIN_NEAREST;
			break;
		}
		break;
	}

	ps->filt = filter;

	{
		float limit;

		limit = CLAMP(cso->lod_bias, -16.0, 15.0);
		ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;

		limit = CLAMP(cso->max_lod, 0.0, 15.0);
		ps->en |= (int)(limit * 256.0) << 7;

		limit = CLAMP(cso->min_lod, 0.0, 15.0);
		ps->en |= (int)(limit * 256.0) << 19;
	}


	if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
		switch (cso->compare_func) {
		case PIPE_FUNC_NEVER:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NEVER;
			break;
		case PIPE_FUNC_GREATER:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GREATER;
			break;
		case PIPE_FUNC_EQUAL:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_EQUAL;
			break;
		case PIPE_FUNC_GEQUAL:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GEQUAL;
			break;
		case PIPE_FUNC_LESS:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LESS;
			break;
		case PIPE_FUNC_NOTEQUAL:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NOTEQUAL;
			break;
		case PIPE_FUNC_LEQUAL:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LEQUAL;
			break;
		case PIPE_FUNC_ALWAYS:
			ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_ALWAYS;
			break;
		default:
			break;
		}
	}

	ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
		    (float_to_ubyte(cso->border_color[0]) << 16) |
		    (float_to_ubyte(cso->border_color[1]) <<  8) |
		    (float_to_ubyte(cso->border_color[2]) <<  0));

	return (void *)ps;
}
Example #29
0
static void
logicop_quad(struct quad_stage *qs, 
             float (*quadColor)[4],
             float (*dest)[4])
{
   struct softpipe_context *softpipe = qs->softpipe;
   ubyte src[4][4], dst[4][4], res[4][4];
   uint *src4 = (uint *) src;
   uint *dst4 = (uint *) dst;
   uint *res4 = (uint *) res;
   uint j;


   /* convert to ubyte */
   for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
      dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
      dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
      dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
      dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */

      src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
      src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
      src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
      src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
   }

   switch (softpipe->blend->logicop_func) {
   case PIPE_LOGICOP_CLEAR:
      for (j = 0; j < 4; j++)
         res4[j] = 0;
      break;
   case PIPE_LOGICOP_NOR:
      for (j = 0; j < 4; j++)
         res4[j] = ~(src4[j] | dst4[j]);
      break;
   case PIPE_LOGICOP_AND_INVERTED:
      for (j = 0; j < 4; j++)
         res4[j] = ~src4[j] & dst4[j];
      break;
   case PIPE_LOGICOP_COPY_INVERTED:
      for (j = 0; j < 4; j++)
         res4[j] = ~src4[j];
      break;
   case PIPE_LOGICOP_AND_REVERSE:
      for (j = 0; j < 4; j++)
         res4[j] = src4[j] & ~dst4[j];
      break;
   case PIPE_LOGICOP_INVERT:
      for (j = 0; j < 4; j++)
         res4[j] = ~dst4[j];
      break;
   case PIPE_LOGICOP_XOR:
      for (j = 0; j < 4; j++)
         res4[j] = dst4[j] ^ src4[j];
      break;
   case PIPE_LOGICOP_NAND:
      for (j = 0; j < 4; j++)
         res4[j] = ~(src4[j] & dst4[j]);
      break;
   case PIPE_LOGICOP_AND:
      for (j = 0; j < 4; j++)
         res4[j] = src4[j] & dst4[j];
      break;
   case PIPE_LOGICOP_EQUIV:
      for (j = 0; j < 4; j++)
         res4[j] = ~(src4[j] ^ dst4[j]);
      break;
   case PIPE_LOGICOP_NOOP:
      for (j = 0; j < 4; j++)
         res4[j] = dst4[j];
      break;
   case PIPE_LOGICOP_OR_INVERTED:
      for (j = 0; j < 4; j++)
         res4[j] = ~src4[j] | dst4[j];
      break;
   case PIPE_LOGICOP_COPY:
      for (j = 0; j < 4; j++)
         res4[j] = src4[j];
      break;
   case PIPE_LOGICOP_OR_REVERSE:
      for (j = 0; j < 4; j++)
         res4[j] = src4[j] | ~dst4[j];
      break;
   case PIPE_LOGICOP_OR:
      for (j = 0; j < 4; j++)
         res4[j] = src4[j] | dst4[j];
      break;
   case PIPE_LOGICOP_SET:
      for (j = 0; j < 4; j++)
         res4[j] = ~0;
      break;
   default:
      assert(0);
   }

   for (j = 0; j < 4; j++) {
      quadColor[j][0] = ubyte_to_float(res[j][0]);
      quadColor[j][1] = ubyte_to_float(res[j][1]);
      quadColor[j][2] = ubyte_to_float(res[j][2]);
      quadColor[j][3] = ubyte_to_float(res[j][3]);
   }
}
Example #30
0
bool radv_format_pack_clear_color(VkFormat format,
				  uint32_t clear_vals[2],
				  VkClearColorValue *value)
{
	uint8_t r = 0, g = 0, b = 0, a = 0;
	const struct vk_format_description *desc = vk_format_description(format);

	if (vk_format_get_component_bits(format, VK_FORMAT_COLORSPACE_RGB, 0) <= 8) {
		if (desc->colorspace == VK_FORMAT_COLORSPACE_RGB) {
			r = float_to_ubyte(value->float32[0]);
			g = float_to_ubyte(value->float32[1]);
			b = float_to_ubyte(value->float32[2]);
			a = float_to_ubyte(value->float32[3]);
		} else if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
			r = util_format_linear_float_to_srgb_8unorm(value->float32[0]);
			g = util_format_linear_float_to_srgb_8unorm(value->float32[1]);
			b = util_format_linear_float_to_srgb_8unorm(value->float32[2]);
			a = float_to_ubyte(value->float32[3]);
		}
	}
	switch (format) {
	case VK_FORMAT_R8_UNORM:
	case VK_FORMAT_R8_SRGB:
		clear_vals[0] = r;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R8G8_UNORM:
	case VK_FORMAT_R8G8_SRGB:
		clear_vals[0] = r | g << 8;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R8G8B8A8_SRGB:
	case VK_FORMAT_R8G8B8A8_UNORM:
		clear_vals[0] = r | g << 8 | b << 16 | a << 24;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_B8G8R8A8_SRGB:
	case VK_FORMAT_B8G8R8A8_UNORM:
		clear_vals[0] = b | g << 8 | r << 16 | a << 24;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
		clear_vals[0] = r | g << 8 | b << 16 | a << 24;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R8_UINT:
		clear_vals[0] = value->uint32[0] & 0xff;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16_UINT:
		clear_vals[0] = value->uint32[0] & 0xffff;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R8G8_UINT:
		clear_vals[0] = value->uint32[0] & 0xff;
		clear_vals[0] |= (value->uint32[1] & 0xff) << 8;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R8G8B8A8_UINT:
		clear_vals[0] = value->uint32[0] & 0xff;
		clear_vals[0] |= (value->uint32[1] & 0xff) << 8;
		clear_vals[0] |= (value->uint32[2] & 0xff) << 16;
		clear_vals[0] |= (value->uint32[3] & 0xff) << 24;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_A8B8G8R8_UINT_PACK32:
		clear_vals[0] = value->uint32[0] & 0xff;
		clear_vals[0] |= (value->uint32[1] & 0xff) << 8;
		clear_vals[0] |= (value->uint32[2] & 0xff) << 16;
		clear_vals[0] |= (value->uint32[3] & 0xff) << 24;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16G16_UINT:
		clear_vals[0] = value->uint32[0] & 0xffff;
		clear_vals[0] |= (value->uint32[1] & 0xffff) << 16;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16G16B16A16_UINT:
		clear_vals[0] = value->uint32[0] & 0xffff;
		clear_vals[0] |= (value->uint32[1] & 0xffff) << 16;
		clear_vals[1] = value->uint32[2] & 0xffff;
		clear_vals[1] |= (value->uint32[3] & 0xffff) << 16;
		break;
	case VK_FORMAT_R32_UINT:
		clear_vals[0] = value->uint32[0];
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R32G32_UINT:
		clear_vals[0] = value->uint32[0];
		clear_vals[1] = value->uint32[1];
		break;
	case VK_FORMAT_R32_SINT:
		clear_vals[0] = value->int32[0];
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16_SFLOAT:
		clear_vals[0] = util_float_to_half(value->float32[0]);
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16G16_SFLOAT:
		clear_vals[0] = util_float_to_half(value->float32[0]);
		clear_vals[0] |= (uint32_t)util_float_to_half(value->float32[1]) << 16;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16G16B16A16_SFLOAT:
		clear_vals[0] = util_float_to_half(value->float32[0]);
		clear_vals[0] |= (uint32_t)util_float_to_half(value->float32[1]) << 16;
		clear_vals[1] = util_float_to_half(value->float32[2]);
		clear_vals[1] |= (uint32_t)util_float_to_half(value->float32[3]) << 16;
		break;
	case VK_FORMAT_R16_UNORM:
		clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0xffff)) & 0xffff;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16G16_UNORM:
		clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0xffff)) & 0xffff;
		clear_vals[0] |= ((uint16_t)util_iround(CLAMP(value->float32[1], 0.0f, 1.0f) * 0xffff)) << 16;
		clear_vals[1] = 0;
		break;
	case VK_FORMAT_R16G16B16A16_UNORM:
		clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0xffff)) & 0xffff;
		clear_vals[0] |= ((uint16_t)util_iround(CLAMP(value->float32[1], 0.0f, 1.0f) * 0xffff)) << 16;
		clear_vals[1] = ((uint16_t)util_iround(CLAMP(value->float32[2], 0.0f, 1.0f) * 0xffff)) & 0xffff;
		clear_vals[1] |= ((uint16_t)util_iround(CLAMP(value->float32[3], 0.0f, 1.0f) * 0xffff)) << 16;
		break;
	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
		/* TODO */
		return false;
	case VK_FORMAT_R32G32_SFLOAT:
		clear_vals[0] = fui(value->float32[0]);
		clear_vals[1] = fui(value->float32[1]);
		break;
	case VK_FORMAT_R32_SFLOAT:
		clear_vals[1] = 0;
		clear_vals[0] = fui(value->float32[0]);
		break;
	default:
		fprintf(stderr, "failed to fast clear %d\n", format);
		return false;
	}
	return true;
}