#include "pipe/p_config.h"
#include "r300_context.h"
+#include "r300_emit.h"
#include "r300_reg.h"
#include "r300_screen.h"
#include "r300_screen_buffer.h"
+#include "r300_state.h"
#include "r300_state_inlines.h"
#include "r300_fs.h"
+#include "r300_texture.h"
#include "r300_vs.h"
#include "r300_winsys.h"
/* Enable reading from the colorbuffer. */
blend->blend_control |= R300_READ_ENABLE;
- if (r300_screen(r300_context(pipe)->context.screen)->caps->is_r500) {
+ if (r300screen->caps.is_r500) {
/* Optimization: Depending on incoming pixels, we can
* conditionally disable the reading in hardware... */
if (eqRGB != PIPE_BLEND_MIN && eqA != PIPE_BLEND_MIN &&
/* Color channel masks for all MRTs. */
blend->color_channel_mask = bgra_cmask(state->rt[0].colormask);
- if (r300screen->caps->is_r500 && state->independent_blend_enable) {
+ if (r300screen->caps.is_r500 && state->independent_blend_enable) {
if (state->rt[1].blend_enable) {
blend->color_channel_mask |= bgra_cmask(state->rt[1].colormask) << 4;
}
const struct pipe_blend_color* color)
{
struct r300_context* r300 = r300_context(pipe);
- struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_blend_color_state* state =
(struct r300_blend_color_state*)r300->blend_color_state.state;
union util_color uc;
float_to_fixed10(color->color[2]) |
(float_to_fixed10(color->color[1]) << 16);
- r300->blend_color_state.size = r300screen->caps->is_r500 ? 3 : 2;
+ r300->blend_color_state.size = r300->screen->caps.is_r500 ? 3 : 2;
r300->blend_color_state.dirty = TRUE;
}
r300->clip = *state;
- if (r300_screen(pipe->screen)->caps->has_tcl) {
+ if (r300->screen->caps.has_tcl) {
memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state));
r300->clip_state.size = 29;
} else {
r300_create_dsa_state(struct pipe_context* pipe,
const struct pipe_depth_stencil_alpha_state* state)
{
- struct r300_capabilities *caps =
- r300_screen(r300_context(pipe)->context.screen)->caps;
+ struct r300_capabilities *caps = &r300_screen(pipe->screen)->caps;
struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
/* Depth test setup. */
(state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
if (state->stencil[1].enabled) {
+ dsa->two_sided = TRUE;
+
dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
dsa->z_stencil_control |=
(r300_translate_depth_stencil_function(state->stencil[1].func) <<
(r300_translate_stencil_op(state->stencil[1].zfail_op) <<
R300_S_BACK_ZFAIL_OP_SHIFT);
- if (caps->is_r500)
- {
+ dsa->stencil_ref_bf =
+ (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |
+ (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);
+
+ if (caps->is_r500) {
dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
- dsa->stencil_ref_bf =
- (state->stencil[1].valuemask <<
- R300_STENCILMASK_SHIFT) |
- (state->stencil[1].writemask <<
- R300_STENCILWRITEMASK_SHIFT);
+ } else {
+ dsa->stencil_ref_bf_fallback =
+ (state->stencil[0].valuemask != state->stencil[1].valuemask ||
+ state->stencil[0].writemask != state->stencil[1].writemask);
}
}
}
return (void*)dsa;
}
+static void r300_update_stencil_ref_fallback_status(struct r300_context *r300)
+{
+ struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
+
+ if (r300->screen->caps.is_r500) {
+ return;
+ }
+
+ r300->stencil_ref_bf_fallback =
+ dsa->stencil_ref_bf_fallback ||
+ (dsa->two_sided &&
+ r300->stencil_ref.ref_value[0] != r300->stencil_ref.ref_value[1]);
+}
+
/* Bind DSA state. */
static void r300_bind_dsa_state(struct pipe_context* pipe,
void* state)
{
struct r300_context* r300 = r300_context(pipe);
+ if (!state) {
+ return;
+ }
+
UPDATE_STATE(state, r300->dsa_state);
+
+ r300_update_stencil_ref_fallback_status(r300);
}
/* Free DSA state. */
const struct pipe_stencil_ref* sr)
{
struct r300_context* r300 = r300_context(pipe);
+
r300->stencil_ref = *sr;
r300->dsa_state.dirty = TRUE;
+
+ r300_update_stencil_ref_fallback_status(r300);
}
/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
continue;
}
- tex = (struct r300_texture*)old_state->cbufs[i]->texture;
+ tex = r300_texture(old_state->cbufs[i]->texture);
if (tex) {
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
if (old_state->zsbuf &&
(!new_state->zsbuf ||
old_state->zsbuf->texture != new_state->zsbuf->texture)) {
- tex = (struct r300_texture*)old_state->zsbuf->texture;
+ tex = r300_texture(old_state->zsbuf->texture);
if (tex) {
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
/* Set tiling flags for new surfaces. */
for (i = 0; i < new_state->nr_cbufs; i++) {
- tex = (struct r300_texture*)new_state->cbufs[i]->texture;
+ tex = r300_texture(new_state->cbufs[i]->texture);
level = new_state->cbufs[i]->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->mip_macrotile[level]);
}
if (new_state->zsbuf) {
- tex = (struct r300_texture*)new_state->zsbuf->texture;
+ tex = r300_texture(new_state->zsbuf->texture);
level = new_state->zsbuf->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
- struct r300_screen* r300screen = r300_screen(pipe->screen);
struct pipe_framebuffer_state *old_state = r300->fb_state.state;
unsigned max_width, max_height;
uint32_t zbuffer_bpp = 0;
return;
}
- if (r300screen->caps->is_r500) {
+ if (r300->screen->caps.is_r500) {
max_width = max_height = 4096;
- } else if (r300screen->caps->is_r400) {
+ } else if (r300->screen->caps.is_r400) {
max_width = max_height = 4021;
} else {
max_width = max_height = 2560;
if (!!old_state->zsbuf != !!state->zsbuf) {
r300->dsa_state.dirty = TRUE;
}
- if (!r300->scissor_enabled) {
- r300->scissor_state.dirty = TRUE;
- }
r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
- (state->zsbuf ? 10 : 0) + 8;
+ (state->zsbuf ? 10 : 0) + 11;
/* Polygon offset depends on the zbuffer bit depth. */
if (state->zsbuf && r300->polygon_offset_enabled) {
fs->state = *shader;
fs->state.tokens = tgsi_dup_tokens(shader->tokens);
- tgsi_scan_shader(shader->tokens, &fs->info);
- r300_shader_read_fs_inputs(&fs->info, &fs->inputs);
-
return (void*)fs;
}
+void r300_mark_fs_code_dirty(struct r300_context *r300)
+{
+ struct r300_fragment_shader* fs = r300_fs(r300);
+
+ 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;
+ }
+}
+
/* Bind fragment shader state. */
static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
{
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
if (fs == NULL) {
- r300->fs = NULL;
+ r300->fs.state = NULL;
return;
}
- r300->fs = fs;
+ r300->fs.state = fs;
r300_pick_fragment_shader(r300);
+ r300_mark_fs_code_dirty(r300);
r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) {
r300->vap_output_state.dirty = TRUE;
}
-
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
/* Delete fragment shader state. */
static void* r300_create_rs_state(struct pipe_context* pipe,
const struct pipe_rasterizer_state* state)
{
- struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
+ int i;
/* Copy rasterizer state for Draw. */
rs->rs = *state;
#endif
/* If no TCL engine is present, turn off the HW TCL. */
- if (!r300screen->caps->has_tcl) {
+ if (!r300_screen(pipe->screen)->caps.has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
}
rs->color_control = R300_SHADE_MODEL_SMOOTH;
}
+ rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+
+ /* Point sprites */
+ if (state->sprite_coord_enable) {
+ rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE;
+ for (i = 0; i < 8; i++) {
+ if (state->sprite_coord_enable & (1 << i))
+ rs->stuffing_enable |=
+ R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2));
+ }
+
+ rs->point_texcoord_left = 0.0f;
+ rs->point_texcoord_right = 1.0f;
+
+ switch (state->sprite_coord_mode) {
+ case PIPE_SPRITE_COORD_UPPER_LEFT:
+ rs->point_texcoord_top = 0.0f;
+ rs->point_texcoord_bottom = 1.0f;
+ break;
+ case PIPE_SPRITE_COORD_LOWER_LEFT:
+ rs->point_texcoord_top = 1.0f;
+ rs->point_texcoord_bottom = 0.0f;
+ break;
+ }
+ }
+
return (void*)rs;
}
{
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
- boolean scissor_was_enabled = r300->scissor_enabled;
+ int last_sprite_coord_enable = r300->sprite_coord_enable;
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_rasterizer_state(r300->draw, &rs->rs);
+ draw_set_rasterizer_state(r300->draw, &rs->rs, state);
}
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
- r300->scissor_enabled = rs->rs.scissor;
+ r300->sprite_coord_enable = rs->rs.sprite_coord_enable;
} else {
r300->polygon_offset_enabled = FALSE;
- r300->scissor_enabled = FALSE;
+ r300->sprite_coord_enable = 0;
}
UPDATE_STATE(state, r300->rs_state);
- r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
+ r300->rs_state.size = 26 + (r300->polygon_offset_enabled ? 5 : 0);
- if (scissor_was_enabled != r300->scissor_enabled) {
- r300->scissor_state.dirty = TRUE;
+ if (last_sprite_coord_enable != r300->sprite_coord_enable) {
+ r300->rs_block_state.dirty = TRUE;
}
}
{
struct r300_context* r300 = r300_context(pipe);
struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
- boolean is_r500 = r300_screen(pipe->screen)->caps->is_r500;
+ boolean is_r500 = r300->screen->caps.is_r500;
int lod_bias;
union util_color uc;
sampler->border_color = uc.ui;
/* R500-specific fixups and optimizations */
- if (r300_screen(r300->context.screen)->caps->is_r500) {
+ if (r300->screen->caps.is_r500) {
sampler->filter1 |= R500_BORDER_FIX;
}
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
+ unsigned tex_units = r300->screen->caps.num_tex_units;
- if (count > 8) {
+ if (count > tex_units) {
return;
}
memcpy(state->sampler_states, states, sizeof(void*) * count);
- state->sampler_count = count;
+ state->sampler_state_count = count;
r300->textures_state.dirty = TRUE;
-
- /* Pick a fragment shader based on the texture compare state. */
- if (r300->fs && count) {
- if (r300_pick_fragment_shader(r300)) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER |
- R300_NEW_FRAGMENT_SHADER_CONSTANTS;
- }
- }
}
static void r300_lacks_vertex_textures(struct pipe_context* pipe,
(struct r300_textures_state*)r300->textures_state.state;
struct r300_texture *texture;
unsigned i;
- boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
+ unsigned tex_units = r300->screen->caps.num_tex_units;
boolean dirty_tex = FALSE;
- /* XXX magic num */
- if (count > 8) {
+ if (count > tex_units) {
return;
}
for (i = 0; i < count; i++) {
- if (state->fragment_sampler_views[i] != views[i]) {
- pipe_sampler_view_reference(&state->fragment_sampler_views[i],
- views[i]);
+ if (&state->sampler_views[i]->base != views[i]) {
+ pipe_sampler_view_reference(
+ (struct pipe_sampler_view**)&state->sampler_views[i],
+ views[i]);
if (!views[i]) {
continue;
/* A new sampler view (= texture)... */
dirty_tex = TRUE;
- /* R300-specific - set the texrect factor in the fragment shader */
- texture = (struct r300_texture *)views[i]->texture;
- if (!is_r500 && texture->uses_pitch) {
- /* XXX It would be nice to re-emit just 1 constant,
- * XXX not all of them */
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ /* Set the texrect factor in the fragment shader.
+ * Needed for RECT and NPOT fallback. */
+ texture = r300_texture(views[i]->texture);
+ if (texture->uses_pitch) {
+ r300->fs_rc_constant_state.dirty = TRUE;
}
}
}
- for (i = count; i < 8; i++) {
- if (state->fragment_sampler_views[i]) {
- pipe_sampler_view_reference(&state->fragment_sampler_views[i],
- NULL);
+ for (i = count; i < tex_units; i++) {
+ if (state->sampler_views[i]) {
+ pipe_sampler_view_reference(
+ (struct pipe_sampler_view**)&state->sampler_views[i],
+ NULL);
}
}
- state->texture_count = count;
+ state->sampler_view_count = count;
r300->textures_state.dirty = TRUE;
static struct pipe_sampler_view *
r300_create_sampler_view(struct pipe_context *pipe,
- struct pipe_texture *texture,
+ struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
- struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
-
- if (view) {
- *view = *templ;
- view->reference.count = 1;
- view->texture = NULL;
- pipe_texture_reference(&view->texture, texture);
- view->context = pipe;
- }
+ struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
+ struct r300_texture *tex = r300_texture(texture);
+ unsigned char swizzle[4];
+
+ if (view) {
+ view->base = *templ;
+ view->base.reference.count = 1;
+ view->base.context = pipe;
+ view->base.texture = NULL;
+ pipe_resource_reference(&view->base.texture, texture);
+
+ swizzle[0] = templ->swizzle_r;
+ swizzle[1] = templ->swizzle_g;
+ swizzle[2] = templ->swizzle_b;
+ swizzle[3] = templ->swizzle_a;
+
+ /* XXX Enable swizzles when they become supported. Now we get RGBA
+ * everywhere. And do testing! */
+ view->format = tex->tx_format;
+ view->format.format1 |= r300_translate_texformat(templ->format,
+ 0); /*swizzle);*/
+ if (r300_screen(pipe->screen)->caps.is_r500) {
+ view->format.format2 |= r500_tx_format_msb_bit(templ->format);
+ }
+ }
- return view;
+ return (struct pipe_sampler_view*)view;
}
static void
r300_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
- pipe_texture_reference(&view->texture, NULL);
+ pipe_resource_reference(&view->texture, NULL);
FREE(view);
}
memcpy(r300->scissor_state.state, state,
sizeof(struct pipe_scissor_state));
- if (r300->scissor_enabled) {
- r300->scissor_state.dirty = TRUE;
- }
+ r300->scissor_state.dirty = TRUE;
}
static void r300_set_viewport_state(struct pipe_context* pipe,
}
r300->viewport_state.dirty = TRUE;
- if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ if (r300->fs.state && r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) {
+ r300->fs_rc_constant_state.dirty = TRUE;
}
}
if (buffers[i].buffer) {
if (buffers[i].stride % 4 != 0) {
// XXX Shouldn't we align the buffer?
- fprintf(stderr, "r300_set_vertex_buffers: "
+ fprintf(stderr, "r300: set_vertex_buffers: "
"Unaligned buffer stride %i isn't supported.\n",
buffers[i].stride);
- assert(0);
abort();
}
}
vbo = (struct pipe_vertex_buffer*)&buffers[i];
/* Reference our buffer. */
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
+ pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
/* Skip NULL buffers */
if (!buffers[i].buffer) {
}
if (vbo->max_index == ~0) {
- /* Bogus value from broken state tracker; hax it. */
- vbo->max_index =
- (vbo->buffer->size - vbo->buffer_offset) / vbo->stride;
+ /* if no VBO stride then only one vertex value so max index is 1 */
+ /* should think about converting to VS constants like svga does */
+ if (!vbo->stride)
+ vbo->max_index = 1;
+ else
+ vbo->max_index =
+ (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
}
max_index = MIN2(vbo->max_index, max_index);
for (; i < r300->vertex_buffer_count; i++) {
/* Dereference any old buffers. */
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
+ pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
}
memcpy(r300->vertex_buffer, buffers,
enum pipe_format format;
unsigned i;
- assert(velems->count <= 16);
+ if (velems->count > 16) {
+ fprintf(stderr, "r300: More than 16 vertex elements are not supported,"
+ " requested %i, using 16.\n", velems->count);
+ velems->count = 16;
+ }
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
unsigned count,
const struct pipe_vertex_element* attribs)
{
- struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_vertex_element_state *velems;
unsigned i, size;
velems->count = count;
memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
- if (r300screen->caps->has_tcl) {
+ if (r300_screen(pipe->screen)->caps.has_tcl) {
/* Check if the format is aligned to the size of DWORD. */
for (i = 0; i < count; i++) {
size = util_format_get_blocksize(attribs[i].src_format);
struct r300_context* r300 = r300_context(pipe);
struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
- r300_vertex_shader_common_init(vs, shader);
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- r300_translate_vertex_shader(r300, vs);
+ /* Copy state directly into shader. */
+ vs->state = *shader;
+ vs->state.tokens = tgsi_dup_tokens(shader->tokens);
+
+ if (r300->screen->caps.has_tcl) {
+ r300_translate_vertex_shader(r300, vs, vs->state.tokens);
} else {
vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
}
r300->vs_state.state = vs;
// VS output mapping for HWTCL or stream mapping for SWTCL to the RS block
- if (r300->fs) {
+ if (r300->fs.state) {
r300_vertex_shader_setup_wpos(r300);
}
memcpy(r300->vap_output_state.state, &vs->vap_out,
/* The majority of the RS block bits is dependent on the vertex shader. */
r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
- if (r300_screen(pipe->screen)->caps->has_tcl) {
+ if (r300->screen->caps.has_tcl) {
r300->vs_state.dirty = TRUE;
- r300->vs_state.size = vs->code.length + 9;
+ r300->vs_state.size =
+ vs->code.length + 9 +
+ (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0);
- r300->pvs_flush.dirty = TRUE;
+ if (vs->externals_count) {
+ r300->vs_constants.dirty = TRUE;
+ r300->vs_constants.size = vs->externals_count * 4 + 3;
+ } else {
+ r300->vs_constants.size = 0;
+ }
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ r300->pvs_flush.dirty = TRUE;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
struct r300_context* r300 = r300_context(pipe);
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
- if (r300_screen(pipe->screen)->caps->has_tcl) {
+ if (r300->screen->caps.has_tcl) {
rc_constants_destroy(&vs->code.constants);
} else {
draw_delete_vertex_shader(r300->draw,
static void r300_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_resource *buf)
{
struct r300_context* r300 = r300_context(pipe);
- struct r300_screen *r300screen = r300_screen(pipe->screen);
+ struct r300_constant_buffer *cbuf;
+ struct pipe_transfer *tr;
void *mapped;
int max_size = 0;
- if (buf == NULL || buf->size == 0 ||
- (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL)
- {
- r300->shader_constants[shader].count = 0;
- return;
- }
-
- assert((buf->size % 4 * sizeof(float)) == 0);
-
- /* Check the size of the constant buffer. */
switch (shader) {
case PIPE_SHADER_VERTEX:
+ cbuf = (struct r300_constant_buffer*)r300->vs_constants.state;
max_size = 256;
break;
case PIPE_SHADER_FRAGMENT:
- if (r300screen->caps->is_r500) {
+ cbuf = (struct r300_constant_buffer*)r300->fs_constants.state;
+ if (r300->screen->caps.is_r500) {
max_size = 256;
- /* XXX Implement emission of r400's extended constant buffer. */
- /*} else if (r300screen->caps->is_r400) {
- max_size = 64;*/
} else {
max_size = 32;
}
break;
default:
assert(0);
+ return;
+ }
+
+ 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->size > (sizeof(float) * 4 * max_size)) {
+ if (buf->width0 > (sizeof(float) * 4 * max_size)) {
fprintf(stderr, "r300: Max size of the constant buffer is "
"%i*4 floats.\n", max_size);
abort();
}
- memcpy(r300->shader_constants[shader].constants, mapped, buf->size);
- r300->shader_constants[shader].count = buf->size / (4 * sizeof(float));
- pipe_buffer_unmap(pipe->screen, buf);
+ memcpy(cbuf->constants, mapped, buf->width0);
+ cbuf->count = buf->width0 / (4 * sizeof(float));
+ pipe_buffer_unmap(pipe, buf, tr);
if (shader == PIPE_SHADER_VERTEX) {
- if (r300screen->caps->has_tcl) {
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ if (r300->screen->caps.has_tcl) {
+ if (r300->vs_constants.size) {
+ r300->vs_constants.dirty = TRUE;
+ }
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,
- buf->size);
+ 0, cbuf->constants,
+ buf->width0);
}
} else if (shader == PIPE_SHADER_FRAGMENT) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ r300->fs_constants.dirty = TRUE;
}
}