diff options
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 52 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_resource.c | 25 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_resource.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_simulator_validate.c | 25 |
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; } |