X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fvc4%2Fvc4_uniforms.c;h=dd07487ab16d7a6a5d4ab1d8900b3fef23442f32;hb=2e1df6a17ff82c4a456caa8be4bfae1fac009b6a;hp=e8fca3d0cbd303adebde9f97285621c77fb2328b;hpb=1835ce6e35e6a186c2ba1bdf39b73783a2cb2ad5;p=mesa.git diff --git a/src/gallium/drivers/vc4/vc4_uniforms.c b/src/gallium/drivers/vc4/vc4_uniforms.c index e8fca3d0cbd..dd07487ab16 100644 --- a/src/gallium/drivers/vc4/vc4_uniforms.c +++ b/src/gallium/drivers/vc4/vc4_uniforms.c @@ -22,94 +22,41 @@ */ #include "util/u_pack_color.h" +#include "util/u_upload_mgr.h" #include "util/format_srgb.h" #include "vc4_context.h" #include "vc4_qir.h" -static uint32_t translate_wrap(uint32_t p_wrap, bool using_nearest) -{ - switch (p_wrap) { - case PIPE_TEX_WRAP_REPEAT: - return 0; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - return 1; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - return 2; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return 3; - case PIPE_TEX_WRAP_CLAMP: - return (using_nearest ? 1 : 3); - default: - fprintf(stderr, "Unknown wrap mode %d\n", p_wrap); - assert(!"not reached"); - return 0; - } -} - static void -write_texture_p0(struct vc4_context *vc4, +write_texture_p0(struct vc4_job *job, struct vc4_cl_out **uniforms, struct vc4_texture_stateobj *texstate, uint32_t unit) { - struct pipe_sampler_view *texture = texstate->textures[unit]; - struct vc4_resource *rsc = vc4_resource(texture->texture); + struct vc4_sampler_view *sview = + vc4_sampler_view(texstate->textures[unit]); + struct vc4_resource *rsc = vc4_resource(sview->texture); - cl_reloc(vc4, &vc4->uniforms, uniforms, rsc->bo, - VC4_SET_FIELD(rsc->slices[0].offset >> 12, VC4_TEX_P0_OFFSET) | - VC4_SET_FIELD(texture->u.tex.last_level - - texture->u.tex.first_level, VC4_TEX_P0_MIPLVLS) | - VC4_SET_FIELD(texture->target == PIPE_TEXTURE_CUBE, - VC4_TEX_P0_CMMODE) | - VC4_SET_FIELD(rsc->vc4_format & 15, VC4_TEX_P0_TYPE)); + cl_reloc(job, &job->uniforms, uniforms, rsc->bo, sview->texture_p0); } static void -write_texture_p1(struct vc4_context *vc4, +write_texture_p1(struct vc4_job *job, struct vc4_cl_out **uniforms, struct vc4_texture_stateobj *texstate, uint32_t unit) { - struct pipe_sampler_view *texture = texstate->textures[unit]; - struct vc4_resource *rsc = vc4_resource(texture->texture); - struct pipe_sampler_state *sampler = texstate->samplers[unit]; - static const uint8_t minfilter_map[6] = { - VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR, - VC4_TEX_P1_MINFILT_LIN_MIP_NEAR, - VC4_TEX_P1_MINFILT_NEAR_MIP_LIN, - VC4_TEX_P1_MINFILT_LIN_MIP_LIN, - VC4_TEX_P1_MINFILT_NEAREST, - VC4_TEX_P1_MINFILT_LINEAR, - }; - static const uint32_t magfilter_map[] = { - [PIPE_TEX_FILTER_NEAREST] = VC4_TEX_P1_MAGFILT_NEAREST, - [PIPE_TEX_FILTER_LINEAR] = VC4_TEX_P1_MAGFILT_LINEAR, - }; - - bool either_nearest = - (sampler->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST || - sampler->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST); + struct vc4_sampler_view *sview = + vc4_sampler_view(texstate->textures[unit]); + struct vc4_sampler_state *sampler = + vc4_sampler_state(texstate->samplers[unit]); - cl_aligned_u32(uniforms, - VC4_SET_FIELD(rsc->vc4_format >> 4, VC4_TEX_P1_TYPE4) | - VC4_SET_FIELD(texture->texture->height0 & 2047, - VC4_TEX_P1_HEIGHT) | - VC4_SET_FIELD(texture->texture->width0 & 2047, - VC4_TEX_P1_WIDTH) | - VC4_SET_FIELD(magfilter_map[sampler->mag_img_filter], - VC4_TEX_P1_MAGFILT) | - VC4_SET_FIELD(minfilter_map[sampler->min_mip_filter * 2 + - sampler->min_img_filter], - VC4_TEX_P1_MINFILT) | - VC4_SET_FIELD(translate_wrap(sampler->wrap_s, either_nearest), - VC4_TEX_P1_WRAP_S) | - VC4_SET_FIELD(translate_wrap(sampler->wrap_t, either_nearest), - VC4_TEX_P1_WRAP_T)); + cl_aligned_u32(uniforms, sview->texture_p1 | sampler->texture_p1); } static void -write_texture_p2(struct vc4_context *vc4, +write_texture_p2(struct vc4_job *job, struct vc4_cl_out **uniforms, struct vc4_texture_stateobj *texstate, uint32_t data) @@ -125,16 +72,40 @@ write_texture_p2(struct vc4_context *vc4, VC4_SET_FIELD((data >> 16) & 1, VC4_TEX_P2_BSLOD)); } +static void +write_texture_first_level(struct vc4_job *job, + struct vc4_cl_out **uniforms, + struct vc4_texture_stateobj *texstate, + uint32_t data) +{ + uint32_t unit = data & 0xffff; + struct pipe_sampler_view *texture = texstate->textures[unit]; + + cl_aligned_f(uniforms, texture->u.tex.first_level); +} + +static void +write_texture_msaa_addr(struct vc4_job *job, + struct vc4_cl_out **uniforms, + 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_aligned_reloc(job, &job->uniforms, uniforms, rsc->bo, 0); +} + #define SWIZ(x,y,z,w) { \ - UTIL_FORMAT_SWIZZLE_##x, \ - UTIL_FORMAT_SWIZZLE_##y, \ - UTIL_FORMAT_SWIZZLE_##z, \ - UTIL_FORMAT_SWIZZLE_##w \ + PIPE_SWIZZLE_##x, \ + PIPE_SWIZZLE_##y, \ + PIPE_SWIZZLE_##z, \ + PIPE_SWIZZLE_##w \ } static void -write_texture_border_color(struct vc4_context *vc4, +write_texture_border_color(struct vc4_job *job, struct vc4_cl_out **uniforms, struct vc4_texture_stateobj *texstate, uint32_t unit) @@ -179,6 +150,7 @@ write_texture_border_color(struct vc4_context *vc4, PIPE_FORMAT_R8G8B8A8_UNORM, &uc); break; case VC4_TEXTURE_TYPE_RGBA4444: + case VC4_TEXTURE_TYPE_RGBA5551: util_pack_color(storage_color, PIPE_FORMAT_A8B8G8R8_UNORM, &uc); break; @@ -215,50 +187,33 @@ get_texrect_scale(struct vc4_texture_stateobj *texstate, return fui(1.0f / dim); } -static struct vc4_bo * -vc4_upload_ubo(struct vc4_context *vc4, - struct vc4_compiled_shader *shader, - const uint32_t *gallium_uniforms) -{ - if (!shader->ubo_size) - return NULL; - - struct vc4_bo *ubo = vc4_bo_alloc(vc4->screen, shader->ubo_size, "ubo"); - uint32_t *data = vc4_bo_map(ubo); - for (uint32_t i = 0; i < shader->num_ubo_ranges; i++) { - memcpy(data + shader->ubo_ranges[i].dst_offset, - gallium_uniforms + shader->ubo_ranges[i].src_offset, - shader->ubo_ranges[i].size); - } - - return ubo; -} - void vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader, struct vc4_constbuf_stateobj *cb, struct vc4_texture_stateobj *texstate) { struct vc4_shader_uniform_info *uinfo = &shader->uniforms; + struct vc4_job *job = vc4->job; const uint32_t *gallium_uniforms = cb->cb[0].user_buffer; - struct vc4_bo *ubo = vc4_upload_ubo(vc4, shader, gallium_uniforms); - cl_ensure_space(&vc4->uniforms, (uinfo->count + + cl_ensure_space(&job->uniforms, (uinfo->count + uinfo->num_texture_samples) * 4); struct vc4_cl_out *uniforms = - cl_start_shader_reloc(&vc4->uniforms, + cl_start_shader_reloc(&job->uniforms, uinfo->num_texture_samples); for (int i = 0; i < uinfo->count; i++) { + enum quniform_contents contents = uinfo->contents[i]; + uint32_t data = uinfo->data[i]; - switch (uinfo->contents[i]) { + switch (contents) { case QUNIFORM_CONSTANT: - cl_aligned_u32(&uniforms, uinfo->data[i]); + cl_aligned_u32(&uniforms, data); break; case QUNIFORM_UNIFORM: cl_aligned_u32(&uniforms, - gallium_uniforms[uinfo->data[i]]); + gallium_uniforms[data]); break; case QUNIFORM_VIEWPORT_X_SCALE: cl_aligned_f(&uniforms, vc4->viewport.scale[0] * 16.0f); @@ -276,31 +231,63 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader, case QUNIFORM_USER_CLIP_PLANE: cl_aligned_f(&uniforms, - vc4->clip.ucp[uinfo->data[i] / 4][uinfo->data[i] % 4]); + vc4->clip.ucp[data / 4][data % 4]); break; case QUNIFORM_TEXTURE_CONFIG_P0: - write_texture_p0(vc4, &uniforms, texstate, - uinfo->data[i]); + write_texture_p0(job, &uniforms, texstate, data); break; case QUNIFORM_TEXTURE_CONFIG_P1: - write_texture_p1(vc4, &uniforms, texstate, - uinfo->data[i]); + write_texture_p1(job, &uniforms, texstate, data); break; case QUNIFORM_TEXTURE_CONFIG_P2: - write_texture_p2(vc4, &uniforms, texstate, - uinfo->data[i]); + write_texture_p2(job, &uniforms, texstate, data); + break; + + case QUNIFORM_TEXTURE_FIRST_LEVEL: + write_texture_first_level(job, &uniforms, texstate, + data); + break; + + case QUNIFORM_UBO0_ADDR: + /* Constant buffer 0 may be a system memory pointer, + * in which case we want to upload a shadow copy to + * the GPU. + */ + if (!cb->cb[0].buffer) { + u_upload_data(vc4->uploader, 0, + cb->cb[0].buffer_size, 16, + cb->cb[0].user_buffer, + &cb->cb[0].buffer_offset, + &cb->cb[0].buffer); + } + + cl_aligned_reloc(job, &job->uniforms, + &uniforms, + vc4_resource(cb->cb[0].buffer)->bo, + cb->cb[0].buffer_offset + + data); break; - case QUNIFORM_UBO_ADDR: - cl_aligned_reloc(vc4, &vc4->uniforms, &uniforms, ubo, 0); + case QUNIFORM_UBO1_ADDR: { + struct vc4_resource *rsc = + vc4_resource(cb->cb[1].buffer); + + cl_aligned_reloc(job, &job->uniforms, + &uniforms, + rsc->bo, cb->cb[1].buffer_offset); + break; + } + + case QUNIFORM_TEXTURE_MSAA_ADDR: + write_texture_msaa_addr(job, &uniforms, texstate, data); break; case QUNIFORM_TEXTURE_BORDER_COLOR: - write_texture_border_color(vc4, &uniforms, - texstate, uinfo->data[i]); + write_texture_border_color(job, &uniforms, + texstate, data); break; case QUNIFORM_TEXRECT_SCALE_X: @@ -308,19 +295,48 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader, cl_aligned_u32(&uniforms, get_texrect_scale(texstate, uinfo->contents[i], - uinfo->data[i])); + data)); break; - case QUNIFORM_BLEND_CONST_COLOR: + case QUNIFORM_BLEND_CONST_COLOR_X: + case QUNIFORM_BLEND_CONST_COLOR_Y: + case QUNIFORM_BLEND_CONST_COLOR_Z: + case QUNIFORM_BLEND_CONST_COLOR_W: cl_aligned_f(&uniforms, - CLAMP(vc4->blend_color.color[uinfo->data[i]], 0, 1)); + CLAMP(vc4->blend_color.f.color[uinfo->contents[i] - + QUNIFORM_BLEND_CONST_COLOR_X], + 0, 1)); break; + case QUNIFORM_BLEND_CONST_COLOR_RGBA: { + const uint8_t *format_swiz = + vc4_get_format_swizzle(vc4->framebuffer.cbufs[0]->format); + uint32_t color = 0; + for (int i = 0; i < 4; i++) { + if (format_swiz[i] >= 4) + continue; + + color |= (vc4->blend_color.ub[format_swiz[i]] << + (i * 8)); + } + cl_aligned_u32(&uniforms, color); + break; + } + + case QUNIFORM_BLEND_CONST_COLOR_AAAA: { + uint8_t a = vc4->blend_color.ub[3]; + cl_aligned_u32(&uniforms, ((a) | + (a << 8) | + (a << 16) | + (a << 24))); + break; + } + case QUNIFORM_STENCIL: cl_aligned_u32(&uniforms, - vc4->zsa->stencil_uniforms[uinfo->data[i]] | - (uinfo->data[i] <= 1 ? - (vc4->stencil_ref.ref_value[uinfo->data[i]] << 8) : + vc4->zsa->stencil_uniforms[data] | + (data <= 1 ? + (vc4->stencil_ref.ref_value[data] << 8) : 0)); break; @@ -328,13 +344,93 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader, cl_aligned_f(&uniforms, vc4->zsa->base.alpha.ref_value); break; + + case QUNIFORM_SAMPLE_MASK: + cl_aligned_u32(&uniforms, vc4->sample_mask); + break; + + case QUNIFORM_UNIFORMS_ADDRESS: + /* This will be filled in by the kernel. */ + cl_aligned_u32(&uniforms, 0xd0d0d0d0); + break; + } + + if (false) { + uint32_t written_val = *((uint32_t *)uniforms - 1); + char *desc = qir_describe_uniform(uinfo->contents[i], + uinfo->data[i], + gallium_uniforms); + + fprintf(stderr, "%p/%d: 0x%08x %s\n", + shader, i, written_val, desc); + + ralloc_free(desc); + } + } + + cl_end(&job->uniforms, uniforms); +} + +void +vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader) +{ + uint32_t dirty = 0; + + for (int i = 0; i < shader->uniforms.count; i++) { + switch (shader->uniforms.contents[i]) { + case QUNIFORM_CONSTANT: + case QUNIFORM_UNIFORMS_ADDRESS: + break; + case QUNIFORM_UNIFORM: + case QUNIFORM_UBO0_ADDR: + case QUNIFORM_UBO1_ADDR: + dirty |= VC4_DIRTY_CONSTBUF; + break; + + case QUNIFORM_VIEWPORT_X_SCALE: + case QUNIFORM_VIEWPORT_Y_SCALE: + case QUNIFORM_VIEWPORT_Z_OFFSET: + case QUNIFORM_VIEWPORT_Z_SCALE: + dirty |= VC4_DIRTY_VIEWPORT; + break; + + case QUNIFORM_USER_CLIP_PLANE: + dirty |= VC4_DIRTY_CLIP; + break; + + case QUNIFORM_TEXTURE_CONFIG_P0: + case QUNIFORM_TEXTURE_CONFIG_P1: + case QUNIFORM_TEXTURE_CONFIG_P2: + case QUNIFORM_TEXTURE_BORDER_COLOR: + case QUNIFORM_TEXTURE_FIRST_LEVEL: + case QUNIFORM_TEXTURE_MSAA_ADDR: + case QUNIFORM_TEXRECT_SCALE_X: + case QUNIFORM_TEXRECT_SCALE_Y: + /* We could flag this on just the stage we're + * compiling for, but it's not passed in. + */ + dirty |= VC4_DIRTY_FRAGTEX | VC4_DIRTY_VERTTEX; + break; + + case QUNIFORM_BLEND_CONST_COLOR_X: + case QUNIFORM_BLEND_CONST_COLOR_Y: + case QUNIFORM_BLEND_CONST_COLOR_Z: + case QUNIFORM_BLEND_CONST_COLOR_W: + case QUNIFORM_BLEND_CONST_COLOR_RGBA: + case QUNIFORM_BLEND_CONST_COLOR_AAAA: + dirty |= VC4_DIRTY_BLEND_COLOR; + break; + + case QUNIFORM_STENCIL: + case QUNIFORM_ALPHA_REF: + dirty |= VC4_DIRTY_ZSA; + break; + + case QUNIFORM_SAMPLE_MASK: + dirty |= VC4_DIRTY_SAMPLE_MASK; + break; } -#if 0 - uint32_t written_val = *((uint32_t *)uniforms - 1); - fprintf(stderr, "%p: %d / 0x%08x (%f)\n", - shader, i, written_val, uif(written_val)); -#endif } - cl_end(&vc4->uniforms, uniforms); + shader->uniform_dirty_bits = dirty; }