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; }
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); }
/* 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; }
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; }
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); } }
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; }
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; } }
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); }
/** * 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; }
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; }
/** * 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; }
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"); } }
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); }
/** * 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; }
/** * 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; }
/** * 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; }
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; }
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; }
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; }
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; }
/* * 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), ""); }
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; }
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); }
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; }
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; }
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; }
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; }
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); }