static void i915_texture_layout_2d(struct i915_texture *tex) { struct pipe_resource *pt = &tex->b.b; unsigned level; unsigned width = util_next_power_of_two(pt->width0); unsigned height = util_next_power_of_two(pt->height0); unsigned nblocksy = util_format_get_nblocksy(pt->format, width); unsigned align_y = 2; if (util_format_is_s3tc(pt->format)) align_y = 1; tex->stride = align(util_format_get_stride(pt->format, width), 4); tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { i915_texture_set_level_info(tex, level, 1); i915_texture_set_image_offset(tex, level, 0, 0, tex->total_nblocksy); tex->total_nblocksy += nblocksy; width = u_minify(width, 1); height = u_minify(height, 1); nblocksy = align_nblocksy(pt->format, height, align_y); } }
static void nvfx_miptree_choose_format(struct nvfx_miptree *mt) { struct pipe_resource *pt = &mt->base.base; unsigned uniform_pitch = 0; static int no_swizzle = -1; if(no_swizzle < 0) no_swizzle = debug_get_bool_option("NV40_NO_SWIZZLE", FALSE); /* this will break things on nv30 */ if (!util_is_power_of_two(pt->width0) || !util_is_power_of_two(pt->height0) || !util_is_power_of_two(pt->depth0) || (!nvfx_screen(pt->screen)->is_nv4x && pt->target == PIPE_TEXTURE_RECT) ) uniform_pitch = 1; if ( (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET)) || (pt->usage & PIPE_USAGE_DYNAMIC) || (pt->usage & PIPE_USAGE_STAGING) || util_format_is_compressed(pt->format) || no_swizzle ) mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; /* non compressed formats with uniform pitch must be linear, and vice versa */ if(!util_format_is_s3tc(pt->format) && (uniform_pitch || mt->base.base.flags & NVFX_RESOURCE_FLAG_LINEAR)) { mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; uniform_pitch = 1; } if(uniform_pitch) { mt->linear_pitch = util_format_get_stride(pt->format, pt->width0); // TODO: this is only a constraint for rendering and not sampling, apparently // we may also want this unconditionally if(pt->bind & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT)) mt->linear_pitch = align(mt->linear_pitch, 64); } else mt->linear_pitch = 0; }
static enum i915_winsys_buffer_tile i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex) { if (!is->debug.tiling) return I915_TILE_NONE; if (tex->b.b.target == PIPE_TEXTURE_1D) return I915_TILE_NONE; if (util_format_is_s3tc(tex->b.b.format)) return I915_TILE_X; if (is->debug.use_blitter) return I915_TILE_X; else return I915_TILE_Y; }
boolean util_format_is_supported(enum pipe_format format, unsigned bind) { if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) { return FALSE; } #ifndef TEXTURE_FLOAT_ENABLED if ((bind & PIPE_BIND_RENDER_TARGET) && format != PIPE_FORMAT_R9G9B9E5_FLOAT && format != PIPE_FORMAT_R11G11B10_FLOAT && util_format_is_float(format)) { return FALSE; } #endif return TRUE; }
/** * Called via ctx->Driver.GetTexImage() */ static void st_GetTexImage(struct gl_context * ctx, GLenum format, GLenum type, GLvoid * pixels, struct gl_texture_image *texImage) { struct st_texture_image *stImage = st_texture_image(texImage); if (stImage->pt && util_format_is_s3tc(stImage->pt->format)) { /* Need to decompress the texture. * We'll do this by rendering a textured quad (which is hopefully * faster than using the fallback code in texcompress.c). * Note that we only expect RGBA formats (no Z/depth formats). */ decompress_with_blit(ctx, format, type, pixels, texImage); } else { _mesa_get_teximage(ctx, format, type, pixels, texImage); } }
static void i945_texture_layout_2d(struct i915_texture *tex) { struct pipe_resource *pt = &tex->b.b; int align_x = 4, align_y = 2; unsigned level; unsigned x = 0; unsigned y = 0; unsigned width = util_next_power_of_two(pt->width0); unsigned height = util_next_power_of_two(pt->height0); unsigned nblocksx = util_format_get_nblocksx(pt->format, width); unsigned nblocksy = util_format_get_nblocksy(pt->format, height); if (util_format_is_s3tc(pt->format)) { align_x = 1; align_y = 1; } tex->stride = align(util_format_get_stride(pt->format, width), 4); /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap level. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap level out past the width of its parent. */ if (pt->last_level > 0) { unsigned mip1_nblocksx = align_nblocksx(pt->format, u_minify(width, 1), align_x) + util_format_get_nblocksx(pt->format, u_minify(width, 2)); if (mip1_nblocksx > nblocksx) tex->stride = mip1_nblocksx * util_format_get_blocksize(pt->format); } /* Pitch must be a whole number of dwords */ tex->stride = align(tex->stride, 64); tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { i915_texture_set_level_info(tex, level, 1); i915_texture_set_image_offset(tex, level, 0, x, y); /* Because the images are packed better, the final offset * might not be the maximal one: */ tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy); /* Layout_below: step right after second mipmap level. */ if (level == 1) { x += nblocksx; } else { y += nblocksy; } width = u_minify(width, 1); height = u_minify(height, 1); nblocksx = align_nblocksx(pt->format, width, align_x); nblocksy = align_nblocksy(pt->format, height, align_y); } }
static boolean nvfx_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned bind, unsigned geom_flags) { struct nvfx_screen *screen = nvfx_screen(pscreen); if (sample_count > 1) return FALSE; if (bind & PIPE_BIND_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B5G6R5_UNORM: break; case PIPE_FORMAT_R16G16B16A16_FLOAT: if(!screen->advertise_fp16) return FALSE; break; case PIPE_FORMAT_R32G32B32A32_FLOAT: if(!screen->advertise_fp32) return FALSE; break; default: return FALSE; } } if (bind & PIPE_BIND_DEPTH_STENCIL) { switch (format) { case PIPE_FORMAT_S8_USCALED_Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_Z16_UNORM: break; default: return FALSE; } } if (bind & PIPE_BIND_SAMPLER_VIEW) { struct nvfx_texture_format* tf = &nvfx_texture_formats[format]; if(util_format_is_s3tc(format) && !util_format_s3tc_enabled) return FALSE; if(format == PIPE_FORMAT_R16G16B16A16_FLOAT && !screen->advertise_fp16) return FALSE; if(format == PIPE_FORMAT_R32G32B32A32_FLOAT && !screen->advertise_fp32) return FALSE; if(screen->use_nv4x) { if(tf->fmt[4] < 0) return FALSE; } else { if(tf->fmt[0] < 0) return FALSE; } } // note that we do actually support everything through translate if (bind & PIPE_BIND_VERTEX_BUFFER) { unsigned type = nvfx_vertex_formats[format]; if(!type) return FALSE; } if (bind & PIPE_BIND_INDEX_BUFFER) { // 8-bit indices supported, but not in hardware index buffer if(format != PIPE_FORMAT_R16_USCALED && format != PIPE_FORMAT_R32_USCALED) return FALSE; } if(bind & PIPE_BIND_STREAM_OUTPUT) return FALSE; return TRUE; }