if (sctx->dummy_pixel_shader) {
sctx->b.b.delete_fs_state(&sctx->b.b, sctx->dummy_pixel_shader);
}
+ if (sctx->fixed_func_tcs_shader)
+ sctx->b.b.delete_tcs_state(&sctx->b.b, sctx->fixed_func_tcs_shader);
sctx->b.b.delete_depth_stencil_alpha_state(&sctx->b.b, sctx->custom_dsa_flush);
sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_resolve);
sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_decompress);
}
}
+static void si_set_tess_state(struct pipe_context *ctx,
+ const float default_outer_level[4],
+ const float default_inner_level[2])
+{
+ struct si_context *sctx = (struct si_context *)ctx;
+ struct pipe_constant_buffer cb;
+ float array[8];
+
+ memcpy(array, default_outer_level, sizeof(float) * 4);
+ memcpy(array+4, default_inner_level, sizeof(float) * 2);
+
+ cb.buffer = NULL;
+ cb.user_buffer = NULL;
+ cb.buffer_size = sizeof(array);
+
+ si_upload_const_buffer(sctx, (struct r600_resource**)&cb.buffer,
+ (void*)array, sizeof(array),
+ &cb.buffer_offset);
+
+ ctx->set_constant_buffer(ctx, PIPE_SHADER_TESS_CTRL,
+ SI_DRIVER_STATE_CONST_BUF, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+}
+
static void si_texture_barrier(struct pipe_context *ctx)
{
struct si_context *sctx = (struct si_context *)ctx;
sctx->b.b.texture_barrier = si_texture_barrier;
sctx->b.b.set_polygon_stipple = si_set_polygon_stipple;
sctx->b.b.set_min_samples = si_set_min_samples;
+ sctx->b.b.set_tess_state = si_set_tess_state;
sctx->b.set_occlusion_query_state = si_set_occlusion_query_state;
sctx->b.need_gfx_cs_space = si_need_gfx_cs_space;
#include "sid.h"
#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_ureg.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
sctx->b.flags |= SI_CONTEXT_VGT_FLUSH;
}
+/**
+ * This is used when TCS is NULL in the VS->TCS->TES chain. In this case,
+ * VS passes its outputs to TES directly, so the fixed-function shader only
+ * has to write TESSOUTER and TESSINNER.
+ */
+static void si_generate_fixed_func_tcs(struct si_context *sctx)
+{
+ struct ureg_src const0, const1;
+ struct ureg_dst tessouter, tessinner;
+ struct ureg_program *ureg = ureg_create(TGSI_PROCESSOR_TESS_CTRL);
+
+ if (!ureg)
+ return; /* if we get here, we're screwed */
+
+ assert(!sctx->fixed_func_tcs_shader);
+
+ ureg_DECL_constant2D(ureg, 0, 1, SI_DRIVER_STATE_CONST_BUF);
+ const0 = ureg_src_dimension(ureg_src_register(TGSI_FILE_CONSTANT, 0),
+ SI_DRIVER_STATE_CONST_BUF);
+ const1 = ureg_src_dimension(ureg_src_register(TGSI_FILE_CONSTANT, 1),
+ SI_DRIVER_STATE_CONST_BUF);
+
+ tessouter = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSOUTER, 0);
+ tessinner = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSINNER, 0);
+
+ ureg_MOV(ureg, tessouter, const0);
+ ureg_MOV(ureg, tessinner, const1);
+ ureg_END(ureg);
+
+ sctx->fixed_func_tcs_shader =
+ ureg_create_shader_and_destroy(ureg, &sctx->b.b);
+ assert(sctx->fixed_func_tcs_shader);
+}
+
static void si_update_vgt_shader_config(struct si_context *sctx)
{
/* Calculate the index of the config.
si_shader_select(ctx, sctx->tcs_shader);
si_pm4_bind_state(sctx, hs, sctx->tcs_shader->current->pm4);
} else {
- assert(!"generate TCS shader");
+ if (!sctx->fixed_func_tcs_shader)
+ si_generate_fixed_func_tcs(sctx);
+ si_shader_select(ctx, sctx->fixed_func_tcs_shader);
+ si_pm4_bind_state(sctx, hs,
+ sctx->fixed_func_tcs_shader->current->pm4);
}
si_shader_select(ctx, sctx->tes_shader);