#include "lima_screen.h"
#include "lima_texture.h"
#include "lima_resource.h"
-#include "lima_submit.h"
+#include "lima_job.h"
#include "lima_util.h"
+#include "lima_format.h"
#include <drm-uapi/lima_drm.h>
-#define LIMA_TEXEL_FORMAT_L8 0x09
-#define LIMA_TEXEL_FORMAT_A8 0x0a
-#define LIMA_TEXEL_FORMAT_I8 0x0b
-#define LIMA_TEXEL_FORMAT_BGR_565 0x0e
-#define LIMA_TEXEL_FORMAT_L8A8 0x11
-#define LIMA_TEXEL_FORMAT_L16 0x12
-#define LIMA_TEXEL_FORMAT_A16 0x13
-#define LIMA_TEXEL_FORMAT_I16 0x14
-#define LIMA_TEXEL_FORMAT_RGB_888 0x15
-#define LIMA_TEXEL_FORMAT_RGBA_8888 0x16
-#define LIMA_TEXEL_FORMAT_RGBX_8888 0x17
-#define LIMA_TEXEL_FORMAT_Z24S8 0x2c
#define lima_tex_list_size 64
-typedef struct {
- bool present;
- uint32_t lima_format;
- bool swap_r_b;
-} lima_format;
-
-#define LIMA_FORMAT(pipe, lima, swap) \
- [PIPE_FORMAT_##pipe] = { .present = true, .lima_format = lima, \
- .swap_r_b = swap }
-
-static const lima_format lima_format_table[] = {
- LIMA_FORMAT(R8G8B8A8_UNORM, LIMA_TEXEL_FORMAT_RGBA_8888, true),
- LIMA_FORMAT(B8G8R8A8_UNORM, LIMA_TEXEL_FORMAT_RGBA_8888, false),
- LIMA_FORMAT(R8G8B8A8_SRGB, LIMA_TEXEL_FORMAT_RGBA_8888, true),
- LIMA_FORMAT(B8G8R8A8_SRGB, LIMA_TEXEL_FORMAT_RGBA_8888, false),
- LIMA_FORMAT(R8G8B8X8_UNORM, LIMA_TEXEL_FORMAT_RGBX_8888, true),
- LIMA_FORMAT(B8G8R8X8_UNORM, LIMA_TEXEL_FORMAT_RGBX_8888, false),
- LIMA_FORMAT(R8G8B8_UNORM, LIMA_TEXEL_FORMAT_RGB_888, true),
- LIMA_FORMAT(B5G6R5_UNORM, LIMA_TEXEL_FORMAT_BGR_565, false),
- LIMA_FORMAT(Z24_UNORM_S8_UINT, LIMA_TEXEL_FORMAT_Z24S8, false),
- LIMA_FORMAT(Z24X8_UNORM, LIMA_TEXEL_FORMAT_Z24S8, false),
- /* Blob uses L16 for Z16 */
- LIMA_FORMAT(Z16_UNORM, LIMA_TEXEL_FORMAT_L16, false),
- LIMA_FORMAT(L16_UNORM, LIMA_TEXEL_FORMAT_L16, false),
- LIMA_FORMAT(L8_UNORM, LIMA_TEXEL_FORMAT_L8, false),
- LIMA_FORMAT(A16_UNORM, LIMA_TEXEL_FORMAT_A16, false),
- LIMA_FORMAT(A8_UNORM, LIMA_TEXEL_FORMAT_A8, false),
- LIMA_FORMAT(I16_UNORM, LIMA_TEXEL_FORMAT_I16, false),
- LIMA_FORMAT(I8_UNORM, LIMA_TEXEL_FORMAT_I8, false),
- LIMA_FORMAT(L8A8_UNORM, LIMA_TEXEL_FORMAT_L8A8, false),
-};
-
static_assert(offsetof(lima_tex_desc, va) == 24, "lima_tex_desc->va offset isn't 24");
-bool
-lima_texel_format_supported(enum pipe_format pformat)
-{
- if (pformat >= ARRAY_SIZE(lima_format_table))
- return false;
-
- return lima_format_table[pformat].present;
-}
static void
lima_texture_desc_set_va(lima_tex_desc *desc,
desc->va[va_idx + 1] |= va >> (32 - va_bit_idx);
}
+/*
+ * Note: this function is used by both draw and flush code path,
+ * make sure no lima_job_get() is called inside this.
+ */
void
lima_texture_desc_set_res(struct lima_context *ctx, lima_tex_desc *desc,
struct pipe_resource *prsc,
height = u_minify(height, first_level);
}
- assert(prsc->format < ARRAY_SIZE(lima_format_table));
- assert(lima_format_table[prsc->format].present);
-
- desc->format = lima_format_table[prsc->format].lima_format;
- desc->swap_r_b = lima_format_table[prsc->format].swap_r_b;
+ desc->format = lima_format_get_texel(prsc->format);
+ desc->swap_r_b = lima_format_get_texel_swap_rb(prsc->format);
desc->width = width;
desc->height = height;
desc->unknown_3_1 = 1;
else {
/* for padded linear texture */
if (lima_res->levels[first_level].width != width) {
- desc->stride = lima_res->levels[first_level].width;
+ desc->stride = lima_res->levels[first_level].stride;
desc->has_stride = 1;
}
layout = 0;
}
- lima_submit_add_bo(ctx->pp_submit, lima_res->bo, LIMA_SUBMIT_BO_READ);
-
uint32_t base_va = lima_res->bo->va;
/* attach first level */
struct lima_sampler_view *texture, void *pdesc,
unsigned desc_size)
{
+ /* unit is 1/16 since lod_bias is in fixed format */
+ int lod_bias_delta = 0;
lima_tex_desc *desc = pdesc;
unsigned first_level;
unsigned last_level;
- bool mipmapping;
+ float max_lod;
memset(desc, 0, desc_size);
- /* 2D texture */
- desc->texture_2d = 1;
+ switch (texture->base.target) {
+ case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_RECT:
+ desc->texture_type = LIMA_TEXTURE_TYPE_2D;
+ break;
+ case PIPE_TEXTURE_CUBE:
+ desc->texture_type = LIMA_TEXTURE_TYPE_CUBE;
+ break;
+ default:
+ break;
+ }
+
+ if (!sampler->base.normalized_coords)
+ desc->unnorm_coords = 1;
first_level = texture->base.u.tex.first_level;
last_level = texture->base.u.tex.last_level;
if (last_level - first_level >= LIMA_MAX_MIP_LEVELS)
last_level = first_level + LIMA_MAX_MIP_LEVELS - 1;
+ desc->min_lod = lima_float_to_fixed8(sampler->base.min_lod);
+ max_lod = MIN2(sampler->base.max_lod, sampler->base.min_lod +
+ (last_level - first_level));
+ desc->max_lod = lima_float_to_fixed8(max_lod);
+ desc->lod_bias = lima_float_to_fixed8(sampler->base.lod_bias);
+
switch (sampler->base.min_mip_filter) {
case PIPE_TEX_MIPFILTER_LINEAR:
- desc->min_mipfilter = 3;
+ desc->min_mipfilter_2 = 3;
+ break;
case PIPE_TEX_MIPFILTER_NEAREST:
- mipmapping = true;
- desc->miplevels = (last_level - first_level);
+ desc->min_mipfilter_2 = 0;
break;
case PIPE_TEX_MIPFILTER_NONE:
+ desc->max_lod = desc->min_lod;
+ break;
default:
- mipmapping = false;
break;
}
switch (sampler->base.mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
desc->mag_img_filter_nearest = 0;
- /* no mipmap, filter_mag = linear */
- if (!mipmapping)
- desc->disable_mipmap = 1;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
break;
case PIPE_TEX_FILTER_NEAREST:
default:
+ lod_bias_delta = 8;
desc->min_img_filter_nearest = 1;
break;
}
break;
}
+ if (desc->min_img_filter_nearest && desc->mag_img_filter_nearest &&
+ desc->min_mipfilter_2 == 0 &&
+ (desc->min_lod != desc->max_lod))
+ lod_bias_delta = -1;
+
+ desc->lod_bias += lod_bias_delta;
+
lima_texture_desc_set_res(ctx, desc, texture->base.texture,
first_level, last_level);
}
void
lima_update_textures(struct lima_context *ctx)
{
+ struct lima_job *job = lima_job_get(ctx);
struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj;
assert (lima_tex->num_samplers <= 16);
if (!lima_tex->num_samplers || !lima_tex->num_textures)
return;
+ /* we always need to add texture bo to job */
+ for (int i = 0; i < lima_tex->num_samplers; i++) {
+ struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]);
+ struct lima_resource *rsc = lima_resource(texture->base.texture);
+ lima_flush_previous_job_writing_resource(ctx, texture->base.texture);
+ lima_job_add_bo(job, LIMA_PIPE_PP, rsc->bo, LIMA_SUBMIT_BO_READ);
+ }
+
+ /* do not regenerate texture desc if no change */
+ if (!(ctx->dirty & LIMA_CONTEXT_DIRTY_TEXTURES))
+ return;
+
unsigned size = lima_tex_list_size;
for (int i = 0; i < lima_tex->num_samplers; i++) {
struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]);
}
uint32_t *descs =
- lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_tex_desc, size, true);
+ lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_tex_desc, size);
off_t offset = lima_tex_list_size;
for (int i = 0; i < lima_tex->num_samplers; i++) {
struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]);
unsigned desc_size = lima_calc_tex_desc_size(texture);
- descs[i] = lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc,
- LIMA_CTX_BUFF_SUBMIT_PP) + offset;
+ descs[i] = lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc) + offset;
lima_update_tex_desc(ctx, sampler, texture, (void *)descs + offset, desc_size);
offset += desc_size;
}
lima_dump_command_stream_print(
- descs, size, false, "add textures_desc at va %x\n",
- lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc, 0));
+ job->dump, descs, size, false, "add textures_desc at va %x\n",
+ lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc));
+
+ lima_dump_texture_descriptor(
+ job->dump, descs, size,
+ lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc) + lima_tex_list_size,
+ lima_tex_list_size);
}