Remove the Surface9 code for dirty rects, used only for Managed
resources. Instead convey the information to the parent texture.
According to documentation, this seems to be the expected behaviour,
and if documentation is wrong there, that's not a problem since it can
only leads to more texture updates in corner cases.
Signed-off-by: Axel Davy <axel.davy@ens.fr>
tex->dirty_rect.x, tex->dirty_rect.y,
tex->dirty_rect.width, tex->dirty_rect.height);
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) {
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);
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;
}
}
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);
} else
if (This->base.type == D3DRTYPE_CUBETEXTURE) {
struct NineCubeTexture9 *tex = NineCubeTexture9(This);
tex->dirty_rect[z].width, tex->dirty_rect[z].height);
if (tex->dirty_rect[z].width) {
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);
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;
}
}
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) {
}
} else
if (This->base.type == D3DRTYPE_VOLUMETEXTURE) {
-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)
{
static INLINE void
rect_to_pipe_box_xy_only(struct pipe_box *dst, const RECT *src)
{
#include "surface9.h"
#include "device9.h"
#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"
#include "nine_helpers.h"
#include "nine_pipe.h"
{
if (This->transfer)
NineSurface9_UnlockRect(This);
{
if (This->transfer)
NineSurface9_UnlockRect(This);
- NineSurface9_ClearDirtyRects(This);
pipe_surface_reference(&This->surface[0], NULL);
pipe_surface_reference(&This->surface[1], NULL);
pipe_surface_reference(&This->surface[0], NULL);
pipe_surface_reference(&This->surface[1], NULL);
-/* 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 )
{
INLINE void
NineSurface9_AddDirtyRect( struct NineSurface9 *This,
const struct pipe_box *box )
{
- float area[2];
- struct u_rect rect, cover_a, cover_b;
DBG("This=%p box=%p\n", This, box);
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)
- }
- 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);
if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) {
NineSurface9_MarkContainerDirty(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);
(void *)NineSurface9_ReleaseDC
};
(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,
HRESULT
NineSurface9_CopySurface( struct NineSurface9 *This,
struct NineSurface9 *From,
* never have to do the reverse, i.e. download the surface.
*/
HRESULT
* 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;
{
struct pipe_context *pipe = This->pipe;
struct pipe_resource *res = This->base.resource;
uint8_t *ptr;
- DBG("This=%p\n", This);
+ DBG("This=%p damaged=%p\n", This, damaged);
assert(This->base.pool == D3DPOOL_MANAGED);
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);
uint8_t *data; /* system memory backing */
unsigned stride; /* for system memory backing */
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 )
};
static INLINE struct NineSurface9 *
NineSurface9( void *data )
NineSurface9_AddDirtyRect( struct NineSurface9 *This,
const struct pipe_box *box );
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));
-}
-
-NineSurface9_UploadSelf( struct NineSurface9 *This );
+NineSurface9_UploadSelf( struct NineSurface9 *This,
+ const struct pipe_box *damaged );
HRESULT
NineSurface9_CopySurface( struct NineSurface9 *This,
HRESULT
NineSurface9_CopySurface( struct NineSurface9 *This,