Skip to main content
clarify alignment constraints
Source Link
Lars Viklund
  • 4.1k
  • 1
  • 19
  • 23

There's three members of a D3D11_MAPPED_SUBRESOURCE:

  1. a pointer to the beginning of the data;
  2. the number of bytes from the beginning of one row of data to the next row of data;
  3. the number of bytes from the beginning of one depth slice of data to the next depth slice of data.

As none of these members communicate anything about the actual extents of a row of data, you need to query your texture resource for a DESC or remember the column and row counts from when you created it.

The 2D layout of the data is such that there are solid rows of data with the potential of padding at the end. The row pitch in the mapping indicate the offsets you need to use to jump between rows.

Assuming you know those quantities, you would iterate your mapped data similiar to this:

{
    uint32_t partialSum = 0u;
    // Point at the beginning of the first row
    BYTE const* rowPtr = msr.pData;
    for (size_t row = 0u; row < rows; ++row) {
        // Take the current row pointer and interpret as sequence of U32
        uint32_t const* p = reinterpret_cast<uint32_t const*>(rowPtr);
        for (size_t col = 0u; col < cols; ++col) {
            partialSum += *p;
            // Advance one U32
            ++p;
        }
        // Advance the row pointer to the beginning of the next row
        rowPtr += msr.RowPitch;
    }
}

The in-place reinterpret of the data is fine as feature levels 10_0 and up guarantee 16-byte alignment of mappings, and feature levels below guarantee 4-byte alignment, which is enough for U32. If this would not be the case, a byte-wise copy would have to be made into a properly aligned value on the CPU side before touching it.

There's three members of a D3D11_MAPPED_SUBRESOURCE:

  1. a pointer to the beginning of the data;
  2. the number of bytes from the beginning of one row of data to the next row of data;
  3. the number of bytes from the beginning of one depth slice of data to the next depth slice of data.

As none of these members communicate anything about the actual extents of a row of data, you need to query your texture resource for a DESC or remember the column and row counts from when you created it.

The 2D layout of the data is such that there are solid rows of data with the potential of padding at the end. The row pitch in the mapping indicate the offsets you need to use to jump between rows.

Assuming you know those quantities, you would iterate your mapped data similiar to this:

{
    uint32_t partialSum = 0u;
    // Point at the beginning of the first row
    BYTE const* rowPtr = msr.pData;
    for (size_t row = 0u; row < rows; ++row) {
        // Take the current row pointer and interpret as sequence of U32
        uint32_t const* p = reinterpret_cast<uint32_t const*>(rowPtr);
        for (size_t col = 0u; col < cols; ++col) {
            partialSum += *p;
            // Advance one U32
            ++p;
        }
        // Advance the row pointer to the beginning of the next row
        rowPtr += msr.RowPitch;
    }
}

There's three members of a D3D11_MAPPED_SUBRESOURCE:

  1. a pointer to the beginning of the data;
  2. the number of bytes from the beginning of one row of data to the next row of data;
  3. the number of bytes from the beginning of one depth slice of data to the next depth slice of data.

As none of these members communicate anything about the actual extents of a row of data, you need to query your texture resource for a DESC or remember the column and row counts from when you created it.

The 2D layout of the data is such that there are solid rows of data with the potential of padding at the end. The row pitch in the mapping indicate the offsets you need to use to jump between rows.

Assuming you know those quantities, you would iterate your mapped data similiar to this:

{
    uint32_t partialSum = 0u;
    // Point at the beginning of the first row
    BYTE const* rowPtr = msr.pData;
    for (size_t row = 0u; row < rows; ++row) {
        // Take the current row pointer and interpret as sequence of U32
        uint32_t const* p = reinterpret_cast<uint32_t const*>(rowPtr);
        for (size_t col = 0u; col < cols; ++col) {
            partialSum += *p;
            // Advance one U32
            ++p;
        }
        // Advance the row pointer to the beginning of the next row
        rowPtr += msr.RowPitch;
    }
}

The in-place reinterpret of the data is fine as feature levels 10_0 and up guarantee 16-byte alignment of mappings, and feature levels below guarantee 4-byte alignment, which is enough for U32. If this would not be the case, a byte-wise copy would have to be made into a properly aligned value on the CPU side before touching it.

reinterpreted answer based on actual question
Source Link
Lars Viklund
  • 4.1k
  • 1
  • 19
  • 23

There's three members of a sizeof(T*)D3D11_MAPPED_SUBRESOURCE is:

  1. a pointer to the beginning of the data;
  2. the number of bytes from the beginning of one row of data to the next row of data;
  3. the number of bytes from the beginning of one depth slice of data to the next depth slice of data.

As none of these members communicate anything about the sizeactual extents of a pointerrow of data, notyou need to query your texture resource for a DESC or remember the size of whatever sequence of objectscolumn and row counts from when you created it points to.

If you wantThe 2D layout of the numberdata is such that there are solid rows of elementsdata with the potential of an array, either use a macropadding at the place where it's still an array,end. The row pitch in the mapping indicate the offsets you need to use a more friendly array type (std::array)to jump between rows.

Assuming you know those quantities, or template ityou would iterate your mapped data similiar to this:

template{
 <typename T, size_t N>uint32_t partialSum = 0u;
size_t array_count   // Point at the beginning of the first row
    BYTE const* rowPtr = msr.pData;
    for (Tsize_t constrow = 0u; row < rows; ++row) {
        // Take the current row pointer and interpret as sequence of U32
        uint32_t const* p = reinterpret_cast<uint32_t const*>(&rowPtr)[N];
        for (size_t col = 0u; col < cols; ++col) {
  return N;         partialSum += *p;
            // Advance one U32
            ++p;
        }
        // Advance the row pointer to the beginning of the next row
        rowPtr += msr.RowPitch;
    }
}

sizeof(T*) is the size of a pointer, not the size of whatever sequence of objects it points to.

If you want the number of elements of an array, either use a macro at the place where it's still an array, use a more friendly array type (std::array), or template it:

template <typename T, size_t N>
size_t array_count(T const (&)[N]) {
  return N;
}

There's three members of a D3D11_MAPPED_SUBRESOURCE:

  1. a pointer to the beginning of the data;
  2. the number of bytes from the beginning of one row of data to the next row of data;
  3. the number of bytes from the beginning of one depth slice of data to the next depth slice of data.

As none of these members communicate anything about the actual extents of a row of data, you need to query your texture resource for a DESC or remember the column and row counts from when you created it.

The 2D layout of the data is such that there are solid rows of data with the potential of padding at the end. The row pitch in the mapping indicate the offsets you need to use to jump between rows.

Assuming you know those quantities, you would iterate your mapped data similiar to this:

{
    uint32_t partialSum = 0u;
    // Point at the beginning of the first row
    BYTE const* rowPtr = msr.pData;
    for (size_t row = 0u; row < rows; ++row) {
        // Take the current row pointer and interpret as sequence of U32
        uint32_t const* p = reinterpret_cast<uint32_t const*>(rowPtr);
        for (size_t col = 0u; col < cols; ++col) {
            partialSum += *p;
            // Advance one U32
            ++p;
        }
        // Advance the row pointer to the beginning of the next row
        rowPtr += msr.RowPitch;
    }
}
Source Link
Lars Viklund
  • 4.1k
  • 1
  • 19
  • 23

sizeof(T*) is the size of a pointer, not the size of whatever sequence of objects it points to.

If you want the number of elements of an array, either use a macro at the place where it's still an array, use a more friendly array type (std::array), or template it:

template <typename T, size_t N>
size_t array_count(T const (&)[N]) {
  return N;
}