FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
+ FREE(r300->fs_constants.state);
FREE(r300);
}
R300_INIT_ATOM(textures_state, 0);
R300_INIT_ATOM(fs, 0);
R300_INIT_ATOM(fs_rc_constant_state, 0);
+ R300_INIT_ATOM(fs_constants, 0);
/* Replace emission functions for r500. */
if (r300->screen->caps.is_r500) {
r300->fs.emit = r500_emit_fs;
r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state;
+ r300->fs_constants.emit = r500_emit_fs_constants;
}
/* Some non-CSO atoms need explicit space to store the state locally. */
r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
+ r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
}
struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct r300_atom fs;
/* Fragment shader RC_CONSTANT_STATE variables. */
struct r300_atom fs_rc_constant_state;
+ /* Fragment shader constant buffer. */
+ struct r300_atom fs_constants;
/* Framebuffer state. */
struct r300_atom fb_state;
/* Rasterizer state. */
#define R300_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV
/* Non-atom dirty state flags. */
-#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
#define R300_NEW_QUERY 0x40000000
#define R300_NEW_KITCHEN_SINK 0x7fffffff
END_CS;
}
-void r300_emit_fs_constant_buffer(struct r300_context* r300,
- struct rc_constant_list* constants)
+void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state)
{
struct r300_fragment_shader *fs = r300_fs(r300);
+ struct rc_constant_list *constants = &fs->shader->code.constants;
+ struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
unsigned i, count = fs->shader->externals_count;
CS_LOCALS(r300);
if (count == 0)
return;
- BEGIN_CS(count * 4 + 1);
+ BEGIN_CS(size);
OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4);
for(i = 0; i < count; ++i) {
assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL);
- const float *data =
- r300->shader_constants[PIPE_SHADER_FRAGMENT].constants[i];
+ const float *data = buf->constants[i];
OUT_CS(pack_float24(data[0]));
OUT_CS(pack_float24(data[1]));
OUT_CS(pack_float24(data[2]));
END_CS;
}
-void r500_emit_fs_constant_buffer(struct r300_context* r300,
- struct rc_constant_list* constants)
+void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state)
{
struct r300_fragment_shader *fs = r300_fs(r300);
+ struct rc_constant_list *constants = &fs->shader->code.constants;
+ struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
unsigned i, count = fs->shader->externals_count;
CS_LOCALS(r300);
OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count * 4);
for(i = 0; i < count; ++i) {
assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL);
- const float *data =
- r300->shader_constants[PIPE_SHADER_FRAGMENT].constants[i];
+ const float *data = buf->constants[i];
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
}
}
- if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
- if (r300screen->caps.is_r500) {
- r500_emit_fs_constant_buffer(r300,
- &r300_fs(r300)->shader->code.constants);
- } else {
- r300_emit_fs_constant_buffer(r300,
- &r300_fs(r300)->shader->code.constants);
- }
- r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
- }
-
if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
struct r300_vertex_shader* vs = r300->vs_state.state;
if (vs->code.constants.Count) {
void r300_emit_fs(struct r300_context* r300, unsigned size, void *state);
-void r300_emit_fs_constant_buffer(struct r300_context* r300,
- struct rc_constant_list* constants);
+void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state);
void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state);
void r500_emit_fs(struct r300_context* r300, unsigned size, void *state);
-void r500_emit_fs_constant_buffer(struct r300_context* r300,
- struct rc_constant_list* constants);
+void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state);
void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state);
r300->fs.dirty = TRUE;
r300->fs_rc_constant_state.dirty = TRUE;
+ r300->fs_constants.dirty = TRUE;
if (r300->screen->caps.is_r500) {
r300->fs.size = r500_get_fs_atom_size(r300);
r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 7;
+ r300->fs_constants.size = fs->shader->externals_count * 4 + 3;
} else {
r300->fs.size = r300_get_fs_atom_size(r300);
r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 5;
+ r300->fs_constants.size = fs->shader->externals_count * 4 + 1;
}
-
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
/* Bind fragment shader state. */
struct pipe_resource *buf)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_constant_buffer *cbuf;
struct pipe_transfer *tr;
void *mapped;
int max_size = 0;
- if (buf == NULL || buf->width0 == 0 ||
- (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
- {
- r300->shader_constants[shader].count = 0;
- return;
- }
-
- assert((buf->width0 % 4 * sizeof(float)) == 0);
-
- /* Check the size of the constant buffer. */
switch (shader) {
case PIPE_SHADER_VERTEX:
+ cbuf = &r300->shader_constants[PIPE_SHADER_VERTEX];
max_size = 256;
break;
case PIPE_SHADER_FRAGMENT:
+ cbuf = (struct r300_constant_buffer*)r300->fs_constants.state;
if (r300->screen->caps.is_r500) {
max_size = 256;
} else {
assert(0);
}
+ if (buf == NULL || buf->width0 == 0 ||
+ (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
+ {
+ cbuf->count = 0;
+ return;
+ }
+
+ assert((buf->width0 % 4 * sizeof(float)) == 0);
+
+ /* Check the size of the constant buffer. */
/* XXX Subtract immediates and RC_STATE_* variables. */
if (buf->width0 > (sizeof(float) * 4 * max_size)) {
fprintf(stderr, "r300: Max size of the constant buffer is "
abort();
}
- memcpy(r300->shader_constants[shader].constants, mapped, buf->width0);
- r300->shader_constants[shader].count = buf->width0 / (4 * sizeof(float));
+ memcpy(cbuf->constants, mapped, buf->width0);
+ cbuf->count = buf->width0 / (4 * sizeof(float));
pipe_buffer_unmap(pipe, buf, tr);
if (shader == PIPE_SHADER_VERTEX) {
r300->pvs_flush.dirty = TRUE;
} else if (r300->draw) {
draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
- 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+ 0, cbuf->constants,
buf->width0);
}
} else if (shader == PIPE_SHADER_FRAGMENT) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ r300->fs_constants.dirty = TRUE;
}
}