#include "radeon/r600_cs.h"
#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_scan.h"
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
#include "util/u_framebuffer.h"
if (blend == NULL)
return;
- pm4 = si_pm4_alloc_state(sctx);
+ pm4 = CALLOC_STRUCT(si_pm4_state);
if (pm4 == NULL)
return;
const struct pipe_blend_color *state)
{
struct si_context *sctx = (struct si_context *)ctx;
- struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
+ struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
if (pm4 == NULL)
return;
const struct pipe_clip_state *state)
{
struct si_context *sctx = (struct si_context *)ctx;
- struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
+ struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
struct pipe_constant_buffer cb;
if (pm4 == NULL)
return;
}
- pm4 = si_pm4_alloc_state(sctx);
+ pm4 = CALLOC_STRUCT(si_pm4_state);
if (pm4 == NULL)
return;
*/
static void si_update_dsa_stencil_ref(struct si_context *sctx)
{
- struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
+ struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
struct pipe_stencil_ref *ref = &sctx->stencil_ref;
struct si_state_dsa *dsa = sctx->queued.named.dsa;
struct si_context *sctx = (struct si_context *)ctx;
memset(key, 0, sizeof(*key));
- if ((sel->type == PIPE_SHADER_VERTEX || sel->type == PIPE_SHADER_GEOMETRY) &&
- sctx->queued.named.rasterizer) {
- if (sctx->queued.named.rasterizer->clip_plane_enable & 0xf0)
- key->vs.ucps_enabled |= 0x2;
- if (sctx->queued.named.rasterizer->clip_plane_enable & 0xf)
- key->vs.ucps_enabled |= 0x1;
- }
-
if (sel->type == PIPE_SHADER_VERTEX) {
unsigned i;
if (!sctx->vertex_elements)
key->vs.instance_divisors[i] = sctx->vertex_elements->elements[i].instance_divisor;
if (sctx->gs_shader) {
- /* At this point, the GS should be selected and compiled. */
key->vs.as_es = 1;
- key->vs.gs_used_inputs = sctx->gs_shader->current->gs_used_inputs;
+ key->vs.gs_used_inputs = sctx->gs_shader->gs_used_inputs;
}
} else if (sel->type == PIPE_SHADER_FRAGMENT) {
- if (sel->fs_write_all)
- key->ps.nr_cbufs = sctx->framebuffer.state.nr_cbufs;
+ if (sel->info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
+ key->ps.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1;
key->ps.export_16bpc = sctx->framebuffer.export_16bpc;
if (sctx->queued.named.rasterizer) {
key->ps.color_two_side = sctx->queued.named.rasterizer->two_side;
key->ps.flatshade = sctx->queued.named.rasterizer->flatshade;
- key->ps.interp_at_sample = sctx->framebuffer.nr_samples > 1 &&
- sctx->ps_iter_samples == sctx->framebuffer.nr_samples;
if (sctx->queued.named.blend) {
key->ps.alpha_to_one = sctx->queued.named.blend->alpha_to_one &&
shader->next_variant = sel->current;
sel->current = shader;
- r = si_shader_create(ctx, shader);
+ r = si_shader_create((struct si_screen*)ctx->screen, shader);
if (unlikely(r)) {
R600_ERR("Failed to build shader variant (type=%u) %d\n",
sel->type, r);
unsigned pipe_shader_type)
{
struct si_shader_selector *sel = CALLOC_STRUCT(si_shader_selector);
- int r;
+ int i;
sel->type = pipe_shader_type;
sel->tokens = tgsi_dup_tokens(state->tokens);
sel->so = state->stream_output;
+ tgsi_scan_shader(state->tokens, &sel->info);
- if (pipe_shader_type == PIPE_SHADER_FRAGMENT) {
- struct tgsi_shader_info info;
+ switch (pipe_shader_type) {
+ case PIPE_SHADER_GEOMETRY:
+ sel->gs_output_prim =
+ sel->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
+ sel->gs_max_out_vertices =
+ sel->info.properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES];
- tgsi_scan_shader(state->tokens, &info);
- sel->fs_write_all = info.color0_writes_all_cbufs;
- }
+ for (i = 0; i < sel->info.num_inputs; i++) {
+ unsigned name = sel->info.input_semantic_name[i];
+ unsigned index = sel->info.input_semantic_index[i];
- r = si_shader_select(ctx, sel);
- if (r) {
- free(sel);
- return NULL;
+ switch (name) {
+ case TGSI_SEMANTIC_PRIMID:
+ break;
+ default:
+ sel->gs_used_inputs |=
+ 1llu << si_shader_io_get_unique_index(name, index);
+ }
+ }
}
return sel;
struct si_context *sctx = (struct si_context *)ctx;
struct si_shader_selector *sel = state;
- if (sctx->vs_shader == sel)
- return;
-
- if (!sel || !sel->current)
+ if (sctx->vs_shader == sel || !sel)
return;
sctx->vs_shader = sel;
sctx->gs_shader = sel;
}
+void si_make_dummy_ps(struct si_context *sctx)
+{
+ if (!sctx->dummy_pixel_shader) {
+ sctx->dummy_pixel_shader =
+ util_make_fragment_cloneinput_shader(&sctx->b.b, 0,
+ TGSI_SEMANTIC_GENERIC,
+ TGSI_INTERPOLATE_CONSTANT);
+ }
+}
+
static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
{
struct si_context *sctx = (struct si_context *)ctx;
if (sctx->ps_shader == sel)
return;
- /* use dummy shader if supplied shader is corrupt */
- if (!sel || !sel->current) {
- if (!sctx->dummy_pixel_shader) {
- sctx->dummy_pixel_shader =
- util_make_fragment_cloneinput_shader(&sctx->b.b, 0,
- TGSI_SEMANTIC_GENERIC,
- TGSI_INTERPOLATE_CONSTANT);
- }
-
+ /* use a dummy shader if binding a NULL shader */
+ if (!sel) {
+ si_make_dummy_ps(sctx);
sel = sctx->dummy_pixel_shader;
}
while (p) {
c = p->next_variant;
- if (sel->type == PIPE_SHADER_GEOMETRY)
+ if (sel->type == PIPE_SHADER_GEOMETRY) {
si_pm4_delete_state(sctx, gs, p->pm4);
- else if (sel->type == PIPE_SHADER_FRAGMENT)
+ si_pm4_delete_state(sctx, vs, p->gs_copy_shader->pm4);
+ } else if (sel->type == PIPE_SHADER_FRAGMENT)
si_pm4_delete_state(sctx, ps, p->pm4);
else if (p->key.vs.as_es)
si_pm4_delete_state(sctx, es, p->pm4);
free(sel->tokens);
free(sel);
- }
+}
static void si_delete_vs_shader(struct pipe_context *ctx, void *state)
{
}
if (border_color_table) {
- struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
+ struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
uint64_t va_offset = sctx->border_color_table->gpu_address;
void si_init_config(struct si_context *sctx)
{
- struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
+ struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
if (pm4 == NULL)
return;