return virgl_shader_encoder(ctx, shader, PIPE_SHADER_VERTEX);
}
+static void *virgl_create_tcs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *shader)
+{
+ return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_CTRL);
+}
+
+static void *virgl_create_tes_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *shader)
+{
+ return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_EVAL);
+}
+
static void *virgl_create_gs_state(struct pipe_context *ctx,
const struct pipe_shader_state *shader)
{
virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
}
+static void
+virgl_delete_tcs_state(struct pipe_context *ctx,
+ void *tcs)
+{
+ uint32_t handle = (unsigned long)tcs;
+ struct virgl_context *vctx = virgl_context(ctx);
+
+ virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
+}
+
+static void
+virgl_delete_tes_state(struct pipe_context *ctx,
+ void *tes)
+{
+ uint32_t handle = (unsigned long)tes;
+ struct virgl_context *vctx = virgl_context(ctx);
+
+ virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
+}
+
static void virgl_bind_vs_state(struct pipe_context *ctx,
void *vss)
{
virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_VERTEX);
}
+static void virgl_bind_tcs_state(struct pipe_context *ctx,
+ void *vss)
+{
+ uint32_t handle = (unsigned long)vss;
+ struct virgl_context *vctx = virgl_context(ctx);
+
+ virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_CTRL);
+}
+
+static void virgl_bind_tes_state(struct pipe_context *ctx,
+ void *vss)
+{
+ uint32_t handle = (unsigned long)vss;
+ struct virgl_context *vctx = virgl_context(ctx);
+
+ virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_EVAL);
+}
+
static void virgl_bind_gs_state(struct pipe_context *ctx,
void *vss)
{
virgl_encoder_set_clip_state(vctx, clip);
}
+static void virgl_set_tess_state(struct pipe_context *ctx,
+ const float default_outer_level[4],
+ const float default_inner_level[2])
+{
+ struct virgl_context *vctx = virgl_context(ctx);
+ struct virgl_screen *rs = virgl_screen(ctx->screen);
+
+ if (!rs->caps.caps.v1.bset.has_tessellation_shaders)
+ return;
+ virgl_encode_set_tess_state(vctx, default_outer_level, default_inner_level);
+}
+
static void virgl_resource_copy_region(struct pipe_context *ctx,
struct pipe_resource *dst,
unsigned dst_level,
vctx->base.set_vertex_buffers = virgl_set_vertex_buffers;
vctx->base.set_constant_buffer = virgl_set_constant_buffer;
+ vctx->base.set_tess_state = virgl_set_tess_state;
vctx->base.create_vs_state = virgl_create_vs_state;
+ vctx->base.create_tcs_state = virgl_create_tcs_state;
+ vctx->base.create_tes_state = virgl_create_tes_state;
vctx->base.create_gs_state = virgl_create_gs_state;
vctx->base.create_fs_state = virgl_create_fs_state;
vctx->base.bind_vs_state = virgl_bind_vs_state;
+ vctx->base.bind_tcs_state = virgl_bind_tcs_state;
+ vctx->base.bind_tes_state = virgl_bind_tes_state;
vctx->base.bind_gs_state = virgl_bind_gs_state;
vctx->base.bind_fs_state = virgl_bind_fs_state;
vctx->base.delete_vs_state = virgl_delete_vs_state;
+ vctx->base.delete_tcs_state = virgl_delete_tcs_state;
+ vctx->base.delete_tes_state = virgl_delete_tes_state;
vctx->base.delete_gs_state = virgl_delete_gs_state;
vctx->base.delete_fs_state = virgl_delete_fs_state;
const struct pipe_draw_info *info)
{
uint32_t length = VIRGL_DRAW_VBO_SIZE;
+ if (info->mode == PIPE_PRIM_PATCHES)
+ length = VIRGL_DRAW_VBO_SIZE_TESS;
if (info->indirect)
length = VIRGL_DRAW_VBO_SIZE_INDIRECT;
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DRAW_VBO, 0, length));
virgl_encoder_write_dword(ctx->cbuf, info->count_from_stream_output->buffer_size);
else
virgl_encoder_write_dword(ctx->cbuf, 0);
+ if (length >= VIRGL_DRAW_VBO_SIZE_TESS) {
+ virgl_encoder_write_dword(ctx->cbuf, info->vertices_per_patch); /* vertices per patch */
+ virgl_encoder_write_dword(ctx->cbuf, info->drawid); /* drawid */
+ }
if (length == VIRGL_DRAW_VBO_SIZE_INDIRECT) {
- virgl_encoder_write_dword(ctx->cbuf, 0); /* vertices per patch */
- virgl_encoder_write_dword(ctx->cbuf, 0); /* drawid */
virgl_encoder_write_res(ctx, virgl_resource(info->indirect->buffer));
virgl_encoder_write_dword(ctx->cbuf, info->indirect->offset);
virgl_encoder_write_dword(ctx->cbuf, 0); /* indirect stride */
virgl_encoder_write_dword(ctx->cbuf, type);
return 0;
}
+
+int virgl_encode_set_tess_state(struct virgl_context *ctx,
+ const float outer[4],
+ const float inner[2])
+{
+ int i;
+ virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_TESS_STATE, 0, 6));
+ for (i = 0; i < 4; i++)
+ virgl_encoder_write_dword(ctx->cbuf, fui(outer[i]));
+ for (i = 0; i < 2; i++)
+ virgl_encoder_write_dword(ctx->cbuf, fui(inner[i]));
+ return 0;
+}
return vscreen->caps.caps.v2.shader_buffer_offset_alignment;
case PIPE_CAP_DOUBLES:
return vscreen->caps.caps.v1.bset.has_fp64;
+ case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
+ return vscreen->caps.caps.v2.max_shader_patch_varyings;
case PIPE_CAP_TEXTURE_GATHER_SM5:
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
case PIPE_CAP_FAKE_SW_MSAA:
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
- case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
case PIPE_CAP_DEPTH_BOUNDS_TEST:
enum pipe_shader_cap param)
{
struct virgl_screen *vscreen = virgl_screen(screen);
+
+ if ((shader == PIPE_SHADER_TESS_CTRL || shader == PIPE_SHADER_TESS_EVAL) &&
+ !vscreen->caps.caps.v1.bset.has_tessellation_shaders)
+ return 0;
+
switch(shader)
{
case PIPE_SHADER_FRAGMENT:
case PIPE_SHADER_VERTEX:
case PIPE_SHADER_GEOMETRY:
+ case PIPE_SHADER_TESS_CTRL:
+ case PIPE_SHADER_TESS_EVAL:
switch (param) {
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: