#include "r300_blit.h"
#include "r300_context.h"
+#include "r300_texture.h"
-#include "util/u_rect.h"
+#include "util/u_format.h"
static void r300_blitter_save_states(struct r300_context* r300)
{
util_blitter_save_blend(r300->blitter, r300->blend_state.state);
util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state);
+ util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref));
util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state);
- util_blitter_save_fragment_shader(r300->blitter, r300->fs);
- util_blitter_save_vertex_shader(r300->blitter, r300->vs);
+ util_blitter_save_fragment_shader(r300->blitter, r300->fs.state);
+ util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
+ util_blitter_save_viewport(r300->blitter, &r300->viewport);
+ util_blitter_save_clip(r300->blitter, &r300->clip);
+ util_blitter_save_vertex_elements(r300->blitter, r300->velems);
}
/* Clear currently bound buffers. */
*/
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_framebuffer_state* fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
r300_blitter_save_states(r300);
util_blitter_clear(r300->blitter,
- r300->framebuffer_state.width,
- r300->framebuffer_state.height,
- r300->framebuffer_state.nr_cbufs,
+ fb->width,
+ fb->height,
+ fb->nr_cbufs,
buffers, rgba, depth, stencil);
}
-/* Copy a block of pixels from one surface to another. */
-void r300_surface_copy(struct pipe_context* pipe,
- struct pipe_surface* dst,
- unsigned dstx, unsigned dsty,
- struct pipe_surface* src,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
+/* Copy a block of pixels from one surface to another using HW. */
+static void r300_hw_copy(struct pipe_context* pipe,
+ struct pipe_surface* dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface* src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_textures_state* state =
+ (struct r300_textures_state*)r300->textures_state.state;
/* Yeah we have to save all those states to ensure this blitter operation
* is really transparent. The states will be restored by the blitter once
* copying is done. */
r300_blitter_save_states(r300);
- util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+ util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
util_blitter_save_fragment_sampler_states(
- r300->blitter, r300->sampler_count, (void**)r300->sampler_states);
+ r300->blitter, state->sampler_state_count,
+ (void**)state->sampler_states);
- util_blitter_save_fragment_sampler_textures(
- r300->blitter, r300->texture_count,
- (struct pipe_texture**)r300->textures);
+ util_blitter_save_fragment_sampler_views(
+ r300->blitter, state->sampler_view_count,
+ (struct pipe_sampler_view**)state->sampler_views);
/* Do a copy */
util_blitter_copy(r300->blitter,
dst, dstx, dsty, src, srcx, srcy, width, height, TRUE);
}
+/* Copy a block of pixels from one surface to another. */
+void r300_surface_copy(struct pipe_context* pipe,
+ struct pipe_surface* dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface* src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
+{
+ enum pipe_format old_format = dst->texture->format;
+ enum pipe_format new_format = old_format;
+
+ assert(dst->texture->format == src->texture->format);
+
+ if (!pipe->screen->is_format_supported(pipe->screen,
+ old_format, src->texture->target,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW, 0)) {
+ switch (util_format_get_blocksize(old_format)) {
+ case 1:
+ new_format = PIPE_FORMAT_I8_UNORM;
+ break;
+ case 2:
+ new_format = PIPE_FORMAT_B4G4R4A4_UNORM;
+ break;
+ case 4:
+ new_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ case 8:
+ new_format = PIPE_FORMAT_R16G16B16A16_UNORM;
+ break;
+ default:
+ debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
+ "r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
+ util_format_name(old_format));
+ }
+ }
+
+ if (old_format != new_format) {
+ dst->format = new_format;
+ src->format = new_format;
+
+ r300_texture_reinterpret_format(pipe->screen,
+ dst->texture, new_format);
+ r300_texture_reinterpret_format(pipe->screen,
+ src->texture, new_format);
+ }
+
+ r300_hw_copy(pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
+
+ if (old_format != new_format) {
+ dst->format = old_format;
+ src->format = old_format;
+
+ r300_texture_reinterpret_format(pipe->screen,
+ dst->texture, old_format);
+ r300_texture_reinterpret_format(pipe->screen,
+ src->texture, old_format);
+ }
+}
+
/* Fill a region of a surface with a constant value. */
void r300_surface_fill(struct pipe_context* pipe,
struct pipe_surface* dst,
struct r300_context* r300 = r300_context(pipe);
r300_blitter_save_states(r300);
- util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+ util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
util_blitter_fill(r300->blitter,
dst, dstx, dsty, width, height, value);