r600g: implement fragment and vertex color clamp
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=38440 Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
This commit is contained in:
parent
d81126b714
commit
eafd331cf3
|
@ -256,6 +256,8 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
rstate = &rs->rstate;
|
rstate = &rs->rstate;
|
||||||
|
rs->clamp_vertex_color = state->clamp_vertex_color;
|
||||||
|
rs->clamp_fragment_color = state->clamp_fragment_color;
|
||||||
rs->flatshade = state->flatshade;
|
rs->flatshade = state->flatshade;
|
||||||
rs->sprite_coord_enable = state->sprite_coord_enable;
|
rs->sprite_coord_enable = state->sprite_coord_enable;
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
||||||
case PIPE_CAP_SM3:
|
case PIPE_CAP_SM3:
|
||||||
case PIPE_CAP_SEAMLESS_CUBE_MAP:
|
case PIPE_CAP_SEAMLESS_CUBE_MAP:
|
||||||
|
case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Supported except the original R600. */
|
/* Supported except the original R600. */
|
||||||
|
@ -392,7 +393,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
||||||
/* Unsupported features. */
|
/* Unsupported features. */
|
||||||
case PIPE_CAP_STREAM_OUTPUT:
|
case PIPE_CAP_STREAM_OUTPUT:
|
||||||
case PIPE_CAP_PRIMITIVE_RESTART:
|
case PIPE_CAP_PRIMITIVE_RESTART:
|
||||||
case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
|
|
||||||
case PIPE_CAP_TGSI_INSTANCEID:
|
case PIPE_CAP_TGSI_INSTANCEID:
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||||
|
|
|
@ -88,6 +88,8 @@ struct r600_pipe_sampler_view {
|
||||||
|
|
||||||
struct r600_pipe_rasterizer {
|
struct r600_pipe_rasterizer {
|
||||||
struct r600_pipe_state rstate;
|
struct r600_pipe_state rstate;
|
||||||
|
boolean clamp_vertex_color;
|
||||||
|
boolean clamp_fragment_color;
|
||||||
boolean flatshade;
|
boolean flatshade;
|
||||||
unsigned sprite_coord_enable;
|
unsigned sprite_coord_enable;
|
||||||
float offset_units;
|
float offset_units;
|
||||||
|
@ -125,6 +127,7 @@ struct r600_pipe_shader {
|
||||||
struct r600_bo *bo;
|
struct r600_bo *bo;
|
||||||
struct r600_bo *bo_fetch;
|
struct r600_bo *bo_fetch;
|
||||||
struct r600_vertex_element vertex_elements;
|
struct r600_vertex_element vertex_elements;
|
||||||
|
struct tgsi_token *tokens;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct r600_pipe_sampler_state {
|
struct r600_pipe_sampler_state {
|
||||||
|
@ -202,6 +205,8 @@ struct r600_pipe_context {
|
||||||
struct pipe_query *saved_render_cond;
|
struct pipe_query *saved_render_cond;
|
||||||
unsigned saved_render_cond_mode;
|
unsigned saved_render_cond_mode;
|
||||||
/* shader information */
|
/* shader information */
|
||||||
|
boolean clamp_vertex_color;
|
||||||
|
boolean clamp_fragment_color;
|
||||||
boolean spi_dirty;
|
boolean spi_dirty;
|
||||||
unsigned sprite_coord_enable;
|
unsigned sprite_coord_enable;
|
||||||
boolean flatshade;
|
boolean flatshade;
|
||||||
|
@ -265,7 +270,7 @@ void r600_init_query_functions(struct r600_pipe_context *rctx);
|
||||||
void r600_init_context_resource_functions(struct r600_pipe_context *r600);
|
void r600_init_context_resource_functions(struct r600_pipe_context *r600);
|
||||||
|
|
||||||
/* r600_shader.c */
|
/* r600_shader.c */
|
||||||
int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens);
|
int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader);
|
||||||
void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader);
|
void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader);
|
||||||
int r600_find_vs_semantic_index(struct r600_shader *vs,
|
int r600_find_vs_semantic_index(struct r600_shader *vs,
|
||||||
struct r600_shader *ps, int id);
|
struct r600_shader *ps, int id);
|
||||||
|
|
|
@ -118,9 +118,9 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
|
static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pipe_shader *pipeshader);
|
||||||
|
|
||||||
int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens)
|
int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader)
|
||||||
{
|
{
|
||||||
static int dump_shaders = -1;
|
static int dump_shaders = -1;
|
||||||
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
||||||
|
@ -133,10 +133,10 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s
|
||||||
|
|
||||||
if (dump_shaders) {
|
if (dump_shaders) {
|
||||||
fprintf(stderr, "--------------------------------------------------------------\n");
|
fprintf(stderr, "--------------------------------------------------------------\n");
|
||||||
tgsi_dump(tokens, 0);
|
tgsi_dump(shader->tokens, 0);
|
||||||
}
|
}
|
||||||
shader->shader.family = r600_get_family(rctx->radeon);
|
shader->shader.family = r600_get_family(rctx->radeon);
|
||||||
r = r600_shader_from_tgsi(tokens, &shader->shader);
|
r = r600_shader_from_tgsi(rctx, shader);
|
||||||
if (r) {
|
if (r) {
|
||||||
R600_ERR("translation from TGSI failed !\n");
|
R600_ERR("translation from TGSI failed !\n");
|
||||||
return r;
|
return r;
|
||||||
|
@ -159,6 +159,8 @@ void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader
|
||||||
|
|
||||||
r600_bo_reference(rctx->radeon, &shader->bo, NULL);
|
r600_bo_reference(rctx->radeon, &shader->bo, NULL);
|
||||||
r600_bc_clear(&shader->shader.bc);
|
r600_bc_clear(&shader->shader.bc);
|
||||||
|
|
||||||
|
memset(&shader->shader,0,sizeof(struct r600_shader));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -594,8 +596,10 @@ static int tgsi_split_literal_constant(struct r600_shader_ctx *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader)
|
static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pipe_shader *pipeshader)
|
||||||
{
|
{
|
||||||
|
struct r600_shader *shader = &pipeshader->shader;
|
||||||
|
struct tgsi_token *tokens = pipeshader->tokens;
|
||||||
struct tgsi_full_immediate *immediate;
|
struct tgsi_full_immediate *immediate;
|
||||||
struct tgsi_full_property *property;
|
struct tgsi_full_property *property;
|
||||||
struct r600_shader_ctx ctx;
|
struct r600_shader_ctx ctx;
|
||||||
|
@ -616,6 +620,9 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
|
||||||
shader->processor_type = ctx.type;
|
shader->processor_type = ctx.type;
|
||||||
ctx.bc->type = shader->processor_type;
|
ctx.bc->type = shader->processor_type;
|
||||||
|
|
||||||
|
shader->clamp_color = (((ctx.type == TGSI_PROCESSOR_FRAGMENT) && rctx->clamp_fragment_color) ||
|
||||||
|
((ctx.type == TGSI_PROCESSOR_VERTEX) && rctx->clamp_vertex_color));
|
||||||
|
|
||||||
/* register allocations */
|
/* register allocations */
|
||||||
/* Values [0,127] correspond to GPR[0..127].
|
/* Values [0,127] correspond to GPR[0..127].
|
||||||
* Values [128,159] correspond to constant buffer bank 0
|
* Values [128,159] correspond to constant buffer bank 0
|
||||||
|
@ -725,8 +732,41 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* export output */
|
|
||||||
noutput = shader->noutput;
|
noutput = shader->noutput;
|
||||||
|
|
||||||
|
/* clamp color outputs */
|
||||||
|
if (shader->clamp_color) {
|
||||||
|
for (i = 0; i < noutput; i++) {
|
||||||
|
if (shader->output[i].name == TGSI_SEMANTIC_COLOR ||
|
||||||
|
shader->output[i].name == TGSI_SEMANTIC_BCOLOR) {
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
struct r600_bc_alu alu;
|
||||||
|
memset(&alu, 0, sizeof(struct r600_bc_alu));
|
||||||
|
|
||||||
|
/* MOV_SAT R, R */
|
||||||
|
alu.inst = BC_INST(ctx.bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
|
||||||
|
alu.dst.sel = shader->output[i].gpr;
|
||||||
|
alu.dst.chan = j;
|
||||||
|
alu.dst.write = 1;
|
||||||
|
alu.dst.clamp = 1;
|
||||||
|
alu.src[0].sel = alu.dst.sel;
|
||||||
|
alu.src[0].chan = j;
|
||||||
|
|
||||||
|
if (j == 3) {
|
||||||
|
alu.last = 1;
|
||||||
|
}
|
||||||
|
r = r600_bc_add_alu(ctx.bc, &alu);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* export output */
|
||||||
for (i = 0, pos0 = 0; i < noutput; i++) {
|
for (i = 0, pos0 = 0; i < noutput; i++) {
|
||||||
memset(&output[i], 0, sizeof(struct r600_bc_output));
|
memset(&output[i], 0, sizeof(struct r600_bc_output));
|
||||||
output[i].gpr = shader->output[i].gpr;
|
output[i].gpr = shader->output[i].gpr;
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct r600_shader {
|
||||||
enum radeon_family family;
|
enum radeon_family family;
|
||||||
boolean uses_kill;
|
boolean uses_kill;
|
||||||
boolean fs_write_all;
|
boolean fs_write_all;
|
||||||
|
boolean clamp_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -299,6 +299,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
rstate = &rs->rstate;
|
rstate = &rs->rstate;
|
||||||
|
rs->clamp_vertex_color = state->clamp_vertex_color;
|
||||||
|
rs->clamp_fragment_color = state->clamp_fragment_color;
|
||||||
rs->flatshade = state->flatshade;
|
rs->flatshade = state->flatshade;
|
||||||
rs->sprite_coord_enable = state->sprite_coord_enable;
|
rs->sprite_coord_enable = state->sprite_coord_enable;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <util/u_format.h>
|
#include <util/u_format.h>
|
||||||
#include <pipebuffer/pb_buffer.h>
|
#include <pipebuffer/pb_buffer.h>
|
||||||
#include "pipe/p_shader_tokens.h"
|
#include "pipe/p_shader_tokens.h"
|
||||||
|
#include "tgsi/tgsi_parse.h"
|
||||||
#include "r600_formats.h"
|
#include "r600_formats.h"
|
||||||
#include "r600_pipe.h"
|
#include "r600_pipe.h"
|
||||||
#include "r600d.h"
|
#include "r600d.h"
|
||||||
|
@ -99,6 +100,8 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
rctx->clamp_vertex_color = rs->clamp_vertex_color;
|
||||||
|
rctx->clamp_fragment_color = rs->clamp_fragment_color;
|
||||||
rctx->flatshade = rs->flatshade;
|
rctx->flatshade = rs->flatshade;
|
||||||
rctx->sprite_coord_enable = rs->sprite_coord_enable;
|
rctx->sprite_coord_enable = rs->sprite_coord_enable;
|
||||||
rctx->rasterizer = rs;
|
rctx->rasterizer = rs;
|
||||||
|
@ -257,7 +260,9 @@ void *r600_create_shader_state(struct pipe_context *ctx,
|
||||||
struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader);
|
struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = r600_pipe_shader_create(ctx, shader, state->tokens);
|
shader->tokens = tgsi_dup_tokens(state->tokens);
|
||||||
|
|
||||||
|
r = r600_pipe_shader_create(ctx, shader);
|
||||||
if (r) {
|
if (r) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -303,6 +308,7 @@ void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
|
||||||
rctx->ps_shader = NULL;
|
rctx->ps_shader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(shader->tokens);
|
||||||
r600_pipe_shader_destroy(ctx, shader);
|
r600_pipe_shader_destroy(ctx, shader);
|
||||||
free(shader);
|
free(shader);
|
||||||
}
|
}
|
||||||
|
@ -316,6 +322,7 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state)
|
||||||
rctx->vs_shader = NULL;
|
rctx->vs_shader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(shader->tokens);
|
||||||
r600_pipe_shader_destroy(ctx, shader);
|
r600_pipe_shader_destroy(ctx, shader);
|
||||||
free(shader);
|
free(shader);
|
||||||
}
|
}
|
||||||
|
@ -531,6 +538,21 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader)
|
||||||
|
{
|
||||||
|
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r600_pipe_shader_destroy(ctx, shader);
|
||||||
|
r = r600_pipe_shader_create(ctx, shader);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
r600_context_pipe_state_set(&rctx->ctx, &shader->rstate);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
|
void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
|
||||||
{
|
{
|
||||||
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
||||||
|
@ -574,6 +596,12 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
|
||||||
if (r600_conv_pipe_prim(draw.info.mode, &prim))
|
if (r600_conv_pipe_prim(draw.info.mode, &prim))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color)
|
||||||
|
r600_shader_rebuild(ctx, rctx->vs_shader);
|
||||||
|
|
||||||
|
if (rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color)
|
||||||
|
r600_shader_rebuild(ctx, rctx->ps_shader);
|
||||||
|
|
||||||
if (rctx->spi_dirty)
|
if (rctx->spi_dirty)
|
||||||
r600_spi_update(rctx);
|
r600_spi_update(rctx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue