broadcom/vc5: Fix translation of stencil ops.
[mesa.git] / src / gallium / drivers / vc5 / vc5_state.c
index db921d63f3664e66cc3a69543238a01dea6c58ef..d88555354917bac3f081d18e7dfc34ba61588182 100644 (file)
@@ -127,6 +127,22 @@ vc5_create_blend_state(struct pipe_context *pctx,
         return vc5_generic_cso_state_create(cso, sizeof(*cso));
 }
 
+static uint32_t
+translate_stencil_op(enum pipe_stencil_op op)
+{
+        switch (op) {
+        case PIPE_STENCIL_OP_KEEP:      return V3D_STENCIL_OP_KEEP;
+        case PIPE_STENCIL_OP_ZERO:      return V3D_STENCIL_OP_ZERO;
+        case PIPE_STENCIL_OP_REPLACE:   return V3D_STENCIL_OP_REPLACE;
+        case PIPE_STENCIL_OP_INCR:      return V3D_STENCIL_OP_INCR;
+        case PIPE_STENCIL_OP_DECR:      return V3D_STENCIL_OP_DECR;
+        case PIPE_STENCIL_OP_INCR_WRAP: return V3D_STENCIL_OP_INCWRAP;
+        case PIPE_STENCIL_OP_DECR_WRAP: return V3D_STENCIL_OP_DECWRAP;
+        case PIPE_STENCIL_OP_INVERT:    return V3D_STENCIL_OP_INVERT;
+        }
+        unreachable("bad stencil op");
+}
+
 static void *
 vc5_create_depth_stencil_alpha_state(struct pipe_context *pctx,
                                      const struct pipe_depth_stencil_alpha_state *cso)
@@ -153,6 +169,47 @@ vc5_create_depth_stencil_alpha_state(struct pipe_context *pctx,
                             cso->stencil[1].zfail_op == PIPE_STENCIL_OP_KEEP))));
         }
 
+        const struct pipe_stencil_state *front = &cso->stencil[0];
+        const struct pipe_stencil_state *back = &cso->stencil[1];
+
+        if (front->enabled) {
+                v3dx_pack(&so->stencil_front, STENCIL_CONFIG, config) {
+                        config.front_config = true;
+                        /* If !back->enabled, then the front values should be
+                         * used for both front and back-facing primitives.
+                         */
+                        config.back_config = !back->enabled;
+
+                        config.stencil_write_mask = front->writemask;
+                        config.stencil_test_mask = front->valuemask;
+
+                        config.stencil_test_function = front->func;
+                        config.stencil_pass_op =
+                                translate_stencil_op(front->zpass_op);
+                        config.depth_test_fail_op =
+                                translate_stencil_op(front->zfail_op);
+                        config.stencil_test_fail_op =
+                                translate_stencil_op(front->fail_op);
+                }
+        }
+        if (back->enabled) {
+                v3dx_pack(&so->stencil_back, STENCIL_CONFIG, config) {
+                        config.front_config = false;
+                        config.back_config = true;
+
+                        config.stencil_write_mask = back->writemask;
+                        config.stencil_test_mask = back->valuemask;
+
+                        config.stencil_test_function = back->func;
+                        config.stencil_pass_op =
+                                translate_stencil_op(back->zpass_op);
+                        config.depth_test_fail_op =
+                                translate_stencil_op(back->zfail_op);
+                        config.stencil_test_fail_op =
+                                translate_stencil_op(back->fail_op);
+                }
+        }
+
         return so;
 }
 
@@ -253,63 +310,61 @@ vc5_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,
                         util_format_description(elem->src_format);
                 uint32_t r_size = desc->channel[0].size;
 
-                struct V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD attr_unpacked = {
-                        /* vec_size == 0 means 4 */
-                        .vec_size = desc->nr_channels & 3,
-                        .signed_int_type = (desc->channel[0].type ==
-                                            UTIL_FORMAT_TYPE_SIGNED),
-
-                        .normalized_int_type = desc->channel[0].normalized,
-                        .read_as_int_uint = desc->channel[0].pure_integer,
-                        .instance_divisor = elem->instance_divisor,
-                };
-
-                switch (desc->channel[0].type) {
-                case UTIL_FORMAT_TYPE_FLOAT:
-                        if (r_size == 32) {
-                                attr_unpacked.type = ATTRIBUTE_FLOAT;
-                        } else {
-                                assert(r_size == 16);
-                                attr_unpacked.type = ATTRIBUTE_HALF_FLOAT;
-                        }
-                        break;
+                const uint32_t size =
+                        cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD);
 
-                case UTIL_FORMAT_TYPE_SIGNED:
-                case UTIL_FORMAT_TYPE_UNSIGNED:
-                        switch (r_size) {
-                        case 32:
-                                attr_unpacked.type = ATTRIBUTE_INT;
-                                break;
-                        case 16:
-                                attr_unpacked.type = ATTRIBUTE_SHORT;
-                                break;
-                        case 10:
-                                attr_unpacked.type = ATTRIBUTE_INT2_10_10_10;
+                v3dx_pack(&so->attrs[i * size],
+                          GL_SHADER_STATE_ATTRIBUTE_RECORD, attr) {
+                        /* vec_size == 0 means 4 */
+                        attr.vec_size = desc->nr_channels & 3;
+                        attr.signed_int_type = (desc->channel[0].type ==
+                                                UTIL_FORMAT_TYPE_SIGNED);
+
+                        attr.normalized_int_type = desc->channel[0].normalized;
+                        attr.read_as_int_uint = desc->channel[0].pure_integer;
+                        attr.instance_divisor = elem->instance_divisor;
+
+                        switch (desc->channel[0].type) {
+                        case UTIL_FORMAT_TYPE_FLOAT:
+                                if (r_size == 32) {
+                                        attr.type = ATTRIBUTE_FLOAT;
+                                } else {
+                                        assert(r_size == 16);
+                                        attr.type = ATTRIBUTE_HALF_FLOAT;
+                                }
                                 break;
-                        case 8:
-                                attr_unpacked.type = ATTRIBUTE_BYTE;
+
+                        case UTIL_FORMAT_TYPE_SIGNED:
+                        case UTIL_FORMAT_TYPE_UNSIGNED:
+                                switch (r_size) {
+                                case 32:
+                                        attr.type = ATTRIBUTE_INT;
+                                        break;
+                                case 16:
+                                        attr.type = ATTRIBUTE_SHORT;
+                                        break;
+                                case 10:
+                                        attr.type = ATTRIBUTE_INT2_10_10_10;
+                                        break;
+                                case 8:
+                                        attr.type = ATTRIBUTE_BYTE;
+                                        break;
+                                default:
+                                        fprintf(stderr,
+                                                "format %s unsupported\n",
+                                                desc->name);
+                                        attr.type = ATTRIBUTE_BYTE;
+                                        abort();
+                                }
                                 break;
+
                         default:
                                 fprintf(stderr,
                                         "format %s unsupported\n",
                                         desc->name);
-                                attr_unpacked.type = ATTRIBUTE_BYTE;
                                 abort();
                         }
-                        break;
-
-                default:
-                        fprintf(stderr,
-                                "format %s unsupported\n",
-                                desc->name);
-                        abort();
                 }
-
-                const uint32_t size =
-                        cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD);
-                V3D33_GL_SHADER_STATE_ATTRIBUTE_RECORD_pack(NULL,
-                                                            (uint8_t *)&so->attrs[i * size],
-                                                            &attr_unpacked);
         }
 
         /* Set up the default attribute values in case any of the vertex
@@ -462,26 +517,17 @@ vc5_create_sampler_state(struct pipe_context *pctx,
                 (cso->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST ||
                  cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST);
 
-        struct V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1 p0_unpacked = {
-                .s_wrap_mode = translate_wrap(cso->wrap_s, either_nearest),
-                .t_wrap_mode = translate_wrap(cso->wrap_t, either_nearest),
-                .r_wrap_mode = translate_wrap(cso->wrap_r, either_nearest),
-        };
-        V3D33_TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1_pack(NULL,
-                                                         (uint8_t *)&so->p0,
-                                                         &p0_unpacked);
-
-        struct V3D33_TEXTURE_SHADER_STATE state_unpacked = {
-                cl_packet_header(TEXTURE_SHADER_STATE),
+        v3dx_pack(&so->p0, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1, p0) {
+                p0.s_wrap_mode = translate_wrap(cso->wrap_s, either_nearest);
+                p0.t_wrap_mode = translate_wrap(cso->wrap_t, either_nearest);
+                p0.r_wrap_mode = translate_wrap(cso->wrap_r, either_nearest);
+        }
 
-                .min_level_of_detail = MAX2(cso->min_lod, 0.0),
-                .depth_compare_function = cso->compare_func,
-                .fixed_bias = cso->lod_bias,
-        };
-        STATIC_ASSERT(ARRAY_SIZE(so->texture_shader_state) ==
-                      cl_packet_length(TEXTURE_SHADER_STATE));
-        cl_packet_pack(TEXTURE_SHADER_STATE)(NULL, so->texture_shader_state,
-                                             &state_unpacked);
+        v3dx_pack(&so->texture_shader_state, TEXTURE_SHADER_STATE, tex) {
+                tex.min_level_of_detail = MAX2(cso->min_lod, 0.0);
+                tex.depth_compare_function = cso->compare_func;
+                tex.fixed_bias = cso->lod_bias;
+        }
 
         return so;
 }
@@ -543,27 +589,19 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
 
         pipe_reference(NULL, &prsc->reference);
 
-        struct V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1 unpacked = {
-        };
+        v3dx_pack(&so->p1, TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1, p1) {
+                p1.return_word_0_of_texture_data = true;
+                if (vc5_get_tex_return_size(cso->format) == 16) {
+                        p1.return_word_1_of_texture_data = true;
+                } else {
+                        int chans = vc5_get_tex_return_channels(cso->format);
 
-        unpacked.return_word_0_of_texture_data = true;
-        if (vc5_get_tex_return_size(cso->format) == 16) {
-                unpacked.return_word_1_of_texture_data = true;
-        } else {
-                int chans = vc5_get_tex_return_channels(cso->format);
-
-                if (chans > 1)
-                        unpacked.return_word_1_of_texture_data = true;
-                if (chans > 2)
-                        unpacked.return_word_2_of_texture_data = true;
-                if (chans > 3)
-                        unpacked.return_word_3_of_texture_data = true;
+                        p1.return_word_1_of_texture_data = chans > 1;
+                        p1.return_word_2_of_texture_data = chans > 2;
+                        p1.return_word_3_of_texture_data = chans > 3;
+                }
         }
 
-        V3D33_TEXTURE_UNIFORM_PARAMETER_1_CFG_MODE1_pack(NULL,
-                                                         (uint8_t *)&so->p1,
-                                                         &unpacked);
-
         /* Compute the sampler view's swizzle up front. This will be plugged
          * into either the sampler (for 16-bit returns) or the shader's
          * texture key (for 32)
@@ -583,94 +621,90 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
 
         int msaa_scale = prsc->nr_samples > 1 ? 2 : 1;
 
-        struct V3D33_TEXTURE_SHADER_STATE state_unpacked = {
-                cl_packet_header(TEXTURE_SHADER_STATE),
-
-                .image_width = prsc->width0 * msaa_scale,
-                .image_height = prsc->height0 * msaa_scale,
-                .image_depth = prsc->depth0,
+        v3dx_pack(&so->texture_shader_state, TEXTURE_SHADER_STATE, tex) {
+                tex.image_width = prsc->width0 * msaa_scale;
+                tex.image_height = prsc->height0 * msaa_scale;
+                tex.image_depth = prsc->depth0;
+
+                tex.srgb = util_format_is_srgb(cso->format);
+
+                tex.base_level = cso->u.tex.first_level;
+                tex.array_stride_64_byte_aligned = rsc->cube_map_stride / 64;
+
+                if (prsc->nr_samples > 1) {
+                        /* Using texture views to reinterpret formats on our
+                         * MSAA textures won't work, because we don't lay out
+                         * the bits in memory as it's expected -- for example,
+                         * RGBA8 and RGB10_A2 are compatible in the
+                         * ARB_texture_view spec, but in HW we lay them out as
+                         * 32bpp RGBA8 and 64bpp RGBA16F.  Just assert for now
+                         * to catch failures.
+                         */
+                        assert(util_format_linear(cso->format) ==
+                               util_format_linear(prsc->format));
+                        uint32_t output_image_format =
+                                vc5_get_rt_format(cso->format);
+                        uint32_t internal_type;
+                        uint32_t internal_bpp;
+                        vc5_get_internal_type_bpp_for_output_format(output_image_format,
+                                                                    &internal_type,
+                                                                    &internal_bpp);
+
+                        switch (internal_type) {
+                        case INTERNAL_TYPE_8:
+                                tex.texture_type = TEXTURE_DATA_FORMAT_RGBA8;
+                                break;
+                        case INTERNAL_TYPE_16F:
+                                tex.texture_type = TEXTURE_DATA_FORMAT_RGBA16F;
+                                break;
+                        default:
+                                unreachable("Bad MSAA texture type");
+                        }
 
-                .srgb = util_format_is_srgb(cso->format),
+                        /* sRGB was stored in the tile buffer as linear and
+                         * would have been encoded to sRGB on resolved tile
+                         * buffer store.  Note that this means we would need
+                         * shader code if we wanted to read an MSAA sRGB
+                         * texture without sRGB decode.
+                         */
+                        tex.srgb = false;
+                } else {
+                        tex.texture_type = vc5_get_tex_format(cso->format);
+                }
 
-                .base_level = cso->u.tex.first_level,
-                .array_stride_64_byte_aligned = rsc->cube_map_stride / 64,
-        };
+                /* Note: Contrary to the docs, the swizzle still applies even
+                 * if the return size is 32.  It's just that you probably want
+                 * to swizzle in the shader, because you need the Y/Z/W
+                 * channels to be defined.
+                 */
+                if (vc5_get_tex_return_size(cso->format) != 32) {
+                        tex.swizzle_r = translate_swizzle(so->swizzle[0]);
+                        tex.swizzle_g = translate_swizzle(so->swizzle[1]);
+                        tex.swizzle_b = translate_swizzle(so->swizzle[2]);
+                        tex.swizzle_a = translate_swizzle(so->swizzle[3]);
+                } else {
+                        tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);
+                        tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);
+                        tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z);
+                        tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W);
+                }
 
-        if (prsc->nr_samples > 1) {
-                /* Using texture views to reinterpret formats on our MSAA
-                 * textures won't work, because we don't lay out the bits in
-                 * memory as it's expected -- for example, RGBA8 and RGB10_A2
-                 * are compatible in the ARB_texture_view spec, but in HW we
-                 * lay them out as 32bpp RGBA8 and 64bpp RGBA16F.  Just assert
-                 * for now to catch failures.
+                /* XXX: While we need to use this flag to enable tiled
+                 * resource sharing (even a small shared buffer should be UIF,
+                 * not UBLINEAR or raster), this is also at the moment
+                 * patching up the fact that our resource layout's decisions
+                 * about XOR don't quite match the HW's.
                  */
-                assert(util_format_linear(cso->format) ==
-                       util_format_linear(prsc->format));
-                uint32_t output_image_format = vc5_get_rt_format(cso->format);
-                uint32_t internal_type;
-                uint32_t internal_bpp;
-                vc5_get_internal_type_bpp_for_output_format(output_image_format,
-                                                            &internal_type,
-                                                            &internal_bpp);
-
-                switch (internal_type) {
-                case INTERNAL_TYPE_8:
-                        state_unpacked.texture_type = TEXTURE_DATA_FORMAT_RGBA8;
-                        break;
-                case INTERNAL_TYPE_16F:
-                        state_unpacked.texture_type = TEXTURE_DATA_FORMAT_RGBA16F;
+                switch (rsc->slices[0].tiling) {
+                case VC5_TILING_UIF_NO_XOR:
+                case VC5_TILING_UIF_XOR:
+                        tex.level_0_is_strictly_uif = true;
+                        tex.level_0_xor_enable = false;
                         break;
                 default:
-                        unreachable("Bad MSAA texture type");
+                        break;
                 }
-
-                /* sRGB was stored in the tile buffer as linear and would have
-                 * been encoded to sRGB on resolved tile buffer store.  Note
-                 * that this means we would need shader code if we wanted to
-                 * read an MSAA sRGB texture without sRGB decode.
-                 */
-                state_unpacked.srgb = false;
-        } else {
-                state_unpacked.texture_type = vc5_get_tex_format(cso->format);
-        }
-
-        /* Note: Contrary to the docs, the swizzle still applies even
-         * if the return size is 32.  It's just that you probably want
-         * to swizzle in the shader, because you need the Y/Z/W
-         * channels to be defined.
-         */
-        if (vc5_get_tex_return_size(cso->format) != 32) {
-                state_unpacked.swizzle_r = translate_swizzle(so->swizzle[0]);
-                state_unpacked.swizzle_g = translate_swizzle(so->swizzle[1]);
-                state_unpacked.swizzle_b = translate_swizzle(so->swizzle[2]);
-                state_unpacked.swizzle_a = translate_swizzle(so->swizzle[3]);
-        } else {
-                state_unpacked.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);
-                state_unpacked.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);
-                state_unpacked.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z);
-                state_unpacked.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W);
-        }
-
-        /* XXX: While we need to use this flag to enable tiled
-         * resource sharing (even a small shared buffer should be UIF,
-         * not UBLINEAR or raster), this is also at the moment
-         * patching up the fact that our resource layout's decisions
-         * about XOR don't quite match the HW's.
-         */
-        switch (rsc->slices[0].tiling) {
-        case VC5_TILING_UIF_NO_XOR:
-        case VC5_TILING_UIF_XOR:
-                state_unpacked.level_0_is_strictly_uif = true;
-                state_unpacked.level_0_xor_enable = false;
-                break;
-        default:
-                break;
-        }
-
-        STATIC_ASSERT(ARRAY_SIZE(so->texture_shader_state) ==
-                      cl_packet_length(TEXTURE_SHADER_STATE));
-        cl_packet_pack(TEXTURE_SHADER_STATE)(NULL, so->texture_shader_state,
-                                             &state_unpacked);
+        };
 
         return &so->base;
 }