summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/nine')
-rw-r--r--src/gallium/state_trackers/nine/basetexture9.c15
-rw-r--r--src/gallium/state_trackers/nine/nine_pipe.h11
-rw-r--r--src/gallium/state_trackers/nine/surface9.c108
-rw-r--r--src/gallium/state_trackers/nine/surface9.h12
4 files changed, 53 insertions, 93 deletions
diff --git a/src/gallium/state_trackers/nine/basetexture9.c b/src/gallium/state_trackers/nine/basetexture9.c
index 75a305f099a..9b7976c3862 100644
--- a/src/gallium/state_trackers/nine/basetexture9.c
+++ b/src/gallium/state_trackers/nine/basetexture9.c
@@ -279,16 +279,17 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
tex->dirty_rect.x, tex->dirty_rect.y,
tex->dirty_rect.width, tex->dirty_rect.height);
+ /* Note: for l < This->managed.lod, the resource is
+ * non-existing, and thus will be entirely re-uploaded
+ * if This->managed.lod changes */
if (tex->dirty_rect.width) {
- for (l = 0; l <= last_level; ++l) {
+ for (l = This->managed.lod; l <= last_level; ++l) {
u_box_minify_2d(&box, &tex->dirty_rect, l);
- NineSurface9_AddDirtyRect(tex->surfaces[l], &box);
+ NineSurface9_UploadSelf(tex->surfaces[l], &box);
}
memset(&tex->dirty_rect, 0, sizeof(tex->dirty_rect));
tex->dirty_rect.depth = 1;
}
- for (l = This->managed.lod; l <= last_level; ++l)
- NineSurface9_UploadSelf(tex->surfaces[l]);
} else
if (This->base.type == D3DRTYPE_CUBETEXTURE) {
struct NineCubeTexture9 *tex = NineCubeTexture9(This);
@@ -303,15 +304,13 @@ NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
tex->dirty_rect[z].width, tex->dirty_rect[z].height);
if (tex->dirty_rect[z].width) {
- for (l = 0; l <= last_level; ++l) {
+ for (l = This->managed.lod; l <= last_level; ++l) {
u_box_minify_2d(&box, &tex->dirty_rect[z], l);
- NineSurface9_AddDirtyRect(tex->surfaces[l * 6 + z], &box);
+ NineSurface9_UploadSelf(tex->surfaces[l * 6 + z], &box);
}
memset(&tex->dirty_rect[z], 0, sizeof(tex->dirty_rect[z]));
tex->dirty_rect[z].depth = 1;
}
- for (l = This->managed.lod; l <= last_level; ++l)
- NineSurface9_UploadSelf(tex->surfaces[l * 6 + z]);
}
} else
if (This->base.type == D3DRTYPE_VOLUMETEXTURE) {
diff --git a/src/gallium/state_trackers/nine/nine_pipe.h b/src/gallium/state_trackers/nine/nine_pipe.h
index 1b88612f2cc..91da5630122 100644
--- a/src/gallium/state_trackers/nine/nine_pipe.h
+++ b/src/gallium/state_trackers/nine/nine_pipe.h
@@ -108,17 +108,6 @@ rect_to_pipe_box_flip(struct pipe_box *dst, const RECT *src)
}
static INLINE void
-nine_u_rect_to_pipe_box(struct pipe_box *dst, const struct u_rect *rect, int z)
-{
- dst->x = rect->x0;
- dst->y = rect->y0;
- dst->z = z;
- dst->width = rect->x1 - rect->x0;
- dst->height = rect->y1 - rect->y0;
- dst->depth = 1;
-}
-
-static INLINE void
rect_to_pipe_box_xy_only(struct pipe_box *dst, const RECT *src)
{
user_warn(src->left > src->right || src->top > src->bottom);
diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c
index 5c6b3bf2c3d..36e108dd48b 100644
--- a/src/gallium/state_trackers/nine/surface9.c
+++ b/src/gallium/state_trackers/nine/surface9.c
@@ -22,7 +22,11 @@
#include "surface9.h"
#include "device9.h"
-#include "basetexture9.h" /* for marking dirty */
+
+/* for marking dirty */
+#include "basetexture9.h"
+#include "texture9.h"
+#include "cubetexture9.h"
#include "nine_helpers.h"
#include "nine_pipe.h"
@@ -146,7 +150,6 @@ NineSurface9_dtor( struct NineSurface9 *This )
{
if (This->transfer)
NineSurface9_UnlockRect(This);
- NineSurface9_ClearDirtyRects(This);
pipe_surface_reference(&This->surface[0], NULL);
pipe_surface_reference(&This->surface[1], NULL);
@@ -257,55 +260,38 @@ NineSurface9_GetDesc( struct NineSurface9 *This,
return D3D_OK;
}
-/* Wine just keeps a single directy rect and expands it to cover all
- * the dirty rects ever added.
- * We'll keep 2, and expand the one that fits better, just for fun.
- */
+/* Add the dirty rects to the source texture */
INLINE void
NineSurface9_AddDirtyRect( struct NineSurface9 *This,
const struct pipe_box *box )
{
- float area[2];
- struct u_rect rect, cover_a, cover_b;
+ RECT dirty_rect;
DBG("This=%p box=%p\n", This, box);
- if (!box) {
- This->dirty_rects[0].x0 = 0;
- This->dirty_rects[0].y0 = 0;
- This->dirty_rects[0].x1 = This->desc.Width;
- This->dirty_rects[0].y1 = This->desc.Height;
+ assert (This->base.pool != D3DPOOL_MANAGED ||
+ This->texture == D3DRTYPE_CUBETEXTURE ||
+ This->texture == D3DRTYPE_TEXTURE);
- memset(&This->dirty_rects[1], 0, sizeof(This->dirty_rects[1]));
+ if (This->base.pool != D3DPOOL_MANAGED)
return;
- }
- rect.x0 = box->x;
- rect.y0 = box->y;
- rect.x1 = box->x + box->width;
- rect.y1 = box->y + box->height;
- if (This->dirty_rects[0].x1 == 0) {
- This->dirty_rects[0] = rect;
- return;
- }
+ /* Add a dirty rect to level 0 of the parent texture */
+ dirty_rect.left = box->x << This->level_actual;
+ dirty_rect.right = dirty_rect.left + (box->width << This->level_actual);
+ dirty_rect.top = box->y << This->level_actual;
+ dirty_rect.bottom = dirty_rect.top + (box->height << This->level_actual);
- u_rect_union(&cover_a, &This->dirty_rects[0], &rect);
- area[0] = u_rect_area(&cover_a);
+ if (This->texture == D3DRTYPE_TEXTURE) {
+ struct NineTexture9 *tex =
+ NineTexture9(This->base.base.container);
- if (This->dirty_rects[1].x1 == 0) {
- area[1] = u_rect_area(&This->dirty_rects[0]);
- if (area[0] > (area[1] * 1.25f))
- This->dirty_rects[1] = rect;
- else
- This->dirty_rects[0] = cover_a;
- } else {
- u_rect_union(&cover_b, &This->dirty_rects[1], &rect);
- area[1] = u_rect_area(&cover_b);
+ NineTexture9_AddDirtyRect(tex, &dirty_rect);
+ } else { /* This->texture == D3DRTYPE_CUBETEXTURE */
+ struct NineCubeTexture9 *ctex =
+ NineCubeTexture9(This->base.base.container);
- if (area[0] > area[1])
- This->dirty_rects[1] = cover_b;
- else
- This->dirty_rects[0] = cover_a;
+ NineCubeTexture9_AddDirtyRect(ctex, This->layer, &dirty_rect);
}
}
@@ -423,8 +409,7 @@ NineSurface9_LockRect( struct NineSurface9 *This,
if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) {
NineSurface9_MarkContainerDirty(This);
- if (This->base.pool == D3DPOOL_MANAGED)
- NineSurface9_AddDirtyRect(This, &box);
+ NineSurface9_AddDirtyRect(This, &box);
}
++This->lock_count;
@@ -478,13 +463,6 @@ IDirect3DSurface9Vtbl NineSurface9_vtable = {
(void *)NineSurface9_ReleaseDC
};
-
-static INLINE boolean
-NineSurface9_IsDirty(struct NineSurface9 *This)
-{
- return This->dirty_rects[0].x1 != 0;
-}
-
HRESULT
NineSurface9_CopySurface( struct NineSurface9 *This,
struct NineSurface9 *From,
@@ -623,33 +601,35 @@ NineSurface9_CopySurface( struct NineSurface9 *This,
* never have to do the reverse, i.e. download the surface.
*/
HRESULT
-NineSurface9_UploadSelf( struct NineSurface9 *This )
+NineSurface9_UploadSelf( struct NineSurface9 *This,
+ const struct pipe_box *damaged )
{
struct pipe_context *pipe = This->pipe;
struct pipe_resource *res = This->base.resource;
uint8_t *ptr;
- unsigned i;
+ struct pipe_box box;
- DBG("This=%p\n", This);
+ DBG("This=%p damaged=%p\n", This, damaged);
assert(This->base.pool == D3DPOOL_MANAGED);
- if (!NineSurface9_IsDirty(This))
- return D3D_OK;
-
- for (i = 0; i < Elements(This->dirty_rects); ++i) {
- struct pipe_box box;
- nine_u_rect_to_pipe_box(&box, &This->dirty_rects[i], This->layer);
+ if (damaged) {
+ box = *damaged;
+ box.z = This->layer;
+ box.depth = 1;
+ } else {
+ box.x = 0;
+ box.y = 0;
+ box.z = This->layer;
+ box.width = This->desc.Width;
+ box.height = This->desc.Height;
+ box.depth = 1;
+ }
- if (box.width == 0)
- break;
- ptr = NineSurface9_GetSystemMemPointer(This, box.x, box.y);
+ ptr = NineSurface9_GetSystemMemPointer(This, box.x, box.y);
- pipe->transfer_inline_write(pipe, res, This->level,
- 0,
- &box, ptr, This->stride, 0);
- }
- NineSurface9_ClearDirtyRects(This);
+ pipe->transfer_inline_write(pipe, res, This->level, 0,
+ &box, ptr, This->stride, 0);
return D3D_OK;
}
diff --git a/src/gallium/state_trackers/nine/surface9.h b/src/gallium/state_trackers/nine/surface9.h
index 7d6932a0f17..aa586f37e3c 100644
--- a/src/gallium/state_trackers/nine/surface9.h
+++ b/src/gallium/state_trackers/nine/surface9.h
@@ -49,9 +49,6 @@ struct NineSurface9
uint8_t *data; /* system memory backing */
unsigned stride; /* for system memory backing */
-
- /* wine doesn't even use these, 2 will be enough */
- struct u_rect dirty_rects[2];
};
static INLINE struct NineSurface9 *
NineSurface9( void *data )
@@ -121,14 +118,9 @@ void
NineSurface9_AddDirtyRect( struct NineSurface9 *This,
const struct pipe_box *box );
-static INLINE void
-NineSurface9_ClearDirtyRects( struct NineSurface9 *This )
-{
- memset(&This->dirty_rects, 0, sizeof(This->dirty_rects));
-}
-
HRESULT
-NineSurface9_UploadSelf( struct NineSurface9 *This );
+NineSurface9_UploadSelf( struct NineSurface9 *This,
+ const struct pipe_box *damaged );
HRESULT
NineSurface9_CopySurface( struct NineSurface9 *This,