summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c52
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h3
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c25
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.h1
-rw-r--r--src/gallium/drivers/vc4/vc4_simulator_validate.c25
5 files changed, 84 insertions, 22 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index a5011039be2..4c97ddfd26f 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -489,6 +489,7 @@ tgsi_to_qir_tex(struct vc4_compile *c,
struct qreg s = src[0 * 4 + 0];
struct qreg t = src[0 * 4 + 1];
+ struct qreg r = src[0 * 4 + 2];
uint32_t unit = tgsi_inst->Src[1].Register.Index;
struct qreg proj = c->undef;
@@ -498,6 +499,14 @@ tgsi_to_qir_tex(struct vc4_compile *c,
t = qir_FMUL(c, t, proj);
}
+ struct qreg texture_u[] = {
+ add_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0, unit),
+ add_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1, unit),
+ add_uniform(c, QUNIFORM_CONSTANT, 0),
+ add_uniform(c, QUNIFORM_CONSTANT, 0),
+ };
+ uint32_t next_texture_u = 0;
+
/* There is no native support for GL texture rectangle coordinates, so
* we have to rescale from ([0, width], [0, height]) to ([0, 1], [0,
* 1]).
@@ -512,19 +521,26 @@ tgsi_to_qir_tex(struct vc4_compile *c,
get_temp_for_uniform(c,
QUNIFORM_TEXRECT_SCALE_Y,
unit));
- }
+ } else if (tgsi_inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) {
+ struct qreg ma = qir_FMAXABS(c, qir_FMAXABS(c, s, t), r);
+ struct qreg rcp_ma = qir_RCP(c, ma);
+ s = qir_FMUL(c, s, rcp_ma);
+ t = qir_FMUL(c, t, rcp_ma);
+ r = qir_FMUL(c, r, rcp_ma);
- qir_TEX_T(c, t, add_uniform(c, QUNIFORM_TEXTURE_CONFIG_P0, unit));
+ texture_u[2] = add_uniform(c, QUNIFORM_TEXTURE_CONFIG_P2, unit);
- struct qreg sampler_p1 = add_uniform(c, QUNIFORM_TEXTURE_CONFIG_P1,
- unit);
- if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXB) {
- qir_TEX_B(c, src[0 * 4 + 3], sampler_p1);
- qir_TEX_S(c, s, add_uniform(c, QUNIFORM_CONSTANT, 0));
- } else {
- qir_TEX_S(c, s, sampler_p1);
+ qir_TEX_R(c, r, texture_u[next_texture_u++]);
}
+ qir_TEX_T(c, t, texture_u[next_texture_u++]);
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXB)
+ qir_TEX_B(c, src[0 * 4 + 3], texture_u[next_texture_u++]);
+
+ qir_TEX_S(c, s, texture_u[next_texture_u++]);
+
c->num_texture_samples++;
struct qreg r4 = qir_TEX_RESULT(c);
@@ -1890,8 +1906,11 @@ write_texture_p0(struct vc4_context *vc4,
struct pipe_sampler_view *texture = texstate->textures[unit];
struct vc4_resource *rsc = vc4_resource(texture->texture);
+ bool is_cube = texture->target == PIPE_TEXTURE_CUBE;
+
cl_reloc(vc4, &vc4->uniforms, rsc->bo,
rsc->slices[0].offset | texture->u.tex.last_level |
+ is_cube << 9 |
((rsc->vc4_format & 7) << 4));
}
@@ -1924,6 +1943,17 @@ write_texture_p1(struct vc4_context *vc4,
(translate_wrap(sampler->wrap_s) << 0));
}
+static void
+write_texture_p2(struct vc4_context *vc4,
+ struct vc4_texture_stateobj *texstate,
+ uint32_t unit)
+{
+ struct pipe_sampler_view *texture = texstate->textures[unit];
+ struct vc4_resource *rsc = vc4_resource(texture->texture);
+
+ cl_u32(&vc4->uniforms, (1 << 30) | rsc->cube_map_stride);
+}
+
static uint32_t
get_texrect_scale(struct vc4_texture_stateobj *texstate,
enum quniform_contents contents,
@@ -1983,6 +2013,10 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
write_texture_p1(vc4, texstate, uinfo->data[i]);
break;
+ case QUNIFORM_TEXTURE_CONFIG_P2:
+ write_texture_p2(vc4, texstate, uinfo->data[i]);
+ break;
+
case QUNIFORM_TEXRECT_SCALE_X:
case QUNIFORM_TEXRECT_SCALE_Y:
cl_u32(&vc4->uniforms,
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index f771c425415..0d490ff9ef5 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -201,6 +201,9 @@ enum quniform_contents {
*/
QUNIFORM_TEXTURE_CONFIG_P1,
+ /** A reference to a texture config parameter 2 cubemap stride uniform */
+ QUNIFORM_TEXTURE_CONFIG_P2,
+
QUNIFORM_TEXRECT_SCALE_X,
QUNIFORM_TEXRECT_SCALE_Y,
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index 3fb0b99b7d5..239443e7a7d 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -45,7 +45,8 @@ vc4_resource_transfer_unmap(struct pipe_context *pctx,
if (trans->map) {
if (ptrans->usage & PIPE_TRANSFER_WRITE) {
- vc4_store_tiled_image(rsc->bo->map + slice->offset,
+ vc4_store_tiled_image(rsc->bo->map + slice->offset +
+ ptrans->box.z * rsc->cube_map_stride,
slice->stride,
trans->map, ptrans->stride,
slice->tiling, rsc->cpp,
@@ -137,7 +138,8 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
trans->map = malloc(ptrans->stride * ptrans->box.height);
if (usage & PIPE_TRANSFER_READ) {
vc4_load_tiled_image(trans->map, ptrans->stride,
- buf + slice->offset,
+ buf + slice->offset +
+ box->z * rsc->cube_map_stride,
slice->stride,
slice->tiling, rsc->cpp,
&ptrans->box);
@@ -152,7 +154,7 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
return buf + slice->offset +
box->y / util_format_get_blockheight(format) * ptrans->stride +
box->x / util_format_get_blockwidth(format) * rsc->cpp +
- box->z * slice->size;
+ box->z * rsc->cube_map_stride;
}
@@ -196,7 +198,6 @@ vc4_setup_slices(struct vc4_resource *rsc)
struct pipe_resource *prsc = &rsc->base.b;
uint32_t width = prsc->width0;
uint32_t height = prsc->height0;
- uint32_t depth = prsc->depth0;
uint32_t offset = 0;
uint32_t utile_w = vc4_utile_width(rsc->cpp);
uint32_t utile_h = vc4_utile_height(rsc->cpp);
@@ -228,10 +229,7 @@ vc4_setup_slices(struct vc4_resource *rsc)
slice->stride = level_width * rsc->cpp;
slice->size = level_height * slice->stride;
- /* Note, since we have cubes but no 3D, depth is invariant
- * with miplevel.
- */
- offset += slice->size * depth;
+ offset += slice->size;
}
/* The texture base pointer that has to point to level 0 doesn't have
@@ -244,6 +242,14 @@ vc4_setup_slices(struct vc4_resource *rsc)
for (int i = 0; i <= prsc->last_level; i++)
rsc->slices[i].offset += page_align_offset;
}
+
+ /* Cube map faces appear as whole miptrees at a page-aligned offset
+ * from the first face's miptree.
+ */
+ if (prsc->target == PIPE_TEXTURE_CUBE) {
+ rsc->cube_map_stride = align(rsc->slices[0].offset +
+ rsc->slices[0].size, 4096);
+ }
}
static struct vc4_resource *
@@ -306,7 +312,8 @@ vc4_resource_create(struct pipe_screen *pscreen,
rsc->bo = vc4_bo_alloc(vc4_screen(pscreen),
rsc->slices[0].offset +
- rsc->slices[0].size * prsc->depth0,
+ rsc->slices[0].size +
+ rsc->cube_map_stride * (prsc->array_size - 1),
"resource");
if (!rsc->bo)
goto fail;
diff --git a/src/gallium/drivers/vc4/vc4_resource.h b/src/gallium/drivers/vc4/vc4_resource.h
index 78869295774..01f481d15c4 100644
--- a/src/gallium/drivers/vc4/vc4_resource.h
+++ b/src/gallium/drivers/vc4/vc4_resource.h
@@ -56,6 +56,7 @@ struct vc4_resource {
struct u_resource base;
struct vc4_bo *bo;
struct vc4_resource_slice slices[VC4_MAX_MIP_LEVELS];
+ uint32_t cube_map_stride;
int cpp;
bool tiled;
/** One of VC4_TEXTURE_TYPE_* */
diff --git a/src/gallium/drivers/vc4/vc4_simulator_validate.c b/src/gallium/drivers/vc4/vc4_simulator_validate.c
index 1b63bf334f2..99f01b238bd 100644
--- a/src/gallium/drivers/vc4/vc4_simulator_validate.c
+++ b/src/gallium/drivers/vc4/vc4_simulator_validate.c
@@ -751,6 +751,10 @@ reloc_tex(struct exec_info *exec,
struct drm_gem_cma_object *tex;
uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]);
uint32_t p1 = *(uint32_t *)(uniform_data_u + sample->p_offset[1]);
+ uint32_t p2 = (sample->p_offset[2] != ~0 ?
+ *(uint32_t *)(uniform_data_u + sample->p_offset[2]) : 0);
+ uint32_t p3 = (sample->p_offset[3] != ~0 ?
+ *(uint32_t *)(uniform_data_u + sample->p_offset[3]) : 0);
uint32_t *validated_p0 = exec->uniforms_v + sample->p_offset[0];
uint32_t offset = p0 & ~0xfff;
uint32_t miplevels = (p0 & 15);
@@ -758,6 +762,7 @@ reloc_tex(struct exec_info *exec,
uint32_t height = (p1 >> 20) & 2047;
uint32_t cpp, tiling_format, utile_w, utile_h;
uint32_t i;
+ uint32_t cube_map_stride = 0;
enum vc4_texture_data_type type;
if (width == 0)
@@ -766,8 +771,20 @@ reloc_tex(struct exec_info *exec,
height = 2048;
if (p0 & (1 << 9)) {
- DRM_ERROR("Cube maps unsupported\n");
- return false;
+ if ((p2 & (3 << 30)) == (1 << 30))
+ cube_map_stride = p2 & 0x3ffff000;
+ if ((p3 & (3 << 30)) == (1 << 30)) {
+ if (cube_map_stride) {
+ DRM_ERROR("Cube map stride set twice\n");
+ return -EINVAL;
+ }
+
+ cube_map_stride = p3 & 0x3ffff000;
+ }
+ if (!cube_map_stride) {
+ DRM_ERROR("Cube map stride not set\n");
+ return -EINVAL;
+ }
}
type = ((p0 >> 4) & 15) | ((p1 >> 31) << 4);
@@ -816,8 +833,8 @@ reloc_tex(struct exec_info *exec,
if (!vc4_use_bo(exec, texture_handle_index, VC4_MODE_RENDER, &tex))
return false;
- if (!check_tex_size(exec, tex, offset, tiling_format,
- width, height, cpp)) {
+ if (!check_tex_size(exec, tex, offset + cube_map_stride * 5,
+ tiling_format, width, height, cpp)) {
return false;
}