Ejemplo n.º 1
0
void
nv30_sampler_view_init(struct pipe_context *pipe,
			  struct nvfx_sampler_view *sv)
{
	struct pipe_resource* pt = sv->base.texture;
	struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
	unsigned txf;
	unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.u.tex.first_level;

	assert(tf->fmt[0] >= 0);

	txf = sv->u.init_fmt;
	txf |= (level != sv->base.u.tex.last_level ? NV30_3D_TEX_FORMAT_MIPMAP : 0);
	txf |= util_logbase2(u_minify(pt->width0, level)) << NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT;
	txf |= util_logbase2(u_minify(pt->height0, level)) << NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT;
	txf |= util_logbase2(u_minify(pt->depth0, level)) << NV30_3D_TEX_FORMAT_BASE_SIZE_W__SHIFT;
	txf |=  0x10000;

	sv->u.nv30.fmt[0] = tf->fmt[0] | txf;
	sv->u.nv30.fmt[1] = tf->fmt[1] | txf;
	sv->u.nv30.fmt[2] = tf->fmt[2] | txf;
	sv->u.nv30.fmt[3] = tf->fmt[3] | txf;

	sv->swizzle  |= (nvfx_subresource_pitch(pt, 0) << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT);

	if(pt->height0 <= 1 || util_format_is_compressed(sv->base.format))
		sv->u.nv30.rect = -1;
	else
		sv->u.nv30.rect = !!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR);

	sv->lod_offset = sv->base.u.tex.first_level - level;
	sv->max_lod_limit = sv->base.u.tex.last_level - level;
}
Ejemplo n.º 2
0
static void amdgpu_buffer_set_metadata(struct pb_buffer *_buf,
                                       struct radeon_bo_metadata *md)
{
   struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
   struct amdgpu_bo_metadata metadata = {0};
   uint32_t tiling_flags = 0;

   if (md->macrotile == RADEON_LAYOUT_TILED)
      tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 4); /* 2D_TILED_THIN1 */
   else if (md->microtile == RADEON_LAYOUT_TILED)
      tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 2); /* 1D_TILED_THIN1 */
   else
      tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); /* LINEAR_ALIGNED */

   tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, md->pipe_config);
   tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, util_logbase2(md->bankw));
   tiling_flags |= AMDGPU_TILING_SET(BANK_HEIGHT, util_logbase2(md->bankh));
   if (md->tile_split)
      tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, eg_tile_split_rev(md->tile_split));
   tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, util_logbase2(md->mtilea));
   tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, util_logbase2(md->num_banks)-1);

   if (md->scanout)
      tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 0); /* DISPLAY_MICRO_TILING */
   else
      tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 1); /* THIN_MICRO_TILING */

   metadata.tiling_info = tiling_flags;
   metadata.size_metadata = md->size_metadata;
   memcpy(metadata.umd_metadata, md->metadata, sizeof(md->metadata));

   amdgpu_bo_set_metadata(bo->bo, &metadata);
}
Ejemplo n.º 3
0
/* Returns the number of pixels that the texture should be aligned to
 * in the given dimension. */
unsigned r300_get_pixel_alignment(enum pipe_format format,
                                  unsigned num_samples,
                                  enum radeon_bo_layout microtile,
                                  enum radeon_bo_layout macrotile,
                                  enum r300_dim dim, boolean is_rs690)
{
    static const unsigned table[2][5][3][2] =
    {
        {
    /* Macro: linear    linear    linear
       Micro: linear    tiled  square-tiled */
            {{ 32, 1}, { 8,  4}, { 0,  0}}, /*   8 bits per pixel */
            {{ 16, 1}, { 8,  2}, { 4,  4}}, /*  16 bits per pixel */
            {{  8, 1}, { 4,  2}, { 0,  0}}, /*  32 bits per pixel */
            {{  4, 1}, { 2,  2}, { 0,  0}}, /*  64 bits per pixel */
            {{  2, 1}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
        },
        {
    /* Macro: tiled     tiled     tiled
       Micro: linear    tiled  square-tiled */
            {{256, 8}, {64, 32}, { 0,  0}}, /*   8 bits per pixel */
            {{128, 8}, {64, 16}, {32, 32}}, /*  16 bits per pixel */
            {{ 64, 8}, {32, 16}, { 0,  0}}, /*  32 bits per pixel */
            {{ 32, 8}, {16, 16}, { 0,  0}}, /*  64 bits per pixel */
            {{ 16, 8}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
        }
    };

    static const unsigned aa_block[2] = {4, 8};
    unsigned tile = 0;
    unsigned pixsize = util_format_get_blocksize(format);

    assert(macrotile <= RADEON_LAYOUT_TILED);
    assert(microtile <= RADEON_LAYOUT_SQUARETILED);
    assert(pixsize <= 16);
    assert(dim <= DIM_HEIGHT);

    if (num_samples > 1) {
        /* Multisampled textures have their own alignment scheme. */
        if (pixsize == 4)
            tile = aa_block[dim];
        /* XXX FP16 AA. */
    } else {
        /* Standard alignment. */
        tile = table[macrotile][util_logbase2(pixsize)][microtile][dim];
        if (macrotile == 0 && is_rs690 && dim == DIM_WIDTH) {
            int align;
            int h_tile;
            h_tile = table[macrotile][util_logbase2(pixsize)][microtile][DIM_HEIGHT];
            align = 64 / (pixsize * h_tile);
            if (tile < align)
                tile = align;
        }
    }

    assert(tile);
    return tile;
}
Ejemplo n.º 4
0
static void
nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
                         const union pipe_color_union *color,
                         unsigned x, unsigned y, unsigned w, unsigned h)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_surface *sf = nv30_surface(ps);
   struct nv30_miptree *mt = nv30_miptree(ps->texture);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nouveau_pushbuf_refn refn;
   uint32_t rt_format;

   rt_format = nv30_format(pipe->screen, ps->format)->hw;
   if (util_format_get_blocksize(ps->format) == 4)
      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
   else
      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;

   if (nv30_miptree(ps->texture)->swizzled) {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      rt_format |= util_logbase2(sf->width) << 16;
      rt_format |= util_logbase2(sf->height) << 24;
   } else {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
   }

   refn.bo = mt->base.bo;
   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
   if (nouveau_pushbuf_space(push, 16, 1, 0) ||
       nouveau_pushbuf_refn (push, &refn, 1))
      return;

   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
   PUSH_DATA (push, sf->width << 16);
   PUSH_DATA (push, sf->height << 16);
   PUSH_DATA (push, rt_format);
   BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);
   if (eng3d->oclass < NV40_3D_CLASS)
      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
   else
      PUSH_DATA (push, sf->pitch);
   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (w << 16) | x);
   PUSH_DATA (push, (h << 16) | y);

   BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);
   PUSH_DATA (push, pack_rgba(ps->format, color->f));
   PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |
                    NV30_3D_CLEAR_BUFFERS_COLOR_G |
                    NV30_3D_CLEAR_BUFFERS_COLOR_B |
                    NV30_3D_CLEAR_BUFFERS_COLOR_A);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
Ejemplo n.º 5
0
void cayman_emit_msaa_config(struct radeon_winsys_cs *cs, int nr_samples,
			     int ps_iter_samples, int overrast_samples)
{
	int setup_samples = nr_samples > 1 ? nr_samples :
			    overrast_samples > 1 ? overrast_samples : 0;

	if (setup_samples > 1) {
		/* indexed by log2(nr_samples) */
		unsigned max_dist[] = {
			0,
			eg_max_dist_2x,
			eg_max_dist_4x,
			cm_max_dist_8x,
			cm_max_dist_16x
		};
		unsigned log_samples = util_logbase2(setup_samples);
		unsigned log_ps_iter_samples =
			util_logbase2(util_next_power_of_two(ps_iter_samples));

		radeon_set_context_reg_seq(cs, CM_R_028BDC_PA_SC_LINE_CNTL, 2);
		radeon_emit(cs, S_028BDC_LAST_PIXEL(1) |
			    S_028BDC_EXPAND_LINE_WIDTH(1)); /* CM_R_028BDC_PA_SC_LINE_CNTL */
		radeon_emit(cs, S_028BE0_MSAA_NUM_SAMPLES(log_samples) |
			    S_028BE0_MAX_SAMPLE_DIST(max_dist[log_samples]) |
			    S_028BE0_MSAA_EXPOSED_SAMPLES(log_samples)); /* CM_R_028BE0_PA_SC_AA_CONFIG */

		if (nr_samples > 1) {
			radeon_set_context_reg(cs, CM_R_028804_DB_EQAA,
					       S_028804_MAX_ANCHOR_SAMPLES(log_samples) |
					       S_028804_PS_ITER_SAMPLES(log_ps_iter_samples) |
					       S_028804_MASK_EXPORT_NUM_SAMPLES(log_samples) |
					       S_028804_ALPHA_TO_MASK_NUM_SAMPLES(log_samples) |
					       S_028804_HIGH_QUALITY_INTERSECTIONS(1) |
					       S_028804_STATIC_ANCHOR_ASSOCIATIONS(1));
			radeon_set_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1,
					     EG_S_028A4C_PS_ITER_SAMPLE(ps_iter_samples > 1));
		} else if (overrast_samples > 1) {
			radeon_set_context_reg(cs, CM_R_028804_DB_EQAA,
					       S_028804_HIGH_QUALITY_INTERSECTIONS(1) |
					       S_028804_STATIC_ANCHOR_ASSOCIATIONS(1) |
					       S_028804_OVERRASTERIZATION_AMOUNT(log_samples));
			radeon_set_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, 0);
		}
	} else {
		radeon_set_context_reg_seq(cs, CM_R_028BDC_PA_SC_LINE_CNTL, 2);
		radeon_emit(cs, S_028BDC_LAST_PIXEL(1)); /* CM_R_028BDC_PA_SC_LINE_CNTL */
		radeon_emit(cs, 0); /* CM_R_028BE0_PA_SC_AA_CONFIG */

		radeon_set_context_reg(cs, CM_R_028804_DB_EQAA,
				       S_028804_HIGH_QUALITY_INTERSECTIONS(1) |
				       S_028804_STATIC_ANCHOR_ASSOCIATIONS(1));
		radeon_set_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, 0);
	}
}
Ejemplo n.º 6
0
int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space)
{
   struct nouveau_pushbuf *push = screen->base.pushbuf;
   int ret;
   uint64_t tls_size;

   if (tls_space < screen->cur_tls_space)
      return 0;
   if (tls_space > screen->max_tls_space) {
      /* fixable by limiting number of warps (LOCAL_WARPS_LOG_ALLOC /
       * LOCAL_WARPS_NO_CLAMP) */
      NOUVEAU_ERR("Unsupported number of temporaries (%u > %u). Fixable if someone cares.\n",
            (unsigned)(tls_space / ONE_TEMP_SIZE),
            (unsigned)(screen->max_tls_space / ONE_TEMP_SIZE));
      return -ENOMEM;
   }

   nouveau_bo_ref(NULL, &screen->tls_bo);
   ret = nv50_tls_alloc(screen, tls_space, &tls_size);
   if (ret)
      return ret;

   BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->tls_bo->offset);
   PUSH_DATA (push, screen->tls_bo->offset);
   PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8));

   return 1;
}
Ejemplo n.º 7
0
void
ImmediateValue::applyLog2()
{
   switch (reg.type) {
   case TYPE_S8:
   case TYPE_S16:
   case TYPE_S32:
      assert(!this->isNegative());
      // fall through
   case TYPE_U8:
   case TYPE_U16:
   case TYPE_U32:
      reg.data.u32 = util_logbase2(reg.data.u32);
      break;
   case TYPE_F32:
      reg.data.f32 = log2f(reg.data.f32);
      break;
   case TYPE_F64:
      reg.data.f64 = log2(reg.data.f64);
      break;
   default:
      assert(0);
      break;
   }
}
Ejemplo n.º 8
0
static void amdgpu_bo_set_tiling(struct pb_buffer *_buf,
                                 struct radeon_winsys_cs *rcs,
                                 enum radeon_bo_layout microtiled,
                                 enum radeon_bo_layout macrotiled,
                                 unsigned pipe_config,
                                 unsigned bankw, unsigned bankh,
                                 unsigned tile_split,
                                 unsigned stencil_tile_split,
                                 unsigned mtilea, unsigned num_banks,
                                 uint32_t pitch,
                                 bool scanout)
{
   struct amdgpu_winsys_bo *bo = get_amdgpu_winsys_bo(_buf);
   struct amdgpu_bo_metadata metadata = {0};
   uint32_t tiling_flags = 0;

   if (macrotiled == RADEON_LAYOUT_TILED)
      tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 4); /* 2D_TILED_THIN1 */
   else if (microtiled == RADEON_LAYOUT_TILED)
      tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 2); /* 1D_TILED_THIN1 */
   else
      tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); /* LINEAR_ALIGNED */

   tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, pipe_config);
   tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, util_logbase2(bankw));
   tiling_flags |= AMDGPU_TILING_SET(BANK_HEIGHT, util_logbase2(bankh));
   if (tile_split)
      tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, eg_tile_split_rev(tile_split));
   tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, util_logbase2(mtilea));
   tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, util_logbase2(num_banks)-1);

   if (scanout)
      tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 0); /* DISPLAY_MICRO_TILING */
   else
      tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 1); /* THIN_MICRO_TILING */

   metadata.tiling_info = tiling_flags;

   amdgpu_bo_set_metadata(bo->bo, &metadata);
}
Ejemplo n.º 9
0
/**
 * Called prior to emitting the TGSI code for each Mesa instruction.
 * Allocate additional space for instructions if needed.
 * Update the insn[] array so the next Mesa instruction points to
 * the next TGSI instruction.
 */
static void set_insn_start( struct st_translate *t,
                            unsigned start )
{
   if (t->insn_count + 1 >= t->insn_size) {
      t->insn_size = 1 << (util_logbase2(t->insn_size) + 1);
      t->insn = realloc(t->insn, t->insn_size * sizeof t->insn[0]);
      if (t->insn == NULL) {
         t->error = TRUE;
         return;
      }
   }

   t->insn[t->insn_count++] = start;
}
Ejemplo n.º 10
0
void r300_texture_setup_format_state(struct r300_screen *screen,
                                     struct r300_texture_desc *desc,
                                     unsigned level,
                                     struct r300_texture_format_state *out)
{
    struct pipe_resource *pt = &desc->b.b;
    boolean is_r500 = screen->caps.is_r500;

    /* Mask out all the fields we change. */
    out->format0 = 0;
    out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
    out->format2 &= R500_TXFORMAT_MSB;
    out->tile_config = 0;

    /* Set sampler state. */
    out->format0 = R300_TX_WIDTH((u_minify(pt->width0, level) - 1) & 0x7ff) |
                   R300_TX_HEIGHT((u_minify(pt->height0, level) - 1) & 0x7ff);

    if (desc->uses_stride_addressing) {
        /* rectangles love this */
        out->format0 |= R300_TX_PITCH_EN;
        out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff;
    } else {
        /* Power of two textures (3D, mipmaps, and no pitch),
         * also NPOT textures with a width being POT. */
        out->format0 |=
            R300_TX_DEPTH(util_logbase2(u_minify(pt->depth0, level)) & 0xf);
    }

    if (pt->target == PIPE_TEXTURE_CUBE) {
        out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
    }
    if (pt->target == PIPE_TEXTURE_3D) {
        out->format1 |= R300_TX_FORMAT_3D;
    }

    /* large textures on r500 */
    if (is_r500)
    {
        if (pt->width0 > 2048) {
            out->format2 |= R500_TXWIDTH_BIT11;
        }
        if (pt->height0 > 2048) {
            out->format2 |= R500_TXHEIGHT_BIT11;
        }
    }

    out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
                       R300_TXO_MICRO_TILE(desc->microtile);
}
/* Returns the number of pixels that the texture should be aligned to
 * in the given dimension. */
unsigned r300_get_pixel_alignment(enum pipe_format format,
                                  unsigned num_samples,
                                  enum r300_buffer_tiling microtile,
                                  enum r300_buffer_tiling macrotile,
                                  enum r300_dim dim)
{
    static const unsigned table[2][5][3][2] =
    {
        {
    /* Macro: linear    linear    linear
       Micro: linear    tiled  square-tiled */
            {{ 32, 1}, { 8,  4}, { 0,  0}}, /*   8 bits per pixel */
            {{ 16, 1}, { 8,  2}, { 4,  4}}, /*  16 bits per pixel */
            {{  8, 1}, { 4,  2}, { 0,  0}}, /*  32 bits per pixel */
            {{  4, 1}, { 0,  0}, { 2,  2}}, /*  64 bits per pixel */
            {{  2, 1}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
        },
        {
    /* Macro: tiled     tiled     tiled
       Micro: linear    tiled  square-tiled */
            {{256, 8}, {64, 32}, { 0,  0}}, /*   8 bits per pixel */
            {{128, 8}, {64, 16}, {32, 32}}, /*  16 bits per pixel */
            {{ 64, 8}, {32, 16}, { 0,  0}}, /*  32 bits per pixel */
            {{ 32, 8}, { 0,  0}, {16, 16}}, /*  64 bits per pixel */
            {{ 16, 8}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
        }
    };
    static const unsigned aa_block[2] = {4, 8};
    unsigned tile = 0;
    unsigned pixsize = util_format_get_blocksize(format);

    assert(macrotile <= R300_BUFFER_TILED);
    assert(microtile <= R300_BUFFER_SQUARETILED);
    assert(pixsize <= 16);
    assert(dim <= DIM_HEIGHT);

    if (num_samples > 1) {
        /* Multisampled textures have their own alignment scheme. */
        if (pixsize == 4)
            tile = aa_block[dim];
        /* XXX FP16 AA. */
    } else {
        /* Standard alignment. */
        tile = table[macrotile][util_logbase2(pixsize)][microtile][dim];
    }

    assert(tile);
    return tile;
}
Ejemplo n.º 12
0
/**
 * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
 * of the given texture.
 */
static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
        int dim, boolean macrotile)
{
    unsigned pixsize, tile_size;

    pixsize = util_format_get_blocksize(tex->tex.format);
    tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];

    if (macrotile) {
        tile_size *= 8;
    }

    assert(tile_size);
    return tile_size;
}
Ejemplo n.º 13
0
void
lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene )
{
   unsigned x, y;

   for (y = 0; y < scene->tiles_y; y++) {
      for (x = 0; x < scene->tiles_x; x++) {
         const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW";
         unsigned sz = lp_scene_bin_size(scene, x, y);
         unsigned sz2 = util_logbase2(sz);
         debug_printf("%c", bits[MIN2(sz2,32)]);
      }
      debug_printf("\n");
   }
}
Ejemplo n.º 14
0
static char *
swizzle2d_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
{
   unsigned k = util_logbase2(MIN2(rect->w, rect->h));
   unsigned km = (1 << k) - 1;
   unsigned nx = rect->w >> k;
   unsigned tx = x >> k;
   unsigned ty = y >> k;
   unsigned m;

   m  = swizzle2d(x & km, 0);
   m |= swizzle2d(y & km, 1);
   m += ((ty * nx) + tx) << k << k;

   return base + (m * rect->cpp);
}
Ejemplo n.º 15
0
/**
 * Compute the partial offset of a pixel block along an arbitrary axis.
 *
 * @param coord   coordinate in pixels
 * @param stride  number of bytes between rows of successive pixel blocks
 * @param block_length  number of pixels in a pixels block along the coordinate
 *                      axis
 * @param out_offset    resulting relative offset of the pixel block in bytes
 * @param out_subcoord  resulting sub-block pixel coordinate
 */
void
lp_build_sample_partial_offset(struct lp_build_context *bld,
                               unsigned block_length,
                               LLVMValueRef coord,
                               LLVMValueRef stride,
                               LLVMValueRef *out_offset,
                               LLVMValueRef *out_subcoord)
{
   LLVMBuilderRef builder = bld->gallivm->builder;
   LLVMValueRef offset;
   LLVMValueRef subcoord;

   if (block_length == 1) {
      subcoord = bld->zero;
   }
   else {
      /*
       * Pixel blocks have power of two dimensions. LLVM should convert the
       * rem/div to bit arithmetic.
       * TODO: Verify this.
       * It does indeed BUT it does transform it to scalar (and back) when doing so
       * (using roughly extract, shift/and, mov, unpack) (llvm 2.7).
       * The generated code looks seriously unfunny and is quite expensive.
       */
#if 0
      LLVMValueRef block_width = lp_build_const_int_vec(bld->type, block_length);
      subcoord = LLVMBuildURem(builder, coord, block_width, "");
      coord    = LLVMBuildUDiv(builder, coord, block_width, "");
#else
      unsigned logbase2 = util_logbase2(block_length);
      LLVMValueRef block_shift = lp_build_const_int_vec(bld->gallivm, bld->type, logbase2);
      LLVMValueRef block_mask = lp_build_const_int_vec(bld->gallivm, bld->type, block_length - 1);
      subcoord = LLVMBuildAnd(builder, coord, block_mask, "");
      coord = LLVMBuildLShr(builder, coord, block_shift, "");
#endif
   }

   offset = lp_build_mul(bld, coord, stride);

   assert(out_offset);
   assert(out_subcoord);

   *out_offset = offset;
   *out_subcoord = subcoord;
}
Ejemplo n.º 16
0
/**
 * Make note of a branch to a label in the TGSI code.
 * After we've emitted all instructions, we'll go over the list
 * of labels built here and patch the TGSI code with the actual
 * location of each label.
 */
static unsigned *get_label( struct st_translate *t,
                            unsigned branch_target )
{
   unsigned i;

   if (t->labels_count + 1 >= t->labels_size) {
      t->labels_size = 1 << (util_logbase2(t->labels_size) + 1);
      t->labels = realloc(t->labels, t->labels_size * sizeof t->labels[0]);
      if (t->labels == NULL) {
         static unsigned dummy;
         t->error = TRUE;
         return &dummy;
      }
   }

   i = t->labels_count++;
   t->labels[i].branch_target = branch_target;
   return &t->labels[i].token;
}
Ejemplo n.º 17
0
/**
 * Try to allocate a pipe_resource object for the given st_texture_object.
 *
 * We use the given st_texture_image as a clue to determine the size of the
 * mipmap image at level=0.
 *
 * \return GL_TRUE for success, GL_FALSE if out of memory.
 */
static GLboolean
guess_and_alloc_texture(struct st_context *st,
			struct st_texture_object *stObj,
			const struct st_texture_image *stImage)
{
   GLuint lastLevel, width, height, depth;
   GLuint bindings;
   GLuint ptWidth, ptHeight, ptDepth, ptLayers;
   enum pipe_format fmt;

   DBG("%s\n", __FUNCTION__);

   assert(!stObj->pt);

   if (!guess_base_level_size(stObj->base.Target,
                              stImage->base.Width2,
                              stImage->base.Height2,
                              stImage->base.Depth2,
                              stImage->base.Level,
                              &width, &height, &depth)) {
      /* we can't determine the image size at level=0 */
      stObj->width0 = stObj->height0 = stObj->depth0 = 0;
      /* this is not an out of memory error */
      return GL_TRUE;
   }

   /* At this point, (width x height x depth) is the expected size of
    * the level=0 mipmap image.
    */

   /* Guess a reasonable value for lastLevel.  With OpenGL we have no
    * idea how many mipmap levels will be in a texture until we start
    * to render with it.  Make an educated guess here but be prepared
    * to re-allocating a texture buffer with space for more (or fewer)
    * mipmap levels later.
    */
   if ((stObj->base.Sampler.MinFilter == GL_NEAREST ||
        stObj->base.Sampler.MinFilter == GL_LINEAR ||
        stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
        stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
       !stObj->base.GenerateMipmap &&
       stImage->base.Level == 0) {
      /* only alloc space for a single mipmap level */
      lastLevel = 0;
   }
   else {
      /* alloc space for a full mipmap */
      GLuint l2width = util_logbase2(width);
      GLuint l2height = util_logbase2(height);
      GLuint l2depth = util_logbase2(depth);
      lastLevel = MAX2(MAX2(l2width, l2height), l2depth);
   }

   /* Save the level=0 dimensions */
   stObj->width0 = width;
   stObj->height0 = height;
   stObj->depth0 = depth;

   fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat);

   bindings = default_bindings(st, fmt);

   st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
                                   width, height, depth,
                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);

   stObj->pt = st_texture_create(st,
                                 gl_target_to_pipe(stObj->base.Target),
                                 fmt,
                                 lastLevel,
                                 ptWidth,
                                 ptHeight,
                                 ptDepth,
                                 ptLayers,
                                 bindings);

   stObj->lastLevel = lastLevel;

   DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));

   return stObj->pt != NULL;
}
Ejemplo n.º 18
0
static void
nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
                         unsigned buffers, double depth, unsigned stencil,
                         unsigned x, unsigned y, unsigned w, unsigned h)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_surface *sf = nv30_surface(ps);
   struct nv30_miptree *mt = nv30_miptree(ps->texture);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nouveau_pushbuf_refn refn;
   uint32_t rt_format, mode = 0;

   rt_format = nv30_format(pipe->screen, ps->format)->hw;
   if (util_format_get_blocksize(ps->format) == 4)
      rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
   else
      rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;

   if (nv30_miptree(ps->texture)->swizzled) {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      rt_format |= util_logbase2(sf->width) << 16;
      rt_format |= util_logbase2(sf->height) << 24;
   } else {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
   }

   if (buffers & PIPE_CLEAR_DEPTH)
      mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
   if (buffers & PIPE_CLEAR_STENCIL)
      mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;

   refn.bo = mt->base.bo;
   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
   if (nouveau_pushbuf_space(push, 32, 1, 0) ||
       nouveau_pushbuf_refn (push, &refn, 1))
      return;

   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
   PUSH_DATA (push, sf->width << 16);
   PUSH_DATA (push, sf->height << 16);
   PUSH_DATA (push, rt_format);
   if (eng3d->oclass < NV40_3D_CLASS) {
      BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 1);
      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
   } else {
      BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
      PUSH_DATA (push, sf->pitch);
   }
   BEGIN_NV04(push, NV30_3D(ZETA_OFFSET), 1);
   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (w << 16) | x);
   PUSH_DATA (push, (h << 16) | y);

   BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 1);
   PUSH_DATA (push, pack_zeta(ps->format, depth, stencil));
   BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
   PUSH_DATA (push, mode);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
Ejemplo n.º 19
0
int
nv50_screen_compute_setup(struct nv50_screen *screen,
                          struct nouveau_pushbuf *push)
{
   struct nouveau_device *dev = screen->base.device;
   struct nouveau_object *chan = screen->base.channel;
   struct nv04_fifo *fifo = (struct nv04_fifo *)chan->data;
   unsigned obj_class;
   int i, ret;

   switch (dev->chipset & 0xf0) {
   case 0x50:
   case 0x80:
   case 0x90:
      obj_class = NV50_COMPUTE_CLASS;
      break;
   case 0xa0:
      switch (dev->chipset) {
      case 0xa3:
      case 0xa5:
      case 0xa8:
         obj_class = NVA3_COMPUTE_CLASS;
         break;
      default:
         obj_class = NV50_COMPUTE_CLASS;
         break;
      }
      break;
   default:
      NOUVEAU_ERR("unsupported chipset: NV%02x\n", dev->chipset);
      return -1;
   }

   ret = nouveau_object_new(chan, 0xbeef50c0, obj_class, NULL, 0,
                            &screen->compute);
   if (ret)
      return ret;

   BEGIN_NV04(push, SUBC_COMPUTE(NV01_SUBCHAN_OBJECT), 1);
   PUSH_DATA (push, screen->compute->handle);

   BEGIN_NV04(push, NV50_COMPUTE(UNK02A0), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_COMPUTE(DMA_STACK), 1);
   PUSH_DATA (push, fifo->vram);
   BEGIN_NV04(push, NV50_COMPUTE(STACK_ADDRESS_HIGH), 2);
   PUSH_DATAh(push, screen->stack_bo->offset);
   PUSH_DATA (push, screen->stack_bo->offset);
   BEGIN_NV04(push, NV50_COMPUTE(STACK_SIZE_LOG), 1);
   PUSH_DATA (push, 4);

   BEGIN_NV04(push, NV50_COMPUTE(UNK0290), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_COMPUTE(LANES32_ENABLE), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_COMPUTE(REG_MODE), 1);
   PUSH_DATA (push, NV50_COMPUTE_REG_MODE_STRIPED);
   BEGIN_NV04(push, NV50_COMPUTE(UNK0384), 1);
   PUSH_DATA (push, 0x100);
   BEGIN_NV04(push, NV50_COMPUTE(DMA_GLOBAL), 1);
   PUSH_DATA (push, fifo->vram);

   for (i = 0; i < 15; i++) {
      BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_ADDRESS_HIGH(i)), 2);
      PUSH_DATA (push, 0);
      PUSH_DATA (push, 0);
      BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_LIMIT(i)), 1);
      PUSH_DATA (push, 0);
      BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_MODE(i)), 1);
      PUSH_DATA (push, NV50_COMPUTE_GLOBAL_MODE_LINEAR);
   }

   BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_ADDRESS_HIGH(15)), 2);
   PUSH_DATA (push, 0);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_LIMIT(15)), 1);
   PUSH_DATA (push, ~0);
   BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_MODE(15)), 1);
   PUSH_DATA (push, NV50_COMPUTE_GLOBAL_MODE_LINEAR);

   BEGIN_NV04(push, NV50_COMPUTE(LOCAL_WARPS_LOG_ALLOC), 1);
   PUSH_DATA (push, 7);
   BEGIN_NV04(push, NV50_COMPUTE(LOCAL_WARPS_NO_CLAMP), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_COMPUTE(STACK_WARPS_LOG_ALLOC), 1);
   PUSH_DATA (push, 7);
   BEGIN_NV04(push, NV50_COMPUTE(STACK_WARPS_NO_CLAMP), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_COMPUTE(USER_PARAM_COUNT), 1);
   PUSH_DATA (push, 0);

   BEGIN_NV04(push, NV50_COMPUTE(DMA_TEXTURE), 1);
   PUSH_DATA (push, fifo->vram);
   BEGIN_NV04(push, NV50_COMPUTE(TEX_LIMITS), 1);
   PUSH_DATA (push, 0x54);
   BEGIN_NV04(push, NV50_COMPUTE(LINKED_TSC), 1);
   PUSH_DATA (push, 0);

   BEGIN_NV04(push, NV50_COMPUTE(DMA_TIC), 1);
   PUSH_DATA (push, fifo->vram);
   BEGIN_NV04(push, NV50_COMPUTE(TIC_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->txc->offset);
   PUSH_DATA (push, screen->txc->offset);
   PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);

   BEGIN_NV04(push, NV50_COMPUTE(DMA_TSC), 1);
   PUSH_DATA (push, fifo->vram);
   BEGIN_NV04(push, NV50_COMPUTE(TSC_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->txc->offset + 65536);
   PUSH_DATA (push, screen->txc->offset + 65536);
   PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);

   BEGIN_NV04(push, NV50_COMPUTE(DMA_CODE_CB), 1);
   PUSH_DATA (push, fifo->vram);

   BEGIN_NV04(push, NV50_COMPUTE(DMA_LOCAL), 1);
   PUSH_DATA (push, fifo->vram);
   BEGIN_NV04(push, NV50_COMPUTE(LOCAL_ADDRESS_HIGH), 2);
   PUSH_DATAh(push, screen->tls_bo->offset + 65536);
   PUSH_DATA (push, screen->tls_bo->offset + 65536);
   BEGIN_NV04(push, NV50_COMPUTE(LOCAL_SIZE_LOG), 1);
   PUSH_DATA (push, util_logbase2((screen->max_tls_space / ONE_TEMP_SIZE) * 2));

   return 0;
}
Ejemplo n.º 20
0
static struct pipe_sampler_view *
nv30_sampler_view_create(struct pipe_context *pipe, struct pipe_resource *pt,
                         const struct pipe_sampler_view *tmpl)
{
   const struct nv30_texfmt *fmt = nv30_texfmt(pipe->screen, tmpl->format);
   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
   struct nv30_miptree *mt = nv30_miptree(pt);
   struct nv30_sampler_view *so;

   so = MALLOC_STRUCT(nv30_sampler_view);
   if (!so)
      return NULL;
   so->pipe = *tmpl;
   so->pipe.reference.count = 1;
   so->pipe.texture = NULL;
   so->pipe.context = pipe;
   pipe_resource_reference(&so->pipe.texture, pt);

   so->fmt = NV30_3D_TEX_FORMAT_NO_BORDER;
   switch (pt->target) {
   case PIPE_TEXTURE_1D:
      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_1D;
      break;
   case PIPE_TEXTURE_CUBE:
      so->fmt |= NV30_3D_TEX_FORMAT_CUBIC;
   case PIPE_TEXTURE_2D:
   case PIPE_TEXTURE_RECT:
      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_2D;
      break;
   case PIPE_TEXTURE_3D:
      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_3D;
      break;
   default:
      assert(0);
      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_1D;
      break;
   }

   so->filt = fmt->filter;
   so->wrap = fmt->wrap;
   so->swz  = fmt->swizzle;
   so->swz |= swizzle(fmt, 3, tmpl->swizzle_a);
   so->swz |= swizzle(fmt, 0, tmpl->swizzle_r) << 2;
   so->swz |= swizzle(fmt, 1, tmpl->swizzle_g) << 4;
   so->swz |= swizzle(fmt, 2, tmpl->swizzle_b) << 6;

   /* apparently, we need to ignore the t coordinate for 1D textures to
    * fix piglit tex1d-2dborder
    */
   so->wrap_mask = ~0;
   if (pt->target == PIPE_TEXTURE_1D) {
      so->wrap_mask &= ~NV30_3D_TEX_WRAP_T__MASK;
      so->wrap      |=  NV30_3D_TEX_WRAP_T_REPEAT;
   }

   /* yet more hardware suckage, can't filter 32-bit float formats */
   switch (tmpl->format) {
   case PIPE_FORMAT_R32_FLOAT:
   case PIPE_FORMAT_R32G32B32A32_FLOAT:
      so->filt_mask = ~(NV30_3D_TEX_FILTER_MIN__MASK |
                        NV30_3D_TEX_FILTER_MAG__MASK);
      so->filt     |= NV30_3D_TEX_FILTER_MIN_NEAREST |
                      NV30_3D_TEX_FILTER_MAG_NEAREST;
      break;
   default:
      so->filt_mask = ~0;
      break;
   }

   so->npot_size0 = (pt->width0 << 16) | pt->height0;
   if (eng3d->oclass >= NV40_3D_CLASS) {
      so->npot_size1 = (pt->depth0 << 20) | mt->uniform_pitch;
      if (!mt->swizzled)
         so->fmt |= NV40_3D_TEX_FORMAT_LINEAR;
      so->fmt |= 0x00008000;
      so->fmt |= (pt->last_level + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT;
   } else {
      so->swz |= mt->uniform_pitch << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT;
      if (pt->last_level)
         so->fmt |= NV30_3D_TEX_FORMAT_MIPMAP;
      so->fmt |= util_logbase2(pt->width0)  << 20;
      so->fmt |= util_logbase2(pt->height0) << 24;
      so->fmt |= util_logbase2(pt->depth0)  << 28;
      so->fmt |= 0x00010000;
   }

   so->base_lod = so->pipe.u.tex.first_level << 8;
   so->high_lod = MIN2(pt->last_level, so->pipe.u.tex.last_level) << 8;
   return &so->pipe;
}
Ejemplo n.º 21
0
static int
svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   SVGA3dDevCapResult result;

   switch (param) {
   case PIPE_CAP_NPOT_TEXTURES:
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
      /*
       * "In virtually every OpenGL implementation and hardware,
       * GL_MAX_DUAL_SOURCE_DRAW_BUFFERS is 1"
       * http://www.opengl.org/wiki/Blending
       */
      return sws->have_vgpu10 ? 1 : 0;
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return 1;
   case PIPE_CAP_POINT_SPRITE:
      return 1;
   case PIPE_CAP_TGSI_TEXCOORD:
      return 0;
   case PIPE_CAP_MAX_RENDER_TARGETS:
      return svgascreen->max_color_buffers;
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
   case PIPE_CAP_QUERY_TIME_ELAPSED:
      return 0;
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
      return sws->have_vgpu10;
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return 0;
   case PIPE_CAP_USER_VERTEX_BUFFERS:
   case PIPE_CAP_USER_INDEX_BUFFERS:
      return 0;
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
      return 1;
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      return 256;

   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
      {
         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         return levels;
      }

   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
         return 8;  /* max 128x128x128 */
      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);

   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
      /*
       * No mechanism to query the host, and at least limited to 2048x2048 on
       * certain hardware.
       */
      return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
                  12 /* 2048x2048 */);

   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
      return sws->have_vgpu10 ? SVGA3D_MAX_SURFACE_ARRAYSIZE : 0;

   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
      return 1;

   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
      return 1;
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
      return sws->have_vgpu10;
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
      return 0;
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return !sws->have_vgpu10;

   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return 1; /* The color outputs of vertex shaders are not clamped */
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
      return 0; /* The driver can't clamp vertex colors */
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
      return 0; /* The driver can't clamp fragment colors */

   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
      return 1; /* expected for GL_ARB_framebuffer_object */

   case PIPE_CAP_GLSL_FEATURE_LEVEL:
      return sws->have_vgpu10 ? 330 : 120;

   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
      return 0;

   case PIPE_CAP_SM3:
      return 1;

   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_QUERY_TIMESTAMP:
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_FAKE_SW_MSAA:
      return sws->have_vgpu10;

   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
      return sws->have_vgpu10 ? SVGA3D_DX_MAX_SOTARGETS : 0;
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
      return sws->have_vgpu10 ? 4 : 0;
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
      return sws->have_vgpu10 ? SVGA3D_MAX_STREAMOUT_DECLS : 0;
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
      return 0;
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
      return svgascreen->ms_samples ? 1 : 0;

   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
      return SVGA3D_DX_MAX_RESOURCE_SIZE;

   case PIPE_CAP_MIN_TEXEL_OFFSET:
      return sws->have_vgpu10 ? VGPU10_MIN_TEXEL_FETCH_OFFSET : 0;
   case PIPE_CAP_MAX_TEXEL_OFFSET:
      return sws->have_vgpu10 ? VGPU10_MAX_TEXEL_FETCH_OFFSET : 0;

   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
      return 0;

   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
      return sws->have_vgpu10 ? 256 : 0;
   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
      return sws->have_vgpu10 ? 1024 : 0;

   case PIPE_CAP_PRIMITIVE_RESTART:
      return 1; /* may be a sw fallback, depending on restart index */

   case PIPE_CAP_GENERATE_MIPMAP:
      return sws->have_vgpu10;

   /* Unsupported features */
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_TEXTURE_BARRIER:
   case PIPE_CAP_MAX_VERTEX_STREAMS:
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
   case PIPE_CAP_COMPUTE:
   case PIPE_CAP_START_INSTANCE:
   case PIPE_CAP_CUBE_MAP_ARRAY:
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
   case PIPE_CAP_TEXTURE_GATHER_SM5:
   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
   case PIPE_CAP_TEXTURE_QUERY_LOD:
   case PIPE_CAP_SAMPLE_SHADING:
   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
   case PIPE_CAP_DRAW_INDIRECT:
   case PIPE_CAP_MULTI_DRAW_INDIRECT:
   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
   case PIPE_CAP_SAMPLER_VIEW_TARGET:
   case PIPE_CAP_CLIP_HALFZ:
   case PIPE_CAP_VERTEXID_NOBASE:
   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
   case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
   case PIPE_CAP_INVALIDATE_BUFFER:
   case PIPE_CAP_STRING_MARKER:
   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
   case PIPE_CAP_QUERY_MEMORY_INFO:
   case PIPE_CAP_PCI_GROUP:
   case PIPE_CAP_PCI_BUS:
   case PIPE_CAP_PCI_DEVICE:
   case PIPE_CAP_PCI_FUNCTION:
      return 0;
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return 64;
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
      return 1;  /* need 4-byte alignment for all offsets and strides */
   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
      return 2048;
   case PIPE_CAP_MAX_VIEWPORTS:
      return 1;
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;

   case PIPE_CAP_VENDOR_ID:
      return 0x15ad; /* VMware Inc. */
   case PIPE_CAP_DEVICE_ID:
      return 0x0405; /* assume SVGA II */
   case PIPE_CAP_ACCELERATED:
      return 0; /* XXX: */
   case PIPE_CAP_VIDEO_MEMORY:
      /* XXX: Query the host ? */
      return 1;
   case PIPE_CAP_UMA:
   case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
   case PIPE_CAP_DEPTH_BOUNDS_TEST:
   case PIPE_CAP_TGSI_TXQS:
   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
   case PIPE_CAP_SHAREABLE_SHADERS:
   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
   case PIPE_CAP_CLEAR_TEXTURE:
   case PIPE_CAP_DRAW_PARAMETERS:
   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
   case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
   case PIPE_CAP_QUERY_BUFFER_OBJECT:
      return 0;
   }

   debug_printf("Unexpected PIPE_CAP_ query %u\n", param);
   return 0;
}
Ejemplo n.º 22
0
/*
 * Do a cached lookup.
 *
 * Returns (vectors of) 4x8 rgba aos value
 */
LLVMValueRef
lp_build_fetch_cached_texels(struct gallivm_state *gallivm,
                             const struct util_format_description *format_desc,
                             unsigned n,
                             LLVMValueRef base_ptr,
                             LLVMValueRef offset,
                             LLVMValueRef i,
                             LLVMValueRef j,
                             LLVMValueRef cache)

{
   LLVMBuilderRef builder = gallivm->builder;
   unsigned count, low_bit, log2size;
   LLVMValueRef color, offset_stored, addr, ptr_addrtrunc, tmp;
   LLVMValueRef ij_index, hash_index, hash_mask, block_index;
   LLVMTypeRef i8t = LLVMInt8TypeInContext(gallivm->context);
   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
   LLVMTypeRef i64t = LLVMInt64TypeInContext(gallivm->context);
   struct lp_type type;
   struct lp_build_context bld32;
   memset(&type, 0, sizeof type);
   type.width = 32;
   type.length = n;

   assert(format_desc->block.width == 4);
   assert(format_desc->block.height == 4);

   lp_build_context_init(&bld32, gallivm, type);

   /*
    * compute hash - we use direct mapped cache, the hash function could
    *                be better but it needs to be simple
    * per-element:
    *    compare offset with offset stored at tag (hash)
    *    if not equal decode/store block, update tag
    *    extract color from cache
    *    assemble result vector
    */

   /* TODO: not ideal with 32bit pointers... */

   low_bit = util_logbase2(format_desc->block.bits / 8);
   log2size = util_logbase2(LP_BUILD_FORMAT_CACHE_SIZE);
   addr = LLVMBuildPtrToInt(builder, base_ptr, i64t, "");
   ptr_addrtrunc = LLVMBuildPtrToInt(builder, base_ptr, i32t, "");
   ptr_addrtrunc = lp_build_broadcast_scalar(&bld32, ptr_addrtrunc);
   /* For the hash function, first mask off the unused lowest bits. Then just
      do some xor with address bits - only use lower 32bits */
   ptr_addrtrunc = LLVMBuildAdd(builder, offset, ptr_addrtrunc, "");
   ptr_addrtrunc = LLVMBuildLShr(builder, ptr_addrtrunc,
                                 lp_build_const_int_vec(gallivm, type, low_bit), "");
   /* This only really makes sense for size 64,128,256 */
   hash_index = ptr_addrtrunc;
   ptr_addrtrunc = LLVMBuildLShr(builder, ptr_addrtrunc,
                                 lp_build_const_int_vec(gallivm, type, 2*log2size), "");
   hash_index = LLVMBuildXor(builder, ptr_addrtrunc, hash_index, "");
   tmp = LLVMBuildLShr(builder, hash_index,
                       lp_build_const_int_vec(gallivm, type, log2size), "");
   hash_index = LLVMBuildXor(builder, hash_index, tmp, "");

   hash_mask = lp_build_const_int_vec(gallivm, type, LP_BUILD_FORMAT_CACHE_SIZE - 1);
   hash_index = LLVMBuildAnd(builder, hash_index, hash_mask, "");
   ij_index = LLVMBuildShl(builder, i, lp_build_const_int_vec(gallivm, type, 2), "");
   ij_index = LLVMBuildAdd(builder, ij_index, j, "");
   block_index = LLVMBuildShl(builder, hash_index,
                              lp_build_const_int_vec(gallivm, type, 4), "");
   block_index = LLVMBuildAdd(builder, ij_index, block_index, "");

   if (n > 1) {
      color = LLVMGetUndef(LLVMVectorType(i32t, n));
      for (count = 0; count < n; count++) {
         LLVMValueRef index, cond, colorx;
         LLVMValueRef block_indexx, hash_indexx, addrx, offsetx, ptr_addrx;
         struct lp_build_if_state if_ctx;

         index = lp_build_const_int32(gallivm, count);
         offsetx = LLVMBuildExtractElement(builder, offset, index, "");
         addrx = LLVMBuildZExt(builder, offsetx, i64t, "");
         addrx = LLVMBuildAdd(builder, addrx, addr, "");
         block_indexx = LLVMBuildExtractElement(builder, block_index, index, "");
         hash_indexx = LLVMBuildLShr(builder, block_indexx,
                                     lp_build_const_int32(gallivm, 4), "");
         offset_stored = lookup_tag_data(gallivm, cache, hash_indexx);
         cond = LLVMBuildICmp(builder, LLVMIntNE, offset_stored, addrx, "");

         lp_build_if(&if_ctx, gallivm, cond);
         {
            ptr_addrx = LLVMBuildIntToPtr(builder, addrx,
                                          LLVMPointerType(i8t, 0), "");
            update_cached_block(gallivm, format_desc, ptr_addrx, hash_indexx, cache);
#if LP_BUILD_FORMAT_CACHE_DEBUG
            update_cache_access(gallivm, cache, 1,
                                LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_MISS);
#endif
         }
         lp_build_endif(&if_ctx);

         colorx = lookup_cached_pixel(gallivm, cache, block_indexx);

         color = LLVMBuildInsertElement(builder, color, colorx,
                                        lp_build_const_int32(gallivm, count), "");
      }
   }
   else {
      LLVMValueRef cond;
      struct lp_build_if_state if_ctx;

      tmp = LLVMBuildZExt(builder, offset, i64t, "");
      addr = LLVMBuildAdd(builder, tmp, addr, "");
      offset_stored = lookup_tag_data(gallivm, cache, hash_index);
      cond = LLVMBuildICmp(builder, LLVMIntNE, offset_stored, addr, "");

      lp_build_if(&if_ctx, gallivm, cond);
      {
         tmp = LLVMBuildIntToPtr(builder, addr, LLVMPointerType(i8t, 0), "");
         update_cached_block(gallivm, format_desc, tmp, hash_index, cache);
#if LP_BUILD_FORMAT_CACHE_DEBUG
         update_cache_access(gallivm, cache, 1,
                             LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_MISS);
#endif
      }
      lp_build_endif(&if_ctx);

      color = lookup_cached_pixel(gallivm, cache, block_index);
   }
#if LP_BUILD_FORMAT_CACHE_DEBUG
   update_cache_access(gallivm, cache, n,
                       LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_TOTAL);
#endif
   return LLVMBuildBitCast(builder, color, LLVMVectorType(i8t, n * 4), "");
}
Ejemplo n.º 23
0
static int
svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   SVGA3dDevCapResult result;

   switch (param) {
   case PIPE_CAP_NPOT_TEXTURES:
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
      return 0;
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return 1;
   case PIPE_CAP_POINT_SPRITE:
      return 1;
   case PIPE_CAP_TGSI_TEXCOORD:
      return 0;
   case PIPE_CAP_MAX_RENDER_TARGETS:
      return svgascreen->max_color_buffers;
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
   case PIPE_CAP_QUERY_TIME_ELAPSED:
      return 0;
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return 0;
   case PIPE_CAP_USER_VERTEX_BUFFERS:
   case PIPE_CAP_USER_INDEX_BUFFERS:
      return 0;
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
      return 1;
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      return 16;

   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
      {
         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         return levels;
      }

   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
         return 8;  /* max 128x128x128 */
      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);

   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
      /*
       * No mechanism to query the host, and at least limited to 2048x2048 on
       * certain hardware.
       */
      return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
                  12 /* 2048x2048 */);

   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
      return 1;

   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
      return 1;
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
      return 0;
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
      return 0;
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return 1;

   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return 1; /* The color outputs of vertex shaders are not clamped */
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
      return 0; /* The driver can't clamp vertex colors */
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
      return 0; /* The driver can't clamp fragment colors */

   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
      return 1; /* expected for GL_ARB_framebuffer_object */

   case PIPE_CAP_GLSL_FEATURE_LEVEL:
      return 120;

   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
      return 0;

   case PIPE_CAP_SM3:
      return 1;

   /* Unsupported features */
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
   case PIPE_CAP_PRIMITIVE_RESTART:
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
   case PIPE_CAP_MIN_TEXEL_OFFSET:
   case PIPE_CAP_MAX_TEXEL_OFFSET:
   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_TEXTURE_BARRIER:
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
   case PIPE_CAP_MAX_VERTEX_STREAMS:
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_COMPUTE:
   case PIPE_CAP_START_INSTANCE:
   case PIPE_CAP_QUERY_TIMESTAMP:
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
   case PIPE_CAP_CUBE_MAP_ARRAY:
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
   case PIPE_CAP_TEXTURE_GATHER_SM5:
   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
   case PIPE_CAP_RASTERIZER_LOWER_LEFT_ORIGIN:
   case PIPE_CAP_FAKE_SW_MSAA:
   case PIPE_CAP_TEXTURE_QUERY_LOD:
   case PIPE_CAP_SAMPLE_SHADING:
   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
   case PIPE_CAP_DRAW_INDIRECT:
   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
      return 0;
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return 64;
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
      return 1;
   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
      return 2048;
   case PIPE_CAP_MAX_VIEWPORTS:
      return 1;
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;

   case PIPE_CAP_VENDOR_ID:
      return 0x15ad; /* VMware Inc. */
   case PIPE_CAP_DEVICE_ID:
      return 0x0405; /* assume SVGA II */
   case PIPE_CAP_ACCELERATED:
      return 0; /* XXX: */
   case PIPE_CAP_VIDEO_MEMORY:
      /* XXX: Query the host ? */
      return 1;
   case PIPE_CAP_UMA:
      return 0;
   }

   debug_printf("Unexpected PIPE_CAP_ query %u\n", param);
   return 0;
}
static int
svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   SVGA3dDevCapResult result;

   switch (param) {
   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
      return 16;
   case PIPE_CAP_NPOT_TEXTURES:
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
      return 0;
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return 1;
   case PIPE_CAP_POINT_SPRITE:
      return 1;
   case PIPE_CAP_MAX_RENDER_TARGETS:
      if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
         return 1;
      if(!result.u)
         return 1;
      return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
   case PIPE_CAP_QUERY_TIME_ELAPSED:
      return 0;
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
   case PIPE_CAP_USER_VERTEX_BUFFERS:
   case PIPE_CAP_USER_INDEX_BUFFERS:
      return 0;
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
      return 1;
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      return 16;

   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
      {
         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         return levels;
      }

   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
         return 8;  /* max 128x128x128 */
      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);

   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
      /*
       * No mechanism to query the host, and at least limited to 2048x2048 on
       * certain hardware.
       */
      return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
                  12 /* 2048x2048 */);

   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
      return 1;

   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
      return 1;
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return 0;

   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return 1; /* The color outputs of vertex shaders are not clamped */
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
      return 0; /* The driver can't clamp vertex colors */
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
      return 0; /* The driver can't clamp fragment colors */

   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
      return 1; /* expected for GL_ARB_framebuffer_object */

   case PIPE_CAP_GLSL_FEATURE_LEVEL:
      return 120;

   /* Unsupported features */
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_SM3:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
   case PIPE_CAP_PRIMITIVE_RESTART:
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
   case PIPE_CAP_SCALED_RESOLVE:
   case PIPE_CAP_MIN_TEXEL_OFFSET:
   case PIPE_CAP_MAX_TEXEL_OFFSET:
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_TEXTURE_BARRIER:
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
   case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_COMPUTE:
   case PIPE_CAP_START_INSTANCE:
   case PIPE_CAP_QUERY_TIMESTAMP:
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
   case PIPE_CAP_CUBE_MAP_ARRAY:
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
      return 0;
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
      return 1;
   }

   debug_printf("Unexpected PIPE_CAP_ query %u\n", param);
   return 0;
}
Ejemplo n.º 25
0
static void
nv30_transfer_rect_sifm(XFER_ARGS)

{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_pushbuf_refn refs[] = {
      { src->bo, src->domain | NOUVEAU_BO_RD },
      { dst->bo, dst->domain | NOUVEAU_BO_WR },
   };
   struct nv04_fifo *fifo = push->channel->data;
   unsigned si_fmt, si_arg;
   unsigned ss_fmt;

   switch (dst->cpp) {
   case 4: ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_A8R8G8B8; break;
   case 2: ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_R5G6B5; break;
   default:
      ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_Y8;
      break;
   }

   switch (src->cpp) {
   case 4: si_fmt = NV03_SIFM_COLOR_FORMAT_A8R8G8B8; break;
   case 2: si_fmt = NV03_SIFM_COLOR_FORMAT_R5G6B5; break;
   default:
      si_fmt = NV03_SIFM_COLOR_FORMAT_AY8;
      break;
   }

   if (filter == NEAREST) {
      si_arg  = NV03_SIFM_FORMAT_ORIGIN_CENTER;
      si_arg |= NV03_SIFM_FORMAT_FILTER_POINT_SAMPLE;
   } else {
      si_arg  = NV03_SIFM_FORMAT_ORIGIN_CORNER;
      si_arg |= NV03_SIFM_FORMAT_FILTER_BILINEAR;
   }

   if (nouveau_pushbuf_space(push, 32, 6, 0) ||
       nouveau_pushbuf_refn (push, refs, 2))
      return;

   if (dst->pitch) {
      BEGIN_NV04(push, NV04_SF2D(DMA_IMAGE_SOURCE), 2);
      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
      BEGIN_NV04(push, NV04_SF2D(FORMAT), 4);
      PUSH_DATA (push, ss_fmt);
      PUSH_DATA (push, dst->pitch << 16 | dst->pitch);
      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
      BEGIN_NV04(push, NV05_SIFM(SURFACE), 1);
      PUSH_DATA (push, nv30->screen->surf2d->handle);
   } else {
      BEGIN_NV04(push, NV04_SSWZ(DMA_IMAGE), 1);
      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
      BEGIN_NV04(push, NV04_SSWZ(FORMAT), 2);
      PUSH_DATA (push, ss_fmt | (util_logbase2(dst->w) << 16) |
                                (util_logbase2(dst->h) << 24));
      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
      BEGIN_NV04(push, NV05_SIFM(SURFACE), 1);
      PUSH_DATA (push, nv30->screen->swzsurf->handle);
   }

   BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1);
   PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
   BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 8);
   PUSH_DATA (push, si_fmt);
   PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY);
   PUSH_DATA (push, (           dst->y0  << 16) |            dst->x0);
   PUSH_DATA (push, ((dst->y1 - dst->y0) << 16) | (dst->x1 - dst->x0));
   PUSH_DATA (push, (           dst->y0  << 16) |            dst->x0);
   PUSH_DATA (push, ((dst->y1 - dst->y0) << 16) | (dst->x1 - dst->x0));
   PUSH_DATA (push, ((src->x1 - src->x0) << 20) / (dst->x1 - dst->x0));
   PUSH_DATA (push, ((src->y1 - src->y0) << 20) / (dst->y1 - dst->y0));
   BEGIN_NV04(push, NV03_SIFM(SIZE), 4);
   PUSH_DATA (push, align(src->h, 2) << 16 | align(src->w, 2));
   PUSH_DATA (push, src->pitch | si_arg);
   PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
   PUSH_DATA (push, (src->y0 << 20) | src->x0 << 4);
}
Ejemplo n.º 26
0
bool r600_common_screen_init(struct r600_common_screen *rscreen,
			     struct radeon_winsys *ws)
{
	char llvm_string[32] = {}, kernel_version[128] = {};
	struct utsname uname_data;

	ws->query_info(ws, &rscreen->info);

	if (uname(&uname_data) == 0)
		snprintf(kernel_version, sizeof(kernel_version),
			 " / %s", uname_data.release);

#if HAVE_LLVM
	snprintf(llvm_string, sizeof(llvm_string),
		 ", LLVM %i.%i.%i", (HAVE_LLVM >> 8) & 0xff,
		 HAVE_LLVM & 0xff, MESA_LLVM_VERSION_PATCH);
#endif

	snprintf(rscreen->renderer_string, sizeof(rscreen->renderer_string),
		 "%s (DRM %i.%i.%i%s%s)",
		 r600_get_chip_name(rscreen), rscreen->info.drm_major,
		 rscreen->info.drm_minor, rscreen->info.drm_patchlevel,
		 kernel_version, llvm_string);

	rscreen->b.get_name = r600_get_name;
	rscreen->b.get_vendor = r600_get_vendor;
	rscreen->b.get_device_vendor = r600_get_device_vendor;
	rscreen->b.get_compute_param = r600_get_compute_param;
	rscreen->b.get_paramf = r600_get_paramf;
	rscreen->b.get_timestamp = r600_get_timestamp;
	rscreen->b.fence_finish = r600_fence_finish;
	rscreen->b.fence_reference = r600_fence_reference;
	rscreen->b.resource_destroy = u_resource_destroy_vtbl;
	rscreen->b.resource_from_user_memory = r600_buffer_from_user_memory;
	rscreen->b.query_memory_info = r600_query_memory_info;

	if (rscreen->info.has_uvd) {
		rscreen->b.get_video_param = rvid_get_video_param;
		rscreen->b.is_video_format_supported = rvid_is_format_supported;
	} else {
		rscreen->b.get_video_param = r600_get_video_param;
		rscreen->b.is_video_format_supported = vl_video_buffer_is_format_supported;
	}

	r600_init_screen_texture_functions(rscreen);
	r600_init_screen_query_functions(rscreen);

	rscreen->ws = ws;
	rscreen->family = rscreen->info.family;
	rscreen->chip_class = rscreen->info.chip_class;
	rscreen->debug_flags = debug_get_flags_option("R600_DEBUG", common_debug_options, 0);

	rscreen->force_aniso = MIN2(16, debug_get_num_option("R600_TEX_ANISO", -1));
	if (rscreen->force_aniso >= 0) {
		printf("radeon: Forcing anisotropy filter to %ix\n",
		       /* round down to a power of two */
		       1 << util_logbase2(rscreen->force_aniso));
	}

	util_format_s3tc_init();
	pipe_mutex_init(rscreen->aux_context_lock);
	pipe_mutex_init(rscreen->gpu_load_mutex);

	if (rscreen->debug_flags & DBG_INFO) {
		printf("pci_id = 0x%x\n", rscreen->info.pci_id);
		printf("family = %i (%s)\n", rscreen->info.family,
		       r600_get_chip_name(rscreen));
		printf("chip_class = %i\n", rscreen->info.chip_class);
		printf("gart_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.gart_size, 1024*1024));
		printf("vram_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.vram_size, 1024*1024));
		printf("max_alloc_size = %i MB\n",
		       (int)DIV_ROUND_UP(rscreen->info.max_alloc_size, 1024*1024));
		printf("has_virtual_memory = %i\n", rscreen->info.has_virtual_memory);
		printf("gfx_ib_pad_with_type2 = %i\n", rscreen->info.gfx_ib_pad_with_type2);
		printf("has_sdma = %i\n", rscreen->info.has_sdma);
		printf("has_uvd = %i\n", rscreen->info.has_uvd);
		printf("vce_fw_version = %i\n", rscreen->info.vce_fw_version);
		printf("vce_harvest_config = %i\n", rscreen->info.vce_harvest_config);
		printf("clock_crystal_freq = %i\n", rscreen->info.clock_crystal_freq);
		printf("drm = %i.%i.%i\n", rscreen->info.drm_major,
		       rscreen->info.drm_minor, rscreen->info.drm_patchlevel);
		printf("has_userptr = %i\n", rscreen->info.has_userptr);

		printf("r600_max_quad_pipes = %i\n", rscreen->info.r600_max_quad_pipes);
		printf("max_shader_clock = %i\n", rscreen->info.max_shader_clock);
		printf("num_good_compute_units = %i\n", rscreen->info.num_good_compute_units);
		printf("max_se = %i\n", rscreen->info.max_se);
		printf("max_sh_per_se = %i\n", rscreen->info.max_sh_per_se);

		printf("r600_gb_backend_map = %i\n", rscreen->info.r600_gb_backend_map);
		printf("r600_gb_backend_map_valid = %i\n", rscreen->info.r600_gb_backend_map_valid);
		printf("r600_num_banks = %i\n", rscreen->info.r600_num_banks);
		printf("num_render_backends = %i\n", rscreen->info.num_render_backends);
		printf("num_tile_pipes = %i\n", rscreen->info.num_tile_pipes);
		printf("pipe_interleave_bytes = %i\n", rscreen->info.pipe_interleave_bytes);
	}
	return true;
}
Ejemplo n.º 27
0
static HRESULT
NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This,
                         struct NineUnknownParams *pParams,
                         UINT Width, UINT Height, UINT Depth, UINT Levels,
                         DWORD Usage,
                         D3DFORMAT Format,
                         D3DPOOL Pool,
                         HANDLE *pSharedHandle )
{
    struct pipe_resource *info = &This->base.base.info;
    struct pipe_screen *screen = pParams->device->screen;
    enum pipe_format pf;
    unsigned l;
    D3DVOLUME_DESC voldesc;
    HRESULT hr;

    DBG("This=%p pParams=%p Width=%u Height=%u Depth=%u Levels=%u "
        "Usage=%d Format=%d Pool=%d pSharedHandle=%p\n",
        This, pParams, Width, Height, Depth, Levels,
        Usage, Format, Pool, pSharedHandle);

    user_assert(Width && Height && Depth, D3DERR_INVALIDCALL);

    /* user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); */
    user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */

    /* An IDirect3DVolume9 cannot be bound as a render target can it ? */
    user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)),
                D3DERR_INVALIDCALL);
    user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP), D3DERR_INVALIDCALL);

    pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_3D, 0,
                                     PIPE_BIND_SAMPLER_VIEW, FALSE,
                                     Pool == D3DPOOL_SCRATCH);

    if (pf == PIPE_FORMAT_NONE)
        return D3DERR_INVALIDCALL;

    /* We support ATI1 and ATI2 hacks only for 2D and Cube textures */
    if (Format == D3DFMT_ATI1 || Format == D3DFMT_ATI2)
        return D3DERR_INVALIDCALL;

    if (compressed_format(Format)) {
        const unsigned w = util_format_get_blockwidth(pf);
        const unsigned h = util_format_get_blockheight(pf);
        /* Compressed formats are not compressed on depth component */
        user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
    }

    info->screen = pParams->device->screen;
    info->target = PIPE_TEXTURE_3D;
    info->format = pf;
    info->width0 = Width;
    info->height0 = Height;
    info->depth0 = Depth;
    if (Levels)
        info->last_level = Levels - 1;
    else
        info->last_level = util_logbase2(MAX2(MAX2(Width, Height), Depth));
    info->array_size = 1;
    info->nr_samples = 0;
    info->bind = PIPE_BIND_SAMPLER_VIEW;
    info->usage = PIPE_USAGE_DEFAULT;
    info->flags = 0;

    if (Usage & D3DUSAGE_DYNAMIC) {
        info->usage = PIPE_USAGE_DYNAMIC;
        info->bind |=
            PIPE_BIND_TRANSFER_READ |
            PIPE_BIND_TRANSFER_WRITE;
    }
    if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
        DBG("Application asked for Software Vertex Processing, "
            "but this is unimplemented\n");

    This->volumes = CALLOC(info->last_level + 1, sizeof(*This->volumes));
    if (!This->volumes)
        return E_OUTOFMEMORY;
    This->base.pstype = 3;

    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL,
                               D3DRTYPE_VOLUMETEXTURE, Format, Pool, Usage);
    if (FAILED(hr))
        return hr;

    voldesc.Format = Format;
    voldesc.Type = D3DRTYPE_VOLUME;
    voldesc.Usage = Usage;
    voldesc.Pool = Pool;
    for (l = 0; l <= info->last_level; ++l) {
        voldesc.Width = u_minify(Width, l);
        voldesc.Height = u_minify(Height, l);
        voldesc.Depth = u_minify(Depth, l);

        hr = NineVolume9_new(This->base.base.base.device, NineUnknown(This),
                             This->base.base.resource, l,
                             &voldesc, &This->volumes[l]);
        if (FAILED(hr))
            return hr;
    }

    /* Textures start initially dirty */
    NineVolumeTexture9_AddDirtyBox(This, NULL);

    return D3D_OK;
}
Ejemplo n.º 28
0
void r300_texture_setup_format_state(struct r300_screen *screen,
                                     struct r300_resource *tex,
                                     enum pipe_format format,
                                     unsigned level,
                                     unsigned width0_override,
                                     unsigned height0_override,
                                     struct r300_texture_format_state *out)
{
    struct pipe_resource *pt = &tex->b.b;
    struct r300_texture_desc *desc = &tex->tex;
    boolean is_r500 = screen->caps.is_r500;
    unsigned width, height, depth;
    unsigned txwidth, txheight, txdepth;

    width = u_minify(width0_override, level);
    height = u_minify(height0_override, level);
    depth = u_minify(desc->depth0, level);

    txwidth = (width - 1) & 0x7ff;
    txheight = (height - 1) & 0x7ff;
    txdepth = util_logbase2(depth) & 0xf;

    /* Mask out all the fields we change. */
    out->format0 = 0;
    out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
    out->format2 &= R500_TXFORMAT_MSB;
    out->tile_config = 0;

    /* Set sampler state. */
    out->format0 =
        R300_TX_WIDTH(txwidth) |
        R300_TX_HEIGHT(txheight) |
        R300_TX_DEPTH(txdepth);

    if (desc->uses_stride_addressing) {
        unsigned stride =
            r300_stride_to_width(format, desc->stride_in_bytes[level]);
        /* rectangles love this */
        out->format0 |= R300_TX_PITCH_EN;
        out->format2 = (stride - 1) & 0x1fff;
    }

    if (pt->target == PIPE_TEXTURE_CUBE) {
        out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
    }
    if (pt->target == PIPE_TEXTURE_3D) {
        out->format1 |= R300_TX_FORMAT_3D;
    }

    /* large textures on r500 */
    if (is_r500)
    {
        unsigned us_width = txwidth;
        unsigned us_height = txheight;
        unsigned us_depth = txdepth;

        if (width > 2048) {
            out->format2 |= R500_TXWIDTH_BIT11;
        }
        if (height > 2048) {
            out->format2 |= R500_TXHEIGHT_BIT11;
        }

        /* The US_FORMAT register fixes an R500 TX addressing bug.
         * Don't ask why it must be set like this. I don't know it either. */
        if (width > 2048) {
            us_width = (0x000007FF + us_width) >> 1;
            us_depth |= 0x0000000D;
        }
        if (height > 2048) {
            us_height = (0x000007FF + us_height) >> 1;
            us_depth |= 0x0000000E;
        }
Ejemplo n.º 29
0
static HRESULT
NineTexture9_ctor( struct NineTexture9 *This,
                   struct NineUnknownParams *pParams,
                   UINT Width, UINT Height, UINT Levels,
                   DWORD Usage,
                   D3DFORMAT Format,
                   D3DPOOL Pool,
                   HANDLE *pSharedHandle )
{
    struct pipe_screen *screen = pParams->device->screen;
    struct pipe_resource *info = &This->base.base.info;
    enum pipe_format pf;
    unsigned *level_offsets;
    unsigned l;
    D3DSURFACE_DESC sfdesc;
    HRESULT hr;
    void *user_buffer = NULL, *user_buffer_for_level;

    DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
        "pSharedHandle=%p\n", This, Width, Height, Levels,
        nine_D3DUSAGE_to_str(Usage),
        d3dformat_to_string(Format), nine_D3DPOOL_to_str(Pool), pSharedHandle);

    user_assert(Width && Height, D3DERR_INVALIDCALL);

    /* pSharedHandle: can be non-null for ex only.
     * D3DPOOL_SYSTEMMEM: Levels must be 1
     * D3DPOOL_DEFAULT: no restriction for Levels
     * Other Pools are forbidden. */
    user_assert(!pSharedHandle || pParams->device->ex, D3DERR_INVALIDCALL);
    user_assert(!pSharedHandle ||
                (Pool == D3DPOOL_SYSTEMMEM && Levels == 1) ||
                Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);

    user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||
                (Pool != D3DPOOL_SYSTEMMEM && Pool != D3DPOOL_SCRATCH && Levels <= 1),
                D3DERR_INVALIDCALL);

    /* TODO: implement pSharedHandle for D3DPOOL_DEFAULT (cross process
     * buffer sharing).
     *
     * Gem names may have fit but they're depreciated and won't work on render-nodes.
     * One solution is to use shm buffers. We would use a /dev/shm file, fill the first
     * values to tell it is a nine buffer, the size, which function created it, etc,
     * and then it would contain the data. The handle would be a number, corresponding to
     * the file to read (/dev/shm/nine-share-4 for example would be 4).
     *
     * Wine just ignores the argument, which works only if the app creates the handle
     * and won't use it. Instead of failing, we support that situation by putting an
     * invalid handle, that we would fail to import. Please note that we don't advertise
     * the flag indicating the support for that feature, but apps seem to not care.
     */

    if (pSharedHandle && Pool == D3DPOOL_DEFAULT) {
        if (!*pSharedHandle) {
            DBG("Creating Texture with invalid handle. Importing will fail\n.");
            *pSharedHandle = (HANDLE)1; /* Wine would keep it NULL */
            pSharedHandle = NULL;
        } else {
            ERR("Application tries to use cross-process sharing feature. Nine "
                "doesn't support it");
            return D3DERR_INVALIDCALL;
        }
    }

    if (Usage & D3DUSAGE_AUTOGENMIPMAP)
        Levels = 0;

    pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_2D, 0,
                                     PIPE_BIND_SAMPLER_VIEW, FALSE,
                                     Pool == D3DPOOL_SCRATCH);

    if (Format != D3DFMT_NULL && pf == PIPE_FORMAT_NONE)
        return D3DERR_INVALIDCALL;

    if (compressed_format(Format)) {
        const unsigned w = util_format_get_blockwidth(pf);
        const unsigned h = util_format_get_blockheight(pf);

        user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
    }

    info->screen = screen;
    info->target = PIPE_TEXTURE_2D;
    info->format = pf;
    info->width0 = Width;
    info->height0 = Height;
    info->depth0 = 1;
    if (Levels)
        info->last_level = Levels - 1;
    else
        info->last_level = util_logbase2(MAX2(Width, Height));
    info->array_size = 1;
    info->nr_samples = 0;
    info->nr_storage_samples = 0;
    info->bind = PIPE_BIND_SAMPLER_VIEW;
    info->usage = PIPE_USAGE_DEFAULT;
    info->flags = 0;

    if (Usage & D3DUSAGE_RENDERTARGET)
        info->bind |= PIPE_BIND_RENDER_TARGET;
    if (Usage & D3DUSAGE_DEPTHSTENCIL)
        info->bind |= PIPE_BIND_DEPTH_STENCIL;

    if (Usage & D3DUSAGE_DYNAMIC) {
        info->usage = PIPE_USAGE_DYNAMIC;
    }

    if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
        DBG("Application asked for Software Vertex Processing, "
            "but this is unimplemented\n");

    if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */
        user_buffer = (void *)*pSharedHandle;
        level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
        (void) nine_format_get_size_and_offsets(pf, level_offsets,
                                                Width, Height,
                                                info->last_level);
    } else if (Pool != D3DPOOL_DEFAULT) {
        /* TODO: For D3DUSAGE_AUTOGENMIPMAP, it is likely we only have to
         * allocate only for the first level, since it is the only lockable
         * level. Check apps don't crash if we allocate smaller buffer (some
         * apps access sublevels of texture even if they locked only first
         * level) */
        level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
        user_buffer = align_calloc(
            nine_format_get_size_and_offsets(pf, level_offsets,
                                             Width, Height,
                                             info->last_level), 32);
        This->managed_buffer = user_buffer;
        if (!This->managed_buffer)
            return E_OUTOFMEMORY;
    }

    This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces));
    if (!This->surfaces)
        return E_OUTOFMEMORY;

    hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage);
    if (FAILED(hr))
        return hr;
    This->base.pstype = (Height == 1) ? 1 : 0;

    /* Create all the surfaces right away.
     * They manage backing storage, and transfers (LockRect) are deferred
     * to them.
     */
    sfdesc.Format = Format;
    sfdesc.Type = D3DRTYPE_SURFACE;
    sfdesc.Usage = Usage;
    sfdesc.Pool = Pool;
    sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE;
    sfdesc.MultiSampleQuality = 0;

    for (l = 0; l <= info->last_level; ++l) {
        sfdesc.Width = u_minify(Width, l);
        sfdesc.Height = u_minify(Height, l);
        /* Some apps expect the memory to be allocated in
         * continous blocks */
        user_buffer_for_level = user_buffer ? user_buffer +
            level_offsets[l] : NULL;

        hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
                              This->base.base.resource, user_buffer_for_level,
                              D3DRTYPE_TEXTURE, l, 0,
                              &sfdesc, &This->surfaces[l]);
        if (FAILED(hr))
            return hr;
    }

    /* Textures start initially dirty */
    This->dirty_rect.width = Width;
    This->dirty_rect.height = Height;
    This->dirty_rect.depth = 1; /* widht == 0 means empty, depth stays 1 */

    if (pSharedHandle && !*pSharedHandle) {/* Pool == D3DPOOL_SYSTEMMEM */
        *pSharedHandle = This->surfaces[0]->data;
    }

    return D3D_OK;
}
Ejemplo n.º 30
0
static void
nv50_screen_init_hwctx(struct nv50_screen *screen)
{
   struct nouveau_pushbuf *push = screen->base.pushbuf;
   struct nv04_fifo *fifo;
   unsigned i;

   fifo = (struct nv04_fifo *)screen->base.channel->data;

   BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
   PUSH_DATA (push, screen->m2mf->handle);
   BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
   PUSH_DATA (push, screen->sync->handle);
   PUSH_DATA (push, fifo->vram);
   PUSH_DATA (push, fifo->vram);

   BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
   PUSH_DATA (push, screen->eng2d->handle);
   BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
   PUSH_DATA (push, screen->sync->handle);
   PUSH_DATA (push, fifo->vram);
   PUSH_DATA (push, fifo->vram);
   PUSH_DATA (push, fifo->vram);
   BEGIN_NV04(push, NV50_2D(OPERATION), 1);
   PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
   BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, SUBC_2D(0x0888), 1);
   PUSH_DATA (push, 1);

   BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
   PUSH_DATA (push, screen->tesla->handle);

   BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
   PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);

   BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
   PUSH_DATA (push, screen->sync->handle);
   BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
   for (i = 0; i < 11; ++i)
      PUSH_DATA(push, fifo->vram);
   BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
   for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
      PUSH_DATA(push, fifo->vram);

   BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
   PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
   BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
   PUSH_DATA (push, 0xf);

   if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
      BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1);
      PUSH_DATA (push, 0x18);
   }

   BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
   PUSH_DATA (push, 1);

   BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
   PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
   PUSH_DATA (push, 1);

   if (screen->tesla->oclass >= NVA0_3D_CLASS) {
      BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
      PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
   }

   BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
   PUSH_DATA (push, 0);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
   PUSH_DATA (push, 0x3f);

   BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
   PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
   PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));

   BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
   PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
   PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));

   BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
   PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
   PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));

   BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->tls_bo->offset);
   PUSH_DATA (push, screen->tls_bo->offset);
   PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8));

   BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->stack_bo->offset);
   PUSH_DATA (push, screen->stack_bo->offset);
   PUSH_DATA (push, 4);

   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
   PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
   PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);

   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
   PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
   PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);

   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
   PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
   PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);

   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
   PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
   PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);

   BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3);
   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);

   /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */
   BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
   PUSH_DATA (push, ((1 << 9) << 6) | NV50_CB_AUX);
   BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4);
   PUSH_DATAf(push, 0.0f);
   PUSH_DATAf(push, 0.0f);
   PUSH_DATAf(push, 0.0f);
   PUSH_DATAf(push, 0.0f);
   BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
   PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + (1 << 9));
   PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + (1 << 9));

   /* max TIC (bits 4:8) & TSC bindings, per program type */
   for (i = 0; i < 3; ++i) {
      BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
      PUSH_DATA (push, 0x54);
   }

   BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->txc->offset);
   PUSH_DATA (push, screen->txc->offset);
   PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);

   BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
   PUSH_DATAh(push, screen->txc->offset + 65536);
   PUSH_DATA (push, screen->txc->offset + 65536);
   PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);

   BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
   PUSH_DATA (push, 0);

   BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
   PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
   BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
   for (i = 0; i < 8 * 2; ++i)
      PUSH_DATA(push, 0);
   BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
   PUSH_DATA (push, 0);

   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
   PUSH_DATAf(push, 0.0f);
   PUSH_DATAf(push, 1.0f);

   BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
#ifdef NV50_SCISSORS_CLIPPING
   PUSH_DATA (push, 0x0000);
#else
   PUSH_DATA (push, 0x1080);
#endif

   BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
   PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);

   /* We use scissors instead of exact view volume clipping,
    * so they're always enabled.
    */
   BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3);
   PUSH_DATA (push, 1);
   PUSH_DATA (push, 8192 << 16);
   PUSH_DATA (push, 8192 << 16);

   BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
   PUSH_DATA (push, 1);
   BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
   PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
   BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
   PUSH_DATA (push, 0x11111111);
   BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
   PUSH_DATA (push, 1);

   PUSH_KICK (push);
}